npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

beautify-event

v1.2.1

Published

A beautiful, customizable React event calendar with month, week, day, and resource views. Built with Radix UI and Tailwind CSS.

Readme

Beautify Event

A beautiful, fully customizable React event calendar component with month, week, day, and resource views. Built with Radix UI, Tailwind CSS, and date-fns.

Features

  • Multiple Views: Month, Week, Day, and Resource views
  • Responsive: Mobile-optimized with collapsible month picker and horizontal-scrolling week view
  • Localization: Built-in support for English, French, and Arabic (extensible)
  • Drag & Drop: Create events by dragging on empty slots; move events by dragging
  • Current Time Line: Optional horizontal line showing the current time in day/week views
  • Customizable: Custom event renderers, headers, themes, and styling
  • TypeScript: Full type definitions included

Installation

npm install beautify-event

Peer Dependencies

Beautify Event requires the following peer dependencies. Install them if not already present:

npm install react react-dom date-fns

For full styling and component support, you'll also need:

  • Tailwind CSS (v3 or v4)
  • Radix UI primitives (or shadcn/ui)
  • lucide-react (or ensure icons are available)

Styling (choose one)

Option A — Import pre-built CSS (recommended, zero config)

import "beautify-event/styles.css"
import { EventCalendar } from "beautify-event"

This includes all styles the calendar needs. The calendar provides its own design tokens (scoped to .event-calendar-root), so it works with or without shadcn/ui.

Option B — Tailwind content (if you already use Tailwind and prefer tree-shaking)

Add beautify-event to your Tailwind content so its classes are included:

Tailwind v3 (tailwind.config.js):

content: [
  "./src/**/*.{js,ts,jsx,tsx}",
  "./node_modules/beautify-event/**/*.js",
],

Tailwind v4 — Add ./node_modules/beautify-event/dist/**/*.js to your @source paths.

Also ensure your project defines the design tokens (primary, border, muted, accent, card, etc.) or use Option A.

Quick Start

import "beautify-event/styles.css"
import { EventCalendar } from "beautify-event"
import type { CalendarEvent } from "beautify-event"

const events: CalendarEvent[] = [
  {
    id: "1",
    title: "Team Meeting",
    start: new Date(2026, 2, 10, 9, 0),
    end: new Date(2026, 2, 10, 10, 0),
    color: "#3b82f6",
  },
]

export default function App() {
  return (
    <div className="h-[600px]">
      <EventCalendar events={events} />
    </div>
  )
}

Usage

Basic Example

<EventCalendar
  events={events}
  defaultDate={new Date()}
  defaultView="week"
  views={["month", "week", "day"]}
/>

Controlled Mode

const [date, setDate] = useState(new Date())
const [view, setView] = useState<ViewType>("week")

<EventCalendar
  events={events}
  date={date}
  view={view}
  onDateChange={setDate}
  onViewChange={setView}
/>

With Resources (Rooms, etc.)

const resources: Resource[] = [
  { id: "room-1", name: "Conference Room A", color: "#3b82f6" },
  { id: "room-2", name: "Meeting Room B", color: "#10b981" },
]

<EventCalendar
  events={events}
  resources={resources}
  views={["month", "week", "day", "resource"]}
/>

Event Handlers

<EventCalendar
  events={events}
  onEventClick={(event) => console.log("Clicked:", event)}
  onEventDoubleClick={(event) => openEditModal(event)}
  onSlotClick={(slot) => createEvent(slot)}
  onSlotDoubleClick={(slot) => createEvent(slot)}
  onDayClick={(date) => navigateToDay(date)}
  onDateChange={(date) => setSelectedDate(date)}
  onRangeChange={(range) => fetchEvents(range)}
/>

Drag & Drop

<EventCalendar
  events={events}
  enableDragToCreate
  enableDragToMove
  onEventCreate={(slotInfo) => {
    const newEvent = { id: "new-1", title: "New Event", ...slotInfo }
    setEvents((prev) => [...prev, newEvent])
  }}
  onEventMove={({ event, newStart, newEnd }) => {
    setEvents((prev) =>
      prev.map((e) =>
        e.id === event.id ? { ...e, start: newStart, end: newEnd } : e
      )
    )
  }}
/>

Calendar Options

Pass configuration via calendarOptions:

| Option | Type | Default | Description | |--------|------|---------|-------------| | startHour | number | 0 | Start hour for time series (0-23) | | endHour | number | 24 | End hour (use 24 for full day) | | timeFormat | "12h" \| "24h" | "12h" | Hour label format | | weekStartsOn | 0-6 | 0 | First day of week (0 = Sunday) | | hourHeight | number | 64 | Height of each hour slot in pixels | | timeSeriesMaxHeight | number \| string | 400 | Max height for day/week grid; enables scrolling | | showCurrentTimeLine | boolean | true | Show horizontal line at current time | | maxEventsPerDay | number | 3 | Events to show before "+X more" in month view | | defaultEventColor | string | "#3b82f6" | Default event color | | defaultResourceColor | string | "#6366f1" | Default resource color | | locale | string | "en-US" | Locale for formatting |

<EventCalendar
  events={events}
  calendarOptions={{
    startHour: 8,
    endHour: 20,
    timeFormat: "24h",
    weekStartsOn: 1,
    locale: "fr",
    timeSeriesMaxHeight: 500,
    showCurrentTimeLine: true,
  }}
/>

Localization

Built-in locales: English (en, en-US), French (fr), Arabic (ar).

<EventCalendar
  events={events}
  calendarOptions={{ locale: "fr" }}
/>

To integrate with your app's i18n:

// With next-intl
const locale = useLocale()

// With react-i18next
const { i18n } = useTranslation()

<EventCalendar
  events={events}
  calendarOptions={{ locale: i18n.language }}
/>

Themes

// Use system/app theme
<EventCalendar events={events} />

// Force light or dark
<EventCalendar events={events} theme="dark" />

// Custom theme variables
<EventCalendar
  events={events}
  themeVars={{
    "--primary": "#6366f1",
    "--background": "#0f172a",
    "--foreground": "#f8fafc",
  }}
/>

Props Reference

EventCalendar

| Prop | Type | Default | Description | |------|------|---------|-------------| | events | CalendarEvent[] | required | Events to display | | resources | Resource[] | [] | Resources for resource view | | date | Date | - | Controlled current date | | defaultDate | Date | new Date() | Initial date (uncontrolled) | | view | ViewType | - | Controlled view | | defaultView | ViewType | "month" | Initial view (uncontrolled) | | views | ViewType[] | ["month","week","day","resource"] | Available views | | calendarOptions | CalendarOptions | {} | Calendar configuration | | showNavigation | boolean | true | Show prev/next buttons | | showViewSwitcher | boolean | true | Show view toggle | | showTodayButton | boolean | true | Show Today button | | className | string | - | Container class name | | loading | boolean | false | Loading state | | theme | "light" \| "dark" \| "system" | "system" | Theme mode | | themeVars | Record<string, string> | - | CSS variable overrides | | enableDragToCreate | boolean | false | Allow drag to create events | | enableDragToMove | boolean | false | Allow drag to move events | | mobileBreakpoint | "sm" \| "md" \| "lg" | "md" | Breakpoint for mobile layout | | showMobileMonthPicker | boolean | true | Show month picker on mobile |

CalendarEvent

interface CalendarEvent {
  id: string
  title: string
  start: Date
  end: Date
  color?: string
  resourceId?: string
  description?: string
  allDay?: boolean
}

Resource

interface Resource {
  id: string
  name: string
  color?: string
}

Custom Renderers

Custom Event Content

<EventCalendar
  events={events}
  renderEvent={(event, view) => (
    <div className="custom-event">
      <strong>{event.title}</strong>
      {event.description && <p>{event.description}</p>}
    </div>
  )}
/>

Custom Header

<EventCalendar
  events={events}
  renderHeader={({ date, view, title, onNavigate, onToday }) => (
    <div className="flex items-center justify-between">
      <h1>{title}</h1>
      <div>
        <button onClick={() => onNavigate("prev")}>Prev</button>
        <button onClick={onToday}>Today</button>
        <button onClick={() => onNavigate("next")}>Next</button>
      </div>
    </div>
  )}
/>

Selected Event / Slot UI

<EventCalendar
  events={events}
  renderSelectedEvent={({ event, onClose }) =>
    event && (
      <Sheet open={!!event} onOpenChange={(open) => !open && onClose()}>
        <SheetContent>
          <SheetHeader>
            <SheetTitle>{event.title}</SheetTitle>
          </SheetHeader>
          <p>{event.description}</p>
        </SheetContent>
      </Sheet>
    )
  }
  renderSelectedSlot={({ slot, onClose }) => (
    // Your slot detail UI
  )}
/>

Mobile Behavior

On viewports below the mobileBreakpoint:

  • Simplified header with week strip
  • Month title with expandable month picker (chevron toggle)
  • Week view shows ~2 days at a time with horizontal scroll
  • Sticky time labels column during horizontal scroll
  • Touch-friendly day selection

Exports

// Components
export { EventCalendar, EventCalendarThemeProvider, useCalendar }

// Types
export type {
  ViewType,
  TimeFormat,
  CalendarOptions,
  CalendarEvent,
  Resource,
  SlotInfo,
  DateRange,
  EventCalendarProps,
  HeaderRenderProps,
  CalendarConfig,
  CalendarTheme,
}

// Utilities
export {
  getMonthDays,
  getWeekDays,
  getEventsForDay,
  navigateDate,
  getViewTitle,
  getViewDateRange,
  formatHour,
  formatDate,
  getDateFnsLocale,
  getHoursArray,
  createSlotDate,
}

Requirements

  • React 18+
  • Tailwind CSS
  • Radix UI (or shadcn/ui components)
  • date-fns

Publishing

npm run build:lib   # Build dist/
npm publish         # Use --otp=XXXXXX if you have 2FA enabled

License

MIT