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

@evoke-ui/budx

v0.2.2

Published

Cannabis production calendar components with day detail views, notes management, and phase visualization for React and Tailwind CSS

Downloads

26

Readme

@evoke-ui/budx

Cannabis production calendar components with day detail views, notes management, and phase visualization for React and Tailwind CSS.

npm version License: MIT

Features

  • 📅 Production Calendar - Track grow cycles with visual phase indicators
  • 🌱 Growth Phase Tracking - Germination, Seedling, Vegetative, Flowering, Harvest
  • 📝 Note Management - Add detailed notes with room conditions and nutrient tracking
  • 🎨 Customizable Themes - Light/dark mode with CSS variables
  • 📱 Responsive Design - Works seamlessly on desktop and mobile
  • Accessible - WCAG compliant with keyboard navigation
  • 🎯 TypeScript - Full type safety and IntelliSense support
  • 🎨 Tailwind CSS 4 - Modern utility-first styling

Installation

npm install @evoke-ui/budx

Peer Dependencies

This package requires the following peer dependencies:

npm install react react-dom tailwindcss
npm install @radix-ui/react-accordion @radix-ui/react-avatar @radix-ui/react-dialog
npm install @radix-ui/react-dropdown-menu @radix-ui/react-scroll-area @radix-ui/react-separator
npm install lucide-react

For Next.js projects:

npm install next

Quick Start

1. Import Styles

Add the styles to your app's entry point:

import '@evoke-ui/budx/styles.css'

Note: The package includes pre-compiled Tailwind CSS utilities, so you don't need to configure Tailwind to scan the package files.

2. Basic Calendar Usage

import { CalendarView } from '@evoke-ui/budx/calendar'

function App() {
  const grows = [
    {
      id: '1',
      name: 'Northern Lights',
      strain: 'Indica',
      startDate: '2024-01-15',
      phase: 'vegetative',
      customColor: '#22c55e',
    },
  ]

  return (
    <CalendarView
      grows={grows}
      currentDate="2024-01-28"
      onDateChange={(date) => console.log('Date changed:', date)}
    />
  )
}

3. Note Management Integration

'use client'

import { useState, useCallback } from 'react'
import { CalendarView } from '@evoke-ui/budx/calendar'
import type { GrowNote } from '@evoke-ui/budx/calendar'

export function MyCalendar() {
  const [currentDate, setCurrentDate] = useState('2024-01-28')

  const grows = [
    {
      id: '1',
      name: 'Northern Lights',
      strain: 'Indica',
      startDate: '2024-01-15',
      phase: 'vegetative',
      customColor: '#22c55e',
    },
  ]

  // Handle note creation
  const handleNoteAdded = useCallback(async (newNote: GrowNote) => {
    // Call your API to create the note
    const response = await fetch('/api/notes', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(newNote),
    })

    if (!response.ok) throw new Error('Failed to create note')

    // Re-fetch notes or update local state as needed
  }, [])

  // Handle note updates
  const handleNoteUpdated = useCallback(async (updatedNote: GrowNote) => {
    const response = await fetch(`/api/notes/${updatedNote.id}`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(updatedNote),
    })

    if (!response.ok) throw new Error('Failed to update note')

    // Re-fetch notes or update local state as needed
  }, [])

  return (
    <CalendarView
      grows={grows}
      currentDate={currentDate}
      onDateChange={(date) => setCurrentDate(date)}
      onNoteAdded={handleNoteAdded}
      onNoteUpdated={handleNoteUpdated}
    />
  )
}

Key Points:

  • ✅ Your app handles API calls and data persistence
  • ✅ Components handle UI, validation, and user interactions
  • ✅ Re-throw errors in callbacks to keep forms open for retry
  • ✅ Full TypeScript support with type inference

📖 View Complete Integration Guide

Subpath Exports

The package provides granular imports for better tree-shaking:

// Main entry - exports everything
import { CalendarView, Button, cn } from '@evoke-ui/budx'

// Calendar components only
import { CalendarView, CalendarHeader, CalendarGrid } from '@evoke-ui/budx/calendar'

// UI components only
import { Button, Card, Input, Badge } from '@evoke-ui/budx/ui'

// Hooks only
import { useMediaQuery } from '@evoke-ui/budx/hooks'

// Utilities only
import { cn, getInitials } from '@evoke-ui/budx/utils'

// Styles
import '@evoke-ui/budx/styles.css'

Components

CalendarView

Main calendar component with grow cycle visualization.

import { CalendarView } from '@evoke-ui/budx/calendar'

<CalendarView
  grows={grows}
  initialYear={2024}
  initialMonth={1}
  onDayClick={(day) => console.log('Day clicked:', day)}
  onMonthChange={(year, month) => console.log('Month changed:', year, month)}
  onNoteAdded={async (note) => { /* API call to create note */ }}
  onNoteUpdated={async (note) => { /* API call to update note */ }}
  onNoteDeleted={async (id) => { /* API call to delete note */ }}
/>

Props:

| Prop | Type | Description | |------|------|-------------| | grows? | Grow[] | Array of grow cycles to display | | initialYear? | number | Initial year to display (defaults to current year) | | initialMonth? | number | Initial month to display (1-12, defaults to current month) | | phaseColors? | Partial<PhaseColorConfig> | Custom phase color configuration | | onDayClick? | (date: Date) => void | Callback when a day cell is clicked | | onPhaseClick? | (phase: GrowPhase, grow: Grow) => void | Callback when a phase bar is clicked | | onMonthChange? | (year: number, month: number) => void | Callback when month changes | | showAdjacentMonths? | boolean | Whether to show days from adjacent months (default: true) | | maxVisiblePhases? | number | Max phase bars per day before overflow (default: 3) | | showLegend? | boolean | Whether to show phase legend (default: true) | | onNoteAdded? | (note: GrowNote) => Promise<void> | Async callback when a note is added | | onNoteUpdated? | (note: GrowNote) => Promise<void> | Async callback when a note is updated | | onNoteDeleted? | (noteId: string) => Promise<void> | Async callback when a note is deleted | | className? | string | Additional CSS classes |

UI Components

Pre-built UI components based on shadcn/ui:

import { Button, Card, Badge, Input, Avatar } from '@evoke-ui/budx/ui'

// Button
<Button variant="default" size="md">Click me</Button>

// Card
<Card>
  <CardHeader>
    <CardTitle>Title</CardTitle>
  </CardHeader>
  <CardContent>Content here</CardContent>
</Card>

// Badge
<Badge variant="default">New</Badge>

// Input
<Input placeholder="Enter text..." />

// Avatar
<Avatar name="John Doe" src="/avatar.jpg" size="md" />

Types

GrowWithPhaseDates

interface GrowWithPhaseDates {
  id: string
  name: string
  strain?: string
  startDate: string // ISO date
  phase: GrowPhase
  customColor?: string // Hex or OKLCH color
  phaseDates?: {
    germination?: { start: string; end: string }
    seedling?: { start: string; end: string }
    vegetative?: { start: string; end: string }
    flowering?: { start: string; end: string }
    harvest?: { start: string; end: string }
  }
}

type GrowPhase = 'germination' | 'seedling' | 'vegetative' | 'flowering' | 'harvest'

GrowNote

interface GrowNote {
  id: string
  grow: GrowWithPhaseDates
  date: string // ISO date
  title?: string
  notes?: string
  room?: RoomConditions
  nutrients?: Record<string, number>
}

interface RoomConditions {
  lights: string // e.g., '18/6', '1000W HPS'
  temps: string // e.g., '75-80F', '24C'
  humidity: string // e.g., '55%', '50-60%'
  vpd: string // e.g., '1.2 kPa'
}

Theming

The package uses CSS variables for theming. Customize by overriding variables:

:root {
  /* Colors */
  --primary: 221 83% 53%;
  --primary-foreground: 0 0% 98%;
  --background: 0 0% 100%;
  --foreground: 0 0% 9%;

  /* Border radius */
  --radius: 0.5rem;

  /* Transitions */
  --transition-base: 200ms;
}

Dark Mode

Dark mode is automatically applied based on system preference:

@media (prefers-color-scheme: dark) {
  :root {
    --background: 0 0% 4%;
    --foreground: 0 0% 93%;
    /* ... other dark mode variables */
  }
}

Utilities

cn

Utility for merging Tailwind CSS classes:

import { cn } from '@evoke-ui/budx/utils'

<div className={cn('base-class', isActive && 'active-class')} />

getInitials

Extract initials from a name:

import { getInitials } from '@evoke-ui/budx/utils'

getInitials('John Doe') // 'JD'

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Contributing

Contributions are welcome! Please read our Contributing Guide for details.

License

MIT © Evoke UI