{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "calendar",
  "title": "Calendar",
  "description": "One key glides from the old day to the new one, and weeks slide in from the side you turned to.",
  "dependencies": [
    "@ui-sdk/core@0.1.0-beta.2",
    "@ui-sdk/react@0.1.0-beta.2"
  ],
  "registryDependencies": [
    "@keyframery/motion"
  ],
  "files": [
    {
      "path": "registry/components/keyframery/primitives/calendar.tsx",
      "content": "\"use client\"\n\n/* Animated drop-in for `@ui-sdk/react/calendar`: same parts, same props. Swap the import and keep your code.\n   This file adds motion only. Colours, radii, shadows and spacing stay yours.\n\n   - Glide: the chosen day's key is one surface per grid that glides from day to day, drawn by the grid\n     and placed with CSS anchors. In a range there are two, one for each end, and the end key follows the\n     pointer while a range is being picked. Style them with `before:` (the date, or a range's start) and\n     `after:` (a range's end) on CalendarGrid.\n   - Direction: a new month's weeks come in from the side the months turned to, with a blur.\n   - Press: days and the month buttons give under the pointer and spring back. */\n\nimport {\n  Calendar as CalendarRoot,\n  CalendarDay as CalendarDayPart,\n  CalendarGrid as CalendarGridPart,\n  CalendarHeading,\n  CalendarNext as CalendarNextPart,\n  CalendarPrevious as CalendarPreviousPart,\n  CalendarWeekdays,\n  CalendarWeeks as CalendarWeeksPart,\n} from \"@ui-sdk/react/calendar\"\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport * from \"@ui-sdk/react/calendar\"\n\n/* The month the first grid showed when it last rendered, so a month change can tell whether it\n   went forward or back. Without the animated Calendar around them the weeks simply fade in. */\nconst ShownMonthContext = React.createContext<React.RefObject<string | null> | null>(null)\n\n/* Marks the way the months last turned as `data-direction=\"next\" | \"previous\"`. */\nfunction Calendar({\n  className,\n  children,\n  onMonthChange,\n  ...props\n}: React.ComponentProps<typeof CalendarRoot>) {\n  const shown = React.useRef<string | null>(null)\n  const [direction, setDirection] = React.useState<\"next\" | \"previous\" | \"none\">(\"none\")\n  const months = Math.max(1, Math.floor(props.months ?? 1) || 1)\n  return (\n    <ShownMonthContext.Provider value={shown}>\n      <CalendarRoot\n        data-direction={direction}\n        className={cn(\"group/calendar\", className)}\n        onMonthChange={(month, details) => {\n          setDirection(shown.current && month < shown.current ? \"previous\" : \"next\")\n          onMonthChange?.(month, details)\n        }}\n        {...props}\n      >\n        {children ?? (\n          <>\n            <CalendarPrevious />\n            <CalendarHeading />\n            <CalendarNext />\n            {Array.from({ length: months }, (_, offset) => (\n              <CalendarGrid key={offset} offset={offset} />\n            ))}\n          </>\n        )}\n      </CalendarRoot>\n    </ShownMonthContext.Provider>\n  )\n}\n\nconst pressable =\n  \"transition-[scale] duration-[calc(200ms*var(--kf-speed,1))] ease-pop active:scale-[0.92] data-disabled:active:scale-100 motion-reduce:transition-none!\"\n\nfunction CalendarPrevious({ className, ...props }: React.ComponentProps<typeof CalendarPreviousPart>) {\n  return <CalendarPreviousPart className={cn(pressable, className)} {...props} />\n}\n\nfunction CalendarNext({ className, ...props }: React.ComponentProps<typeof CalendarNextPart>) {\n  return <CalendarNextPart className={cn(pressable, className)} {...props} />\n}\n\n/* One month. Its rows are keyed by the month, so a new month arrives as new rows.\n   The keys: neutral surfaces that follow the text colour until you give them your own. They glide\n   on a spring, and fade in late when a month that holds the chosen day arrives, so they land\n   after the weeks have slid in. In \"multiple\" mode there is no single key to glide. */\nfunction CalendarGrid({\n  className,\n  children,\n  offset = 0,\n  ...props\n}: React.ComponentProps<typeof CalendarGridPart>) {\n  const shown = React.useContext(ShownMonthContext)\n  return (\n    <CalendarGridPart\n      offset={offset}\n      className={cn(\n        \"relative isolate [anchor-scope:--kf-day-a,--kf-day-b]\",\n        \"before:pointer-events-none before:absolute before:-z-10 before:opacity-0 before:content-[''] before:[position-anchor:--kf-day-a]\",\n        \"before:bg-[color-mix(in_oklch,currentColor_9%,transparent)]\",\n        \"before:top-[anchor(top)] before:right-[anchor(right)] before:bottom-[anchor(bottom)] before:left-[anchor(left)]\",\n        \"before:[transition:top_calc(300ms*var(--kf-speed,1))_var(--ease-spring),right_calc(300ms*var(--kf-speed,1))_var(--ease-spring),bottom_calc(300ms*var(--kf-speed,1))_var(--ease-spring),left_calc(300ms*var(--kf-speed,1))_var(--ease-spring),opacity_calc(220ms*var(--kf-speed,1))_var(--ease-house)_calc(180ms*var(--kf-speed,1))]\",\n        \"motion-reduce:before:[transition:none]!\",\n        \"after:pointer-events-none after:absolute after:-z-10 after:opacity-0 after:content-[''] after:[position-anchor:--kf-day-b]\",\n        \"after:bg-[color-mix(in_oklch,currentColor_9%,transparent)]\",\n        \"after:top-[anchor(top)] after:right-[anchor(right)] after:bottom-[anchor(bottom)] after:left-[anchor(left)]\",\n        \"after:[transition:top_calc(300ms*var(--kf-speed,1))_var(--ease-spring),right_calc(300ms*var(--kf-speed,1))_var(--ease-spring),bottom_calc(300ms*var(--kf-speed,1))_var(--ease-spring),left_calc(300ms*var(--kf-speed,1))_var(--ease-spring),opacity_calc(220ms*var(--kf-speed,1))_var(--ease-house)_calc(180ms*var(--kf-speed,1))]\",\n        \"motion-reduce:after:[transition:none]!\",\n        \"has-[[data-slot=calendar-day][data-selected]:not([data-range-middle]),[data-slot=calendar-day][data-range-start]]:before:opacity-100\",\n        \"has-[[data-slot=calendar-day][data-range-end]]:after:opacity-100\",\n        \"group-data-[mode=multiple]/calendar:before:hidden group-data-[mode=multiple]/calendar:after:hidden\",\n        className,\n      )}\n      {...props}\n    >\n      {(grid) => {\n        if (shown && offset === 0) shown.current = grid.month\n        return (\n          <React.Fragment key={grid.month}>\n            {typeof children === \"function\"\n              ? children(grid)\n              : (children ?? (\n                  <>\n                    <CalendarWeekdays />\n                    <CalendarWeeks />\n                  </>\n                ))}\n          </React.Fragment>\n        )\n      }}\n    </CalendarGridPart>\n  )\n}\n\n/* Direction: the new weeks come 28px from the side the months turned to, blurred, on a spring. */\nfunction CalendarWeeks({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof CalendarWeeksPart>) {\n  return (\n    <CalendarWeeksPart\n      className={cn(\n        \"transition-[opacity,filter,translate] duration-[calc(460ms*var(--kf-speed,1))] ease-spring\",\n        \"starting:opacity-0 starting:blur-[6px]\",\n        \"group-data-[direction=none]/calendar:starting:opacity-100 group-data-[direction=none]/calendar:starting:blur-none\",\n        \"group-data-[direction=next]/calendar:starting:translate-x-7 group-data-[direction=previous]/calendar:starting:-translate-x-7\",\n        \"motion-reduce:transition-none!\",\n        className,\n      )}\n      {...props}\n    >\n      {children ?? ((cell) => <CalendarDay value={cell.date} />)}\n    </CalendarWeeksPart>\n  )\n}\n\n/* Names itself as the anchor the grid's keys follow, and gives under the pointer. */\nfunction CalendarDay({ className, ...props }: React.ComponentProps<typeof CalendarDayPart>) {\n  return (\n    <CalendarDayPart\n      className={cn(\n        \"data-selected:not-data-range-middle:not-data-range-end:[anchor-name:--kf-day-a] data-range-start:[anchor-name:--kf-day-a]\",\n        \"data-range-end:[anchor-name:--kf-day-b] data-range-start:data-range-end:[anchor-name:--kf-day-a,--kf-day-b]\",\n        \"transition-[scale] duration-[calc(200ms*var(--kf-speed,1))] ease-pop active:scale-[0.9] data-disabled:active:scale-100 motion-reduce:transition-none!\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Calendar, CalendarDay, CalendarGrid, CalendarNext, CalendarPrevious, CalendarWeeks }\n",
      "type": "registry:component",
      "target": "components/keyframery/primitives/calendar.tsx"
    },
    {
      "path": "registry/components/keyframery/calendar.tsx",
      "content": "\"use client\"\n\n/* Styled calendar: the animated primitive plus the Keyframery look. */\n\nimport * as React from \"react\"\n\nimport {\n  Calendar as CalendarPrimitive,\n  CalendarDay as CalendarDayPrimitive,\n  CalendarGrid as CalendarGridPrimitive,\n  CalendarHeading as CalendarHeadingPrimitive,\n  CalendarMonthSelect as CalendarMonthSelectPrimitive,\n  CalendarNext as CalendarNextPrimitive,\n  CalendarPrevious as CalendarPreviousPrimitive,\n  CalendarWeekday as CalendarWeekdayPrimitive,\n  CalendarWeekdays as CalendarWeekdaysPrimitive,\n  CalendarWeeks as CalendarWeeksPrimitive,\n  CalendarYearSelect as CalendarYearSelectPrimitive,\n} from \"@/components/keyframery/primitives/calendar\"\nimport { cn } from \"@/lib/utils\"\n\n/* A small key: the month buttons. The primitive springs them back after a press. */\nconst stepKey = cn(\n  \"inline-flex size-7 shrink-0 cursor-pointer items-center justify-center rounded-[9px] bg-background text-muted-foreground outline-none select-none [&_svg]:size-4\",\n  \"shadow-[0_0_0_1px_rgb(0_0_0/0.06),0_1px_1px_rgb(0_0_0/0.05),0_3px_6px_-2px_rgb(0_0_0/0.1)]\",\n  \"dark:bg-accent dark:shadow-[0_0_0_1px_rgb(255_255_255/0.07),inset_0_1px_0_rgb(255_255_255/0.08),0_2px_6px_-1px_rgb(0_0_0/0.6)]\",\n  \"hover:text-foreground active:shadow-[0_0_0_1px_rgb(0_0_0/0.08),0_1px_1px_rgb(0_0_0/0.04)]\",\n  \"dark:active:shadow-[0_0_0_1px_rgb(255_255_255/0.07),inset_0_1px_0_rgb(255_255_255/0.05),0_1px_2px_rgb(0_0_0/0.6)]\",\n  \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card\",\n  \"data-disabled:pointer-events-none data-disabled:opacity-40\",\n)\n\n/* The native month and year selects, as compact fields. */\nconst selectField = cn(\n  \"h-7 cursor-pointer appearance-none rounded-[8px] bg-background px-2 text-[13px] font-medium text-foreground outline-none\",\n  \"shadow-[0_0_0_1px_rgb(0_0_0/0.09),0_1px_2px_rgb(0_0_0/0.05)] hover:shadow-[0_0_0_1px_rgb(0_0_0/0.16),0_1px_2px_rgb(0_0_0/0.05)]\",\n  \"dark:shadow-[0_0_0_1px_rgb(255_255_255/0.1)] dark:hover:shadow-[0_0_0_1px_rgb(255_255_255/0.16)]\",\n  \"transition-shadow duration-[calc(150ms*var(--kf-speed,1))] focus-visible:shadow-[0_0_0_1px_var(--ring)] focus-visible:ring-[3px] focus-visible:ring-ring/25\",\n  \"dark:focus-visible:shadow-[0_0_0_1px_var(--ring)]\",\n  \"data-disabled:pointer-events-none data-disabled:opacity-40 motion-reduce:transition-none!\",\n)\n\nfunction ChevronLeftIcon() {\n  return (\n    <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n      <path d=\"M9.5 3.5 5 8l4.5 4.5\" />\n    </svg>\n  )\n}\n\nfunction ChevronRightIcon() {\n  return (\n    <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n      <path d=\"M6.5 3.5 11 8l-4.5 4.5\" />\n    </svg>\n  )\n}\n\n/* The card. Without children it lays out the heading, the month keys and a grid per month. */\nfunction Calendar({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof CalendarPrimitive>) {\n  const months = Math.max(1, Math.floor(props.months ?? 1) || 1)\n  return (\n    <CalendarPrimitive\n      className={cn(\n        \"flex w-fit flex-col gap-2 rounded-[14px] bg-card p-3 text-card-foreground\",\n        \"shadow-[0_0_0_1px_rgb(0_0_0/0.06),0_1px_2px_rgb(0_0_0/0.04),0_6px_16px_-6px_rgb(0_0_0/0.1)]\",\n        \"dark:shadow-[0_0_0_1px_rgb(255_255_255/0.08),0_6px_16px_-6px_rgb(0_0_0/0.6)]\",\n        className,\n      )}\n      {...props}\n    >\n      {children ?? (\n        <>\n          <CalendarHeader>\n            <CalendarPrevious />\n            <CalendarHeading />\n            <CalendarNext />\n          </CalendarHeader>\n          <div className=\"flex gap-4\">\n            {Array.from({ length: months }, (_, offset) => (\n              <CalendarGrid key={offset} offset={offset} />\n            ))}\n          </div>\n        </>\n      )}\n    </CalendarPrimitive>\n  )\n}\n\n/* The row above the grid. The heading sits first, the month keys after it. */\nfunction CalendarHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"calendar-header\"\n      className={cn(\"flex h-7 items-center gap-1.5\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CalendarHeading({\n  className,\n  ...props\n}: React.ComponentProps<typeof CalendarHeadingPrimitive>) {\n  return (\n    <CalendarHeadingPrimitive\n      className={cn(\n        \"order-first mr-auto pl-1.5 text-[15px] font-semibold tracking-tight tabular-nums\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CalendarPrevious({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof CalendarPreviousPrimitive>) {\n  return (\n    <CalendarPreviousPrimitive className={cn(stepKey, className)} {...props}>\n      {children ?? <ChevronLeftIcon />}\n    </CalendarPreviousPrimitive>\n  )\n}\n\nfunction CalendarNext({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof CalendarNextPrimitive>) {\n  return (\n    <CalendarNextPrimitive className={cn(stepKey, className)} {...props}>\n      {children ?? <ChevronRightIcon />}\n    </CalendarNextPrimitive>\n  )\n}\n\nfunction CalendarMonthSelect({\n  className,\n  ...props\n}: React.ComponentProps<typeof CalendarMonthSelectPrimitive>) {\n  return <CalendarMonthSelectPrimitive className={cn(selectField, className)} {...props} />\n}\n\nfunction CalendarYearSelect({\n  className,\n  ...props\n}: React.ComponentProps<typeof CalendarYearSelectPrimitive>) {\n  return (\n    <CalendarYearSelectPrimitive\n      className={cn(selectField, \"tabular-nums\", className)}\n      {...props}\n    />\n  )\n}\n\n/* One month. The primitive draws the chosen day's key here, as `before:` (the date or a range's\n   start) and `after:` (a range's end), and glides it between days. This gives it the primary key look. */\nconst chosenKey = cn(\n  \"before:rounded-[9px] before:bg-primary after:rounded-[9px] after:bg-primary\",\n  \"before:shadow-[inset_0_1px_0_rgb(255_255_255/0.14),0_1px_2px_rgb(0_0_0/0.25)] after:shadow-[inset_0_1px_0_rgb(255_255_255/0.14),0_1px_2px_rgb(0_0_0/0.25)]\",\n  \"dark:before:shadow-[inset_0_1px_0_rgb(255_255_255/0.7),0_1px_2px_rgb(0_0_0/0.5)] dark:after:shadow-[inset_0_1px_0_rgb(255_255_255/0.7),0_1px_2px_rgb(0_0_0/0.5)]\",\n)\n\nfunction CalendarGrid({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof CalendarGridPrimitive>) {\n  return (\n    <CalendarGridPrimitive\n      className={cn(\n        \"border-separate border-spacing-x-0 border-spacing-y-0.5 data-disabled:opacity-50\",\n        chosenKey,\n        className,\n      )}\n      {...props}\n    >\n      {children ?? (\n        <>\n          <CalendarWeekdays />\n          <CalendarWeeks />\n        </>\n      )}\n    </CalendarGridPrimitive>\n  )\n}\n\nfunction CalendarWeekdays({\n  children,\n  ...props\n}: React.ComponentProps<typeof CalendarWeekdaysPrimitive>) {\n  return (\n    <CalendarWeekdaysPrimitive {...props}>\n      {children ?? ((index) => <CalendarWeekday index={index} />)}\n    </CalendarWeekdaysPrimitive>\n  )\n}\n\nfunction CalendarWeekday({\n  className,\n  ...props\n}: React.ComponentProps<typeof CalendarWeekdayPrimitive>) {\n  return (\n    <CalendarWeekdayPrimitive\n      className={cn(\n        \"h-7 w-8 p-0 text-center text-[11px] font-medium text-muted-foreground\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CalendarWeeks({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof CalendarWeeksPrimitive>) {\n  return (\n    <CalendarWeeksPrimitive\n      className={className}\n      {...props}\n    >\n      {children ?? ((cell) => <CalendarDay value={cell.date} />)}\n    </CalendarWeeksPrimitive>\n  )\n}\n\n/* A day. The chosen key is drawn under it by the grid, so a chosen day only turns its number\n   to the key's text colour. A range is a soft band between the two keys, rounded where a week wraps. */\nfunction CalendarDay({\n  className,\n  ...props\n}: React.ComponentProps<typeof CalendarDayPrimitive>) {\n  return (\n    <CalendarDayPrimitive\n      className={cn(\n        \"relative size-8 cursor-pointer rounded-[9px] p-0 text-center align-middle text-[13px] leading-none font-medium text-foreground tabular-nums outline-none select-none\",\n        \"transition-[color,background-color,scale] duration-[calc(200ms*var(--kf-speed,1))]\",\n        \"not-data-selected:not-data-range-start:not-data-range-end:hover:bg-foreground/[0.06]\",\n        \"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\",\n        /* Chosen: the number sits on the primary key. */\n        \"data-selected:not-data-range-middle:text-primary-foreground data-range-start:text-primary-foreground data-range-end:text-primary-foreground\",\n        \"group-data-[mode=multiple]/calendar:data-selected:bg-primary\",\n        /* Today: a small dot under the number. */\n        \"data-today:font-semibold data-today:after:absolute data-today:after:bottom-[3px] data-today:after:left-1/2 data-today:after:size-1 data-today:after:-translate-x-1/2 data-today:after:rounded-full data-today:after:bg-foreground\",\n        \"data-selected:not-data-range-middle:after:bg-primary-foreground data-range-start:after:bg-primary-foreground data-range-end:after:bg-primary-foreground\",\n        /* A range: the band between the keys. */\n        \"data-range-middle:rounded-none data-range-middle:bg-accent data-range-middle:text-accent-foreground data-range-middle:first:rounded-l-[9px] data-range-middle:last:rounded-r-[9px]\",\n        \"data-preview:not-data-range-start:not-data-range-end:rounded-none data-preview:not-data-range-start:not-data-range-end:bg-accent/70 data-preview:first:rounded-l-[9px] data-preview:last:rounded-r-[9px]\",\n        \"data-outside:text-muted-foreground/55\",\n        \"data-disabled:cursor-default data-disabled:text-muted-foreground/45 data-disabled:hover:bg-transparent\",\n        \"data-unavailable:line-through\",\n        \"motion-reduce:transition-none!\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Calendar,\n  CalendarDay,\n  CalendarGrid,\n  CalendarHeader,\n  CalendarHeading,\n  CalendarMonthSelect,\n  CalendarNext,\n  CalendarPrevious,\n  CalendarWeekday,\n  CalendarWeekdays,\n  CalendarWeeks,\n  CalendarYearSelect,\n}\n",
      "type": "registry:component",
      "target": "components/keyframery/calendar.tsx"
    }
  ],
  "type": "registry:component"
}