Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/web-weaver/llms.txt

Use this file to discover all available pages before exploring further.

The MoonPhase component renders a crisp SVG illustration of one of four lunar phases — new, waxing, full, or waning. On the Projects page it doubles as a filter control, letting visitors sift through portfolio work by mystical category. Each phase maps to a named project group, and the selected phase scales up while unselected phases dim to half opacity until hovered.

Where It’s Used

MoonPhase lives on the Projects page (/projects). Four instances are rendered side-by-side as a filter bar. Clicking a phase button updates the active filter and re-renders the project grid below with the corresponding entries.

Props

phase
'new' | 'waxing' | 'full' | 'waning'
required
Which lunar phase to render. Each value produces a distinct SVG shape and maps to a named project category:
ValueLabel
newUnreleased Visions
waxingBrews in Progress
fullLive Hexes
waningFading Echoes
size
number
default:"80"
The width and height of the rendered SVG in pixels. Both dimensions are set to the same value, keeping the moon perfectly circular.

Usage

import MoonPhase from "@/components/MoonPhase";

// Selected (full) phase filter button
<MoonPhase phase="full" size={80} />

// Unselected (new) phase filter button
<MoonPhase phase="new" size={80} />
Full filter-bar implementation on the Projects page:
const phases = ["new", "waxing", "full", "waning"];

{phases.map((phase) => (
  <button
    key={phase}
    onClick={() => setActivePhase(phase)}
    className={
      activePhase === phase
        ? "scale-125"
        : "scale-100 opacity-50 hover:opacity-100"
    }
  >
    <MoonPhase phase={phase} size={80} />
  </button>
))}

Behavior Details

Selection States

The component itself is a pure display element — scale and opacity are applied by the parent button wrapper rather than internally. This keeps MoonPhase stateless and reusable in any context.
StateTailwind Classes
Selectedscale-125
Unselectedscale-100 opacity-50
Unselected (hovered)opacity-100

Phase Shapes

Each phase value produces a different SVG path:
  • new — A solid dark circle, representing the absence of reflected light.
  • waxing — A crescent open to the left, showing the moon growing toward full.
  • full — A fully illuminated circle with a subtle inner glow ring.
  • waning — A crescent open to the right, the mirror of the waxing shape.

Customization Tips

Pass a larger size value (e.g. 120) to use MoonPhase as a decorative hero element rather than a filter button — it scales cleanly at any resolution because it’s pure SVG.

Resize for Context

The default 80 px is tuned for the filter bar. Sidebars or hero sections may benefit from size={48} or size={120} respectively.

Wrap for Interaction

MoonPhase renders no click handler itself. Always wrap it in a <button> or interactive element when using it as a control.

Animate the Transition

Add transition-transform duration-300 to the wrapper button so the scale-125 selection state animates smoothly.

Phase Labels

The phase-to-label mapping (full → “Live Hexes”, etc.) lives in the Projects page data layer, not inside the component — update labels there without touching MoonPhase.
MoonPhase does not manage its own selected state. The active phase is tracked in the Projects page via a useState hook, and the correct Tailwind classes are applied by the parent. This ensures the component remains composable and testable in isolation.

Build docs developers (and LLMs) love