npm package: @k3studio/property-panel
Description: A flexible property panel component for React applications
Author: Your Name
Latest version: 0.0.4

# Property Panel Component

一个灵活、可配置的 React 属性面板组件，基于 Ant Design 构建，支持多种数据类型和主题。

## 特性

- 🎨 **内置主题支持** - 只需选择 `dark` 或 `light`，无需额外配置
- 📝 多种数据类型支持（字符串、数字、布尔值、选择器、JSON、颜色选择器）
- 🔧 灵活的布局配置
- 🎯 完整的 TypeScript 支持
- 📦 支持 ES Module 和 CommonJS
- 🌐 支持 UMD 格式（CDN 使用）

## 安装

```bash
npm install @k3studio/property-panel
# 或
yarn add @k3studio/property-panel
# 或
pnpm add @k3studio/property-panel
```

## 依赖要求

```json
{
  "react": ">=16.8.0",
  "react-dom": ">=16.8.0",
  "antd": ">=5.0.0"
}
```

## 导入方式

### 基本导入

```tsx
// 导入主组件（默认导出）
import PropertyPanel from '@k3studio/property-panel';

// 导入主组件（命名导出）
import { PropertyPanel } from '@k3studio/property-panel';

// 导入类型定义
import type { 
  Meta, 
  UpdatePayload, 
  SetterConfig,
  PropertyPanelProps,
  Option,
  Field,
  CompositeField,
  Operations,
  OperationHandlers,
  OperationConfig,
  SetterProps
} from '@k3studio/property-panel';

// 导入常量
import { EVENT_TYPES } from '@k3studio/property-panel';

// 导入主题相关
import { 
  getPropertyPanelTheme, 
  DARK_THEME, 
  LIGHT_THEME 
} from '@k3studio/property-panel';
import type { ThemeType } from '@k3studio/property-panel';

// 导入单独的Setter组件（用于自定义扩展）
import { 
  BooleanSetter,
  NumberSetter,
  JsonSetter,
  ColorPickerTrigger
} from '@k3studio/property-panel';
```

### 一次性导入

```tsx
import PropertyPanel, { 
  // 类型
  type Meta,
  type UpdatePayload,
  type SetterConfig,
  type PropertyPanelProps,
  
  // 常量
  EVENT_TYPES,
  
  // 主题
  getPropertyPanelTheme,
  DARK_THEME,
  LIGHT_THEME,
  type ThemeType,
  
  // Setter组件
  BooleanSetter,
  NumberSetter,
  JsonSetter,
  ColorPickerTrigger
} from '@k3studio/property-panel';
```

## 常量和类型使用

### EVENT_TYPES 常量

```tsx
import { EVENT_TYPES } from '@k3studio/property-panel';

const handlePropertyChange = (payload: UpdatePayload) => {
  switch (payload.type) {
    case EVENT_TYPES.SET_META:
      console.log('设置元数据:', payload.data);
      break;
    case EVENT_TYPES.UPDATE_VALUE:
      console.log('更新值:', payload.data);
      break;
    default:
      console.log('未知事件类型:', payload.type);
  }
};
```

### 类型定义使用

```tsx
import type { 
  Meta, 
  SetterConfig, 
  UpdatePayload,
  PropertyPanelProps 
} from '@k3studio/property-panel';

// 定义属性面板配置
const panelMeta: Meta = {
  setters: {
    props: [
      {
        name: "title",
        title: "标题",
        setter: "string",
      } as SetterConfig
    ],
    layout: [
      {
        name: "basic",
        title: "基础设置",
        items: [
          {
            name: "info",
            title: "基本信息",
            fields: ["setters/props/title"]
          }
        ]
      }
    ]
  },
  defaultValues: {
    props: {
      title: "默认标题"
    }
  }
};

// 定义变化处理函数
const handleChange = (payload: UpdatePayload) => {
  // 处理属性变化
};

// 定义组件属性
const panelProps: PropertyPanelProps = {
  meta: panelMeta,
  onChange: handleChange,
  theme: 'light'
};
```

### 自定义Setter组件使用

```tsx
import { 
  BooleanSetter,
  NumberSetter,
  JsonSetter,
  ColorPickerTrigger
} from '@k3studio/property-panel';

// 在自定义组件中使用单独的Setter
const CustomForm: React.FC = () => {
  const [value, setValue] = useState(false);
  
  return (
    <div>
      <BooleanSetter 
        config={{
          name: "enabled",
          title: "启用状态",
          setter: "boolean"
        }}
        value={value}
        onChange={setValue}
      />
    </div>
  );
};
```

### 主题和样式使用

```tsx
import PropertyPanel, { 
  lightTheme, 
  darkTheme 
} from '@k3studio/property-panel';

// 使用预设主题
const App: React.FC = () => {
  const [theme, setTheme] = useState<'light' | 'dark'>('light');
  
  return (
    <div>
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        切换主题
      </button>
      <PropertyPanel
        meta={meta}
        theme={theme}
        onChange={handleChange}
      />
    </div>
  );
};

// 使用主题对象
const AppWithThemeObject: React.FC = () => {
  return (
    <PropertyPanel
      meta={meta}
      theme={lightTheme}
      onChange={handleChange}
    />
  );
};
```

### 完整使用示例

```tsx
import React, { useState } from 'react';
import PropertyPanel, { 
  type Meta, 
  type UpdatePayload,
  EVENT_TYPES,
  lightTheme
} from '@k3studio/property-panel';

const App: React.FC = () => {
  const [values, setValues] = useState({
    title: '我的组件',
    enabled: true,
    count: 10,
    color: '#ff0000'
  });

  const meta: Meta = {
    setters: {
      props: [
        {
          name: "title",
          title: "标题",
          setter: "string",
        },
        {
          name: "enabled",
          title: "启用状态",
          setter: "boolean",
        },
        {
          name: "count",
          title: "数量",
          setter: "number",
        },
        {
          name: "color",
          title: "颜色",
          setter: "color",
        }
      ],
      layout: [
        {
          name: "basic",
          title: "基础设置",
          items: [
            {
              name: "info",
              title: "基本信息",
              fields: ["setters/props/title", "setters/props/enabled"]
            },
            {
              name: "style",
              title: "样式设置",
              fields: ["setters/props/count", "setters/props/color"]
            }
          ]
        }
      ]
    },
    defaultValues: {
      props: values
    }
  };

  const handleChange = (payload: UpdatePayload) => {
    console.log('属性变化:', payload);
    
    if (payload.type === EVENT_TYPES.UPDATE_VALUE) {
      setValues(prev => ({
        ...prev,
        [payload.name]: payload.value
      }));
    }
  };

  return (
    <div style={{ padding: '20px' }}>
      <h1>Property Panel 示例</h1>
      <PropertyPanel
        meta={meta}
        theme={lightTheme}
        onChange={handleChange}
      />
      
      <div style={{ marginTop: '20px' }}>
        <h2>当前值:</h2>
        <pre>{JSON.stringify(values, null, 2)}</pre>
      </div>
    </div>
  );
};

export default App;
```

## 基本使用

### 简单使用（推荐）

组件内置了完整的主题配置，外部使用者只需要选择主题类型：

```tsx
import React, { useState } from 'react';
import PropertyPanel, { Meta, UpdatePayload, EVENT_TYPES } from '@k3studio/property-panel';

const App: React.FC = () => {
  const [meta, setMeta] = useState<Meta>({
    setters: {
      props: [
        {
          name: "title",
          title: "标题",
          setter: "string",
        },
        {
          name: "isVisible",
          title: "是否显示",
          setter: "boolean",
        },
      ],
      layout: [
        {
          name: "basicSettings",
          title: "基础设置",
          items: [
            {
              name: "basic",
              title: "基本信息",
              fields: [
                "setters/props/title",
                "setters/props/isVisible",
              ],
            },
          ],
        },
      ],
    },
    defaultValues: {
      props: {
        title: "示例标题",
        isVisible: true,
      },
    },
  });

  const handlePropertyChange = (payload: UpdatePayload) => {
    console.log('属性变化:', payload);
    // 处理属性变化...
  };

  return (
    <PropertyPanel
      meta={meta}
      onChange={handlePropertyChange}
      theme="light" // 只需要选择 'dark' 或 'light'
      config={{
        defaultActiveTab: 0,
        allowMultipleExpand: true,
        showOperations: true,
        showTooltips: true,
        validateOnChange: true,
        debounceTime: 300,
      }}
    />
  );
};

export default App;
```

### 主题切换示例

```tsx
import React, { useState } from 'react';
import { Button } from 'antd';
import PropertyPanel from '@k3studio/property-panel';

const App: React.FC = () => {
  const [theme, setTheme] = useState<'dark' | 'light'>('light');

  return (
    <div>
      <Button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
        切换到 {theme === 'dark' ? '明亮' : '暗色'} 主题
      </Button>
      
      <PropertyPanel
        meta={meta}
        onChange={handlePropertyChange}
        theme={theme} // 动态切换主题
      />
    </div>
  );
};
```

### 高级使用（自定义主题）

如果你需要自定义主题，可以使用内置的主题函数：

```tsx
import React from 'react';
import { ConfigProvider } from 'antd';
import PropertyPanel, { getPropertyPanelTheme } from '@k3studio/property-panel';

const App: React.FC = () => {
  // 获取基础主题配置
  const baseTheme = getPropertyPanelTheme('dark');
  
  // 自定义主题配置
  const customTheme = {
    ...baseTheme,
    token: {
      ...baseTheme.token,
      colorPrimary: '#ff6b35', // 自定义主色调
    },
  };

  return (
    <ConfigProvider theme={customTheme}>
      <PropertyPanel
        meta={meta}
        onChange={handlePropertyChange}
        // 注意：当外层有 ConfigProvider 时，不需要传 theme 属性
      />
    </ConfigProvider>
  );
};
```

## 支持的 Setter 类型

### 字符串输入 (string)
```tsx
{
  name: "title",
  title: "标题",
  setter: "string",
}
```

### 数字输入 (number)
```tsx
{
  name: "count",
  title: "数量",
  setter: "number",
  min: 0,
  max: 100,
  step: 1,
}
```

### 布尔值开关 (boolean)
```tsx
{
  name: "isEnabled",
  title: "启用状态",
  setter: "boolean",
}
```

### 选择器 (select)
```tsx
{
  name: "status",
  title: "状态",
  setter: "select",
  options: [
    { label: "启用", value: "enabled" },
    { label: "禁用", value: "disabled" },
  ],
}
```

### JSON 编辑器 (json)
```tsx
{
  name: "config",
  title: "配置",
  setter: "json",
}
```

### 颜色选择器 (colorPicker)
```tsx
{
  name: "themeColor",
  title: "主题色",
  setter: "colorPicker",
  options: [
    { label: "蓝色", value: "#1890ff" },
    { label: "绿色", value: "#52c41a" },
  ],
}
```

## 主题支持

### 内置主题（推荐）

组件内置了完整的明暗主题配置，只需要传入主题类型：

```tsx
// 明亮主题
<PropertyPanel theme="light" {...props} />

// 暗色主题  
<PropertyPanel theme="dark" {...props} />
```

### 主题函数

如果需要获取主题配置进行自定义：

```tsx
import { getPropertyPanelTheme, DARK_THEME, LIGHT_THEME } from '@k3studio/property-panel';

// 动态获取主题
const themeConfig = getPropertyPanelTheme('dark');

// 或使用预定义的主题常量
const darkTheme = DARK_THEME;
const lightTheme = LIGHT_THEME;
```

## 配置选项

```tsx
interface PropertyPanelConfig {
  defaultActiveTab?: number;        // 默认激活的标签页
  allowMultipleExpand?: boolean;    // 是否允许多个面板同时展开
  showOperations?: boolean;         // 是否显示操作按钮
  showTooltips?: boolean;          // 是否显示提示信息
  autoSelectOnHover?: boolean;     // 鼠标悬停时是否自动选择
  validateOnChange?: boolean;      // 是否在变化时验证
  debounceTime?: number;          // 防抖时间（毫秒）
}
```

## API 参考

### PropertyPanel Props

| 属性 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| meta | Meta | - | 面板配置数据 |
| onChange | (payload: UpdatePayload) => void | - | 属性变化回调 |
| theme | 'dark' \| 'light' | 'light' | 主题类型 |
| config | PropertyPanelConfig | - | 面板配置选项 |

### 主题相关 API

| 函数/常量 | 类型 | 描述 |
|-----------|------|------|
| getPropertyPanelTheme | (theme: ThemeType) => ThemeConfig | 获取主题配置 |
| DARK_THEME | ThemeConfig | 预定义暗色主题 |
| LIGHT_THEME | ThemeConfig | 预定义明亮主题 |
| ThemeType | 'dark' \| 'light' | 主题类型 |

### Meta 类型

```tsx
interface Meta {
  setters: {
    props: SetterConfig[];
    layout: setterLayout[];
  };
  defaultValues: {
    props: Record<string, any>;
  };
  transforms?: Record<string, { getValues: (values: Record<string, any>) => any; }>;
  datasource?: Record<string, any>;
  dependencyAnalysis?: {
    strict?: boolean;
    warnCycles?: boolean;
  };
}
```

## 开发

```bash
# 安装依赖
npm install

# 启动开发服务器
npm run dev

# 查看独立 demo
npm run demo

# 构建库
npm run build

# 发布
npm publish
```

## 许可证

MIT

## 贡献

欢迎提交 Issue 和 Pull Request！