This page sets up the React color picker with Vite, from the install to a
working picker in App.tsx. There is no plugin to add and no configuration to
change. The package ships ESM, so Vite resolves it directly.
Install
npm install chroma-panelreact and react-dom are peer dependencies and the package has no
dependencies of its own, so nothing else is pulled in.
Import the stylesheet
The panel injects its stylesheet from an effect. In a client-rendered Vite app
that happens before you see anything, so the import is optional. Import it
yourself when you want the CSS in your build output rather than in a <style>
tag, for example under a strict Content Security Policy.
// src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "chroma-panel/style.css";
import "./index.css";
import App from "./App";
const root = document.getElementById("root");
if (root !== null) {
createRoot(root).render(
<StrictMode>
<App />
</StrictMode>
);
}Once you import it yourself, pass injectStyles={false} so the panel does not
write the tag as well. It does not make your bundle smaller — the CSS is in the
module either way. The other ways to load the CSS are in
theming.
A picker in App.tsx
// src/App.tsx
import { useState } from "react";
import { ColorInput, type ColorChangeResult } from "chroma-panel";
export default function App() {
const [color, setColor] = useState<string>("#3366cc");
const handleChange = (result: ColorChangeResult): void => {
setColor(result.hex);
};
return (
<main>
<ColorInput value={color} onChange={handleChange} injectStyles={false} />
<p style={{ color }}>{color}</p>
</main>
);
}onChange fires continuously while you drag. Use onChangeComplete for
anything that costs something, such as saving or a network call — see
controlled and uncontrolled.
If you use Tailwind
The package ships its rules inside @layer chroma-panel. An undeclared layer
sorts after Tailwind's, which would let the panel's rules beat your utility
classes. Import the stylesheet from your CSS file and declare the order there
instead of importing it in main.tsx:
/* src/index.css */
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/preflight.css" layer(base);
@import "chroma-panel/style.css";
@import "tailwindcss/utilities.css" layer(utilities);Styling with Tailwind explains why that order is the one that works, and which class names each part of the panel takes.
Only the modes you need
Importing chroma-panel registers all five modes: wheel, sliders, palettes,
image and pencils. Import the shell from chroma-panel/panel and add the modes
yourself to ship less.
import { ChromaPanel } from "chroma-panel/panel";
import "chroma-panel/wheel";
<ChromaPanel modes={["wheel"]} />;| What you import | Added to your app |
|---|---|
| all five modes | 22.2 kB |
| shell plus one mode | 14.1 kB |
Both figures are gzipped, with React external, measured as the increase in a Vite production build.
Import modes for the side effect
A mode entry point registers itself when it loads. Write import "chroma-panel/wheel", not a named import, or the bundler may drop it.
Every subpath, including chroma-panel/core for the color engine without React,
is listed under entry points.