Keyframes Editor
ridiculous/keyframes-editorFreeComponent
Ridiculously typed editor for a CSS @keyframes body — the composition flagship. A two-level type validates each stop selector and dispatches every declaration into its property's own validator (transform, filter, color, easing, …). A timeline embeds the real editors per stop, with a scrubbed preview.
Install it
npx shadcn@latest add http://ridiculous.turtlesocks.dev/r/keyframes-editor.jsonSource
1"use client"23import { useEffect, useRef, useState } from "react"4import { Button } from "@/components/ui/button"5import {6 Popover,7 PopoverContent,8 PopoverTrigger,9} from "@/components/ui/popover"10import { cn } from "@/lib/utils"11import { DeclarationRow } from "./declaration-row"12import { KeyframePreview } from "./keyframe-preview"13import { KeyframeTimeline } from "./keyframe-timeline"14import {15 defaultKeyframes,16 formatKeyframes,17 parseKeyframes,18 percentToSelector,19 selectorToPercent,20} from "./keyframes-editor.helpers"21import type {22 Declaration,23 KeyframeBlock,24 KeyframesString,25} from "./keyframes-editor.types"2627// Re-export the public sub-components + their prop types so consumers (and the28// barrel) can import them from `./keyframes-editor`.29export type { DeclarationRowProps } from "./declaration-row"30export { DeclarationRow } from "./declaration-row"31export type { KeyframePreviewProps } from "./keyframe-preview"32export { KeyframePreview } from "./keyframe-preview"33export type { KeyframeTimelineProps } from "./keyframe-timeline"34export { KeyframeTimeline } from "./keyframe-timeline"35export type { MiniSelectProps } from "./mini-select"36export { MiniSelect } from "./mini-select"3738// ---------------------------------------------------------------------------39// Props40// ---------------------------------------------------------------------------4142export interface KeyframesEditorPanelProps {43 value: KeyframesString | (string & {})44 onChange: (value: KeyframesString) => void45 className?: string46 "aria-label"?: string47}4849export interface KeyframesEditorProps extends KeyframesEditorPanelProps {}5051// ---------------------------------------------------------------------------52// KeyframesEditor — popover-wrapped53// ---------------------------------------------------------------------------5455export function KeyframesEditor(props: KeyframesEditorProps) {56 const {57 value,58 className,59 "aria-label": ariaLabel = "Edit a CSS @keyframes body",60 } = props61 const { blocks, error } = parseKeyframes(String(value))62 const label =63 error !== null64 ? "invalid"65 : `${blocks.length} stop${blocks.length === 1 ? "" : "s"}`6667 return (68 <Popover>69 <PopoverTrigger asChild>70 <Button71 variant="outline"72 className={cn("h-9 gap-2 px-3 font-mono", className)}73 aria-label={ariaLabel}74 >75 <span aria-hidden="true" className="text-foreground/60">76 ⏱77 </span>78// … truncated
What it pulls in
Other registry items
Files it writes
More from ridiculous
All 22 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| All ridiculous componentsall | ridiculous | Components | Free | no deps | |
| Anchor Position Editoranchor-position-editor | ridiculous | Components | Free | no deps · 9 files | |
| Background Editorbackground-editor | ridiculous | Components | Free | no deps · 9 files | |
| Box Shadow Editorbox-shadow-editor | ridiculous | Components | Free | no deps · 7 files | |
| Calc Editorcalc-editor | ridiculous | Components | Free | no deps · 4 files | |
| Clip Path Editorclip-path-editor | ridiculous | Components | Free | no deps · 20 files | |
| Color Functioncolor-function | ridiculous | Components | Free | no deps · 10 files | |
| Color Pickercolor-picker | ridiculous | Components | Free | no deps · 11 files |
