# 初始配色脚本

- 页面: https://jiguang132.com/zh/resources/material-ui/docs/init-color-scheme-script
- 资源: Material UI (https://jiguang132.com/zh/resources/material-ui.md)
- 全部指南: https://jiguang132.com/zh/resources/material-ui/docs.md

在 SSR 文档的 React 水合前设置初始配色属性。

本指南覆盖默认 Emotion 环境的 Material UI Core；扩展包与额外示例按清单单独标注。

## 使用场景与业务边界

这是初始化脚本，不是可见 UI；匹配 Provider 配置、CSP nonce 和存储键，并检查真实服务端 HTML。

## 原生组成与范围

`InitColorSchemeScript`

保持 Material UI 原生组合与类型，不替换为 JGuang／Base UI／Radix 同名 API。示例条目不是额外组件。

## 原生安装与初始化

```bash
npm install @mui/material@9.4.0 @emotion/react@11.14.0 @emotion/styled@11.14.1
```

采用原生 npm 包与 Emotion，不提供虚构的 JGuang UI Registry 地址。将示例放在原生 ThemeProvider 内，按项目选择 CssBaseline 或 ScopedCssBaseline。先检查 React、现有 Provider、锁文件与 SSR 配置；不要覆盖用户文件或忽略 peer 冲突。本批实际验收 React 19.2.8；React 18 及以下须匹配 react-is。完整初始化规则见随附的双语 setup 文档。

## 关键原生参数

仅解释本指南选出的关键参数，不是平铺的通用 API。原生继承来源、slot 结构、可空值与泛型仍按固定源码保留。

| 所属组件.属性 | 用途说明 | 声明来源 |
| --- | --- | --- |
| `InitColorSchemeScript.attribute` | 初始配色选择器，必须匹配 ThemeProvider 的 colorSchemeSelector。 | `InitColorSchemeScript` |
| `InitColorSchemeScript.defaultMode` | 没有保存偏好时的原生 light／dark／system 初始模式。 | `InitColorSchemeScript` |
| `InitColorSchemeScript.modeStorageKey` | 原生模式偏好键，匹配 Provider，并避免其他应用的键。 | `InitColorSchemeScript` |
| `InitColorSchemeScript.nonce` | 服务端输出初始化脚本使用的 CSP nonce。 | `InitColorSchemeScript` |

## 可运行原生示例

下列机器键只选择示例入口，不会作为通用 variant 属性传入每个组件。原生示例 JSX 与数据保持上游原文；JGuang 编写的验收示例明确标注。

- 真实 SSR 与水合，默认浅色 · `Init-light` · JGuang 原生验收代码
- 真实 SSR 与水合，默认深色 · `Init-dark` · JGuang 原生验收代码
- 真实 SSR 与水合，跟随系统 · `Init-system` · JGuang 原生验收代码

## 真实使用示例

JGuang 编写的原生验收代码，不是上游组件实现。

```tsx
// JGuang-authored genuine SSR/hydration fixture using Material UI's native APIs.
import { useEffect, useSyncExternalStore } from "react";
import { ThemeProvider, createTheme, useColorScheme } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline";
import Button from "@mui/material/Button";
import Paper from "@mui/material/Paper";
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";

export const modeStorageKey = "jguang-material-init-mode";
export const colorSchemeStorageKey = "jguang-material-init-scheme";
const theme = createTheme({ cssVariables: { colorSchemeSelector: "data" }, colorSchemes: { light: true, dark: true } });
export type Mode = "light" | "dark" | "system";
type Props = { defaultMode: Mode; zh: boolean };
const subscribeHydration = () => () => {};
const clientHydrated = () => true;
const serverHydrated = () => false;

function Controls({ defaultMode, zh }: Props) {
  const { mode, systemMode, setMode } = useColorScheme();
  const hydrated = useSyncExternalStore(subscribeHydration, clientHydrated, serverHydrated);
  useEffect(() => {
    const report = () => { const root = document.getElementById("root")!; parent.postMessage({ type: "jguang-preview-ready", token: new URLSearchParams(location.search).get("token") ?? "", height: Math.ceil(root.getBoundingClientRect().bottom + window.scrollY) }, location.origin); };
    const frame = requestAnimationFrame(report);
    const observer = new ResizeObserver(report);
    observer.observe(document.getElementById("root")!);
    return () => { cancelAnimationFrame(frame); observer.disconnect(); };
  }, []);
  const reset = () => {
    // Remove only this fixture's namespaced preferences, never the website's.
    for (const key of [modeStorageKey, `${colorSchemeStorageKey}-light`, `${colorSchemeStorageKey}-dark`]) localStorage.removeItem(key);
    location.reload();
  };
  return <Stack spacing={2}><Typography variant="h5">{zh ? "原生配色初始化与水合" : "Native color initialization and hydration"}</Typography><Paper sx={{ p: 3 }}><Typography>{zh ? "默认模式" : "Default mode"}: {defaultMode}</Typography><Typography role="status" data-hydrated={hydrated ? "true" : "false"} data-native-mode={mode ?? "pending"} data-system-mode={systemMode ?? "pending"}>{zh ? "当前模式" : "Current mode"}: {mode ?? (zh ? "等待水合" : "Awaiting hydration")}</Typography><Stack direction="row" useFlexGap spacing={1} sx={{ mt: 2, flexWrap: "wrap" }}>{(["light", "dark", "system"] as const).map(value => <Button key={value} disabled={!mode} variant={mode === value ? "contained" : "outlined"} onClick={() => setMode(value)}>{zh ? ({ light: "浅色", dark: "深色", system: "跟随系统" })[value] : value}</Button>)}<Button disabled={!hydrated} onClick={reset}>{zh ? "清除演示偏好并刷新" : "Clear demo preference and reload"}</Button></Stack><Typography sx={{ mt: 2 }}>{zh ? "脚本在 React 启动前执行；按钮通过原生 useColorScheme 更新并保存偏好。该工具不是可见 UI 组件，演示面板是 JGuang 编写的验收代码。" : "The native script runs before React starts. Buttons update and persist preferences using useColorScheme. This utility is not a visible UI component; JGuang authored this acceptance panel."}</Typography><input aria-label={zh ? "原生日期" : "Native date"} type="date" defaultValue="2026-01-25" style={{ marginTop: 16 }} /></Paper></Stack>;
}
export default function ColorSchemeApp(props: Props) {
  return <ThemeProvider theme={theme} defaultMode={props.defaultMode} modeStorageKey={modeStorageKey} colorSchemeStorageKey={colorSchemeStorageKey} disableTransitionOnChange><CssBaseline enableColorScheme /><Controls {...props} /></ThemeProvider>;
}

```

## 示例依赖边界

原生 Core／Emotion 验收代码。

直接导入 Icons／System／Utils 的示例需要匹配 9.4.0 包。局部数据与辅助文件属于示例闭包，不是额外组件。远程图片和模拟操作不提供后端。

## 固定上游 API 元数据参考

以下表格保留上游元数据，不是重新推断的通用类型体系。条件泛型、继承属性与回调细节以以下源码声明为准。主题默认配置可能覆盖元数据默认值。

### InitColorSchemeScript

```tsx
import InitColorSchemeScript from '@mui/material/InitColorSchemeScript';
import { InitColorSchemeScript } from '@mui/material';
```

| 属性 | 必需 | 上游元数据类型／约束 | 元数据默认值 |
| --- | --- | --- | --- |
| `attribute` | 否 | `string` | `'data-mui-color-scheme'` |
| `colorSchemeNode` | 否 | `string` | `'document.documentElement'` |
| `colorSchemeStorageKey` | 否 | `string` | `'mui-color-scheme'` |
| `defaultDarkColorScheme` | 否 | `string` | `'dark'` |
| `defaultLightColorScheme` | 否 | `string` | `'light'` |
| `defaultMode` | 否 | `'dark' \| 'light' \| 'system'` | `'system'` |
| `modeStorageKey` | 否 | `string` | `'mui-mode'` |
| `nonce` | 否 | `string` | — |


## 原生源码声明

声明与 import 从固定源码提取，不平铺联合类型或外部继承。英文注释／类型属于原始源码参考，不代表上游正文已全文翻译。共享类型仍位于原生包中。

### vendor/src/InitColorSchemeScript/InitColorSchemeScript.tsx

```ts
import PropTypes from 'prop-types';

import SystemInitColorSchemeScript from '@mui/system/InitColorSchemeScript';

export interface InitColorSchemeScriptProps {
  /**
   * The default mode when the storage is empty (user's first visit).
   * @default 'system'
   */
  defaultMode?: 'system' | 'light' | 'dark' | undefined;
  /**
   * The default color scheme to be used in light mode.
   * @default 'light'
   */
  defaultLightColorScheme?: string | undefined;
  /**
   * The default color scheme to be used in dark mode.
   * @default 'dark'
   */
  defaultDarkColorScheme?: string | undefined;
  /**
   * The node (provided as string) used to attach the color-scheme attribute.
   * @default 'document.documentElement'
   */
  colorSchemeNode?: string | undefined;
  /**
   * localStorage key used to store `mode`.
   * @default 'mui-mode'
   */
  modeStorageKey?: string | undefined;
  /**
   * localStorage key used to store `colorScheme`.
   * @default 'mui-color-scheme'
   */
  colorSchemeStorageKey?: string | undefined;
  /**
   * DOM attribute for applying a color scheme.
   * @default 'data-mui-color-scheme'
   * @example '.mode-%s' // for class based color scheme
   * @example '[data-mode-%s]' // for data-attribute without '='
   */
  attribute?: 'class' | 'data' | string | undefined;
  /**
   * Nonce string to pass to the inline script for CSP headers.
   */
  nonce?: string | undefined;
}
```

## 安装后验收

执行严格类型检查、生产构建和实际交互。检查键盘标签／焦点、原生支持的禁用／错误／只读语义、深浅色、窄屏和减少动画。按真实宿主数据检查回调，不把复制提示词当作安装完成。初始化工具还需检查服务端 HTML 与无告警水合。

## 来源与许可

https://github.com/mui/material-ui/tree/809a7717b4c050ba3f69b75300689f07c050a16e

MIT · @mui/material@9.4.0. 保留上游原始内容与许可证。上游完整原文保留于 vendor/docs，不标为全文中文化。

---

JGuang 全部资源索引: https://jiguang132.com/llms.txt
