# useColorStore

> createColorStore 及其 hooks 保存着 React 颜色选择器背后的颜色。可以用它们在多个面板间共享一个颜色，或构建自己的选择器界面。

Source: https://chroma-panel.jscrate.dev/zh/react/utils/use-color-store
Last updated: 2026-09-21

`createColorStore` 保存一个 HSVA 颜色，并在变化时通知订阅者。当多个组件共享同一个值，或者你要在 `ChromaPanel` 之外构建自定义控件时，就用这套 React 颜色选择器的 hook 和 store。在自定义模式内部，`usePanel` 返回所在面板的 store。

```ts
import { createColorStore } from "chroma-panel/core";

const store = createColorStore({ h: 220, s: 75, v: 80, a: 1 });
```

`chroma-panel/core` 不含 React，也不依赖 DOM，所以 store 可以放在任何环境下运行的代码里。

## API 参考

```ts
function createColorStore(initial: Hsva): ColorStore
```

Creates the store the panel is built on. It holds the full Hsva and notifies subscribers, so a drag never re-renders React.

| 方法                                    | 作用                               |
| --------------------------------------- | ---------------------------------- |
| `get()`                                 | 返回当前的 `Hsva`                  |
| `set(next)`                             | 替换颜色                           |
| `patch(partial)`                        | 修改部分通道                       |
| `ingest(next)`                          | 合并修改，保留色相和饱和度         |
| `commit()`                              | 标记一次手势操作结束               |
| `subscribe(fn)`                         | 每次变化都触发，返回取消订阅的函数 |
| `subscribeCommit(fn)`                   | 仅在 commit 时触发                 |
| `getSnapshot()` / `getServerSnapshot()` | 供 `useSyncExternalStore` 使用     |

拖动时，`subscribe` 每一帧都会触发；`subscribeCommit` 只在手势结束时触发一次。`onChange` 和 `onChangeComplete` 正是基于这种区分实现的，详见[受控与非受控](https://chroma-panel.jscrate.dev/zh/react/handbook/controlled)。

## 在 React 中读取

```ts
function useColorValue(store: ColorStore): Hsva
```

Subscribes to a store and returns the color as ordinary state. Re-renders on every change, so use it where a re-render per frame is acceptable.

```ts
function useTransientColor(store: ColorStore, effect: (color: Hsva) => void): void
```

Runs an effect on every color change without re-rendering. This is how the panel stays smooth: it writes to the DOM directly.

```ts
function usePanel(): PanelContextValue
```

Reaches the surrounding panel's store, ids and options. Only valid inside a ChromaPanel, which is what a custom mode's Panel renders within.

面板能保持流畅，靠的是 `useTransientColor`。它直接写入 DOM，而不是设置 state：

```tsx
useTransientColor(store, (c) => {
  el.current.style.background = toHex(c);
});
```

## 构建自己的控件

```ts
function usePointerDrag(options: UsePointerDragOptions): PointerDragProps
```

The pointer-tracking behind the wheel and the sliders, for building a drag surface of your own. Keeps tracking when the pointer leaves the element.

```ts
function useAxisKeyboard(options: UseAxisKeyboardOptions): AxisKeyboardProps
```

Adds arrow, Page Up/Down and Home/End handling to one axis, matching the built-in controls.

## 驱动多个面板

通过 `store` prop 把 store 传给 `ColorInput` 或 `ChromaPanel`，就能用同一个值驱动多个组件。

```tsx
<ChromaPanel store={store} />
<ColorInput store={store} />
```
