Background Editor
ridiculous/background-editorFreeComponent
Ridiculously typed editor for the CSS background shorthand. An index-aware fold permits a <color> token only on the final layer, so a color in any earlier layer is a compile error. A reorderable layer stack embeds the real gradient + color pickers over a live composite preview.
Install it
npx shadcn@latest add http://ridiculous.turtlesocks.dev/r/background-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 {12 defaultBackground,13 formatBackground,14 parseBackground,15} from "./background-editor.helpers"16import type { BackgroundString, BgLayer } from "./background-editor.types"17import { BackgroundPreview } from "./background-preview"18import { LayerStack } from "./layer-stack"1920// Re-export the public sub-components + their prop types so consumers (and the21// barrel) can import them from `./background-editor`.22export type { BackgroundPreviewProps } from "./background-preview"23export { BackgroundPreview } from "./background-preview"24export type { LayerCardProps } from "./layer-card"25export { LayerCard } from "./layer-card"26export type { LayerStackProps } from "./layer-stack"27export { LayerStack } from "./layer-stack"28export type { MiniSelectProps } from "./mini-select"29export { MiniSelect } from "./mini-select"30export type { PositionPadProps } from "./position-pad"31export { PositionPad } from "./position-pad"3233// ---------------------------------------------------------------------------34// Props35// ---------------------------------------------------------------------------3637export interface BackgroundEditorPanelProps {38 value: BackgroundString | (string & {})39 onChange: (value: BackgroundString) => void40 className?: string41 "aria-label"?: string42}4344export interface BackgroundEditorProps extends BackgroundEditorPanelProps {}4546// ---------------------------------------------------------------------------47// color re-homing — the index-aware invariant, kept true under reorder48// ---------------------------------------------------------------------------4950/**51 * Keep the `<color>` on the FINAL layer no matter how the stack is reordered.52 * A reorder swaps whole layer objects, so a color that was on the last layer53 * would otherwise travel with its object into a non-final slot and be dropped54 * by `formatBackground` (which only emits a color on the last layer). This55 * collects any color found anywhere in the stack and re-homes it onto the last56 * layer, stripping it from every other — so the invariant survives a reorder.57 */58function migrateColorToFinal(layers: BgLayer[]): BgLayer[] {59 if (layers.length === 0) return layers60 // The last non-empty color wins (mirrors CSS: only the final layer's color61// … 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 | |
| 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 | |
| Easing Pickereasing-picker | ridiculous | Components | Free | no deps · 17 files |
