npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@wecode-team/we0-cms

v1.1.11

Published

A CMS component for React applications with shadcn/ui

Downloads

1,666

Readme

@wecode-team/we0-cms

一个基于 React 的动态 CMS 前端组件库,支持 shadcn/ui 风格的现代化 UI,与 @wecode-team/cms-supabase-api 配合使用实现完整的内容管理系统。

📖 设计理念

核心思想

本包的核心理念是 "配置驱动的 CMS UI"

  1. 模型驱动 UI:根据 JSON Schema 模型配置自动生成表单和表格
  2. 零代码管理:无需编写代码,通过配置即可实现数据的增删改查
  3. 关系可视化:支持关联字段的下拉选择和数据展示
  4. 多租户支持:通过 Session ID 实现数据隔离

架构设计

┌─────────────────────────────────────────────────────────────┐
│                    CmsLayoutShadcn                          │
│                   (主布局组件)                               │
├─────────────────────────────────────────────────────────────┤
│  UI Components (shadcn/ui)                                  │
│  ├── Sidebar         侧边栏导航                             │
│  ├── DataTable       数据表格                               │
│  ├── Dialog          弹窗表单                               │
│  └── Form Controls   表单控件                               │
├─────────────────────────────────────────────────────────────┤
│  Pages (页面组件)                                            │
│  ├── LoginPage       登录页面                               │
│  ├── DataListPage    数据列表页                             │
│  └── DataManagePage  数据管理页(按模型)                    │
├─────────────────────────────────────────────────────────────┤
│  Services (服务层)                                           │
│  ├── modelApi        模型管理 API                           │
│  ├── dataApi         数据操作 API                           │
│  └── authApi         认证 API                               │
├─────────────────────────────────────────────────────────────┤
│  Request Layer (请求层)                                      │
│  └── request.ts      Axios 封装,自动添加 Token             │
└─────────────────────────────────────────────────────────────┘

数据流

用户操作 → UI 组件 → Services API → HTTP 请求 → 后端 API → Supabase
                                        ↓
用户界面 ← UI 更新 ← State 更新 ← API 响应 ←

🚀 安装

npm install @wecode-team/we0-cms
# 或
pnpm add @wecode-team/we0-cms
# 或
yarn add @wecode-team/we0-cms

📋 依赖

Peer Dependencies(必须安装)

{
  "react": "^18.2.0",
  "react-dom": "^18.2.0"
}

内置依赖

  • @radix-ui/* - 无障碍 UI 原语
  • lucide-react - 图标库
  • tailwind-merge - Tailwind 类名合并
  • class-variance-authority - 变体样式管理
  • dayjs - 日期处理

🔧 快速开始

第一步:配置 Tailwind CSS

确保你的项目已配置 Tailwind CSS:

// tailwind.config.js
module.exports = {
  content: [
    './src/**/*.{js,jsx,ts,tsx}',
    './node_modules/@wecode-team/we0-cms/dist/**/*.{js,jsx}'
  ],
  theme: {
    extend: {}
  },
  plugins: []
}

第二步:引入样式

import '@wecode-team/we0-cms/dist/index.css'

第三步:使用组件

import React from 'react'
import { CmsLayoutShadcn, setSessionId } from '@wecode-team/we0-cms'
import '@wecode-team/we0-cms/dist/index.css'

// 设置 Session ID(用于多租户隔离)
setSessionId('your-session-id')

// 定义模型配置
const modelData = {
  models: [
    {
      id: 1,
      name: '用户模型',
      table_name: 'users',
      json_schema: {
        fields: [
          {
            name: 'name',
            type: 'string',
            comment: '用户姓名',
            required: true,
            maxLength: 100
          },
          {
            name: 'email',
            type: 'email',
            unique: true,
            comment: '用户邮箱',
            required: true
          },
          {
            name: 'age',
            type: 'integer',
            comment: '年龄',
            required: false
          }
        ]
      },
      created_at: '2023-07-18T19:00:28.098Z',
      updated_at: '2023-07-18T19:00:28.099Z'
    }
  ]
}

function App() {
  return (
    <div className="min-h-screen">
      <CmsLayoutShadcn inputModels={modelData} />
    </div>
  )
}

export default App

📚 组件 API

CmsLayoutShadcn

主布局组件,包含侧边栏、导航和内容区域。

interface CmsLayoutProps {
  inputModels: {
    models: CmsModel[]
  }
  /**
   * 是否跳过登录验证(免登录模式)
   * 当设置为 true 时,组件将跳过所有登录检查,直接进入后台配置页面
   * 适用于由使用方统一处理鉴权的场景
   * @default false
   */
  skipAuth?: boolean
}

Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | inputModels | { models: CmsModel[] } | - | 模型配置对象 | | skipAuth | boolean | false | 是否跳过登录验证 |

使用示例

// 标准模式(需要登录)
<CmsLayoutShadcn inputModels={modelData} />

// 免登录模式(适用于已有鉴权系统)
<CmsLayoutShadcn inputModels={modelData} skipAuth={true} />

setSessionId

设置会话 ID,用于多租户数据隔离。

import { setSessionId } from '@wecode-team/we0-cms'

// 设置 Session ID
setSessionId('tenant-123')

// 后续 API 调用会自动添加前缀
// 例如:GET /data/users → GET /data/tenant-123_users

🏗️ 模型配置

CmsModel 结构

interface CmsModel {
  id: number
  name: string           // 模型显示名称
  table_name: string     // 数据表名
  json_schema: {
    fields: SchemaField[]
  }
  created_at: string
  updated_at: string
}

SchemaField 结构

interface SchemaField {
  name: string           // 字段名
  type: string           // 字段类型
  comment?: string       // 字段显示名称
  required?: boolean     // 是否必填
  unique?: boolean       // 是否唯一
  maxLength?: number     // 最大长度
  defaultValue?: any     // 默认值
  relation?: RelationConfig  // 关联配置
  editable?: boolean     // 是否允许在后台编辑(默认 true;false=不可编辑)
  readOnly?: boolean     // 兼容字段:readOnly=true 等价于 editable=false
}

字段不可编辑(协议层)

当你希望某些字段(如 created_atupdated_atowner_idtoken)在后台 只展示不允许修改 时,可以在字段上标记:

  • editable: false(推荐)
  • readOnly: true(兼容写法)

前端行为:

  • 表单控件会被禁用
  • create/update 提交时会自动跳过该字段(不会传到后端)

示例:

{
  name: "created_at",
  type: "datetime",
  comment: "创建时间",
  readOnly: true
},
{
  name: "owner_id",
  type: "string",
  comment: "归属用户",
  editable: false
}

字段类型

| 类型 | 渲染组件 | 说明 | |------|----------|------| | string | <Input /> | 单行文本输入 | | text | <Textarea /> | 多行文本输入 | | integer | <Input type="number" /> | 整数输入 | | float | <Input type="number" /> | 浮点数输入 | | boolean | <Switch /> | 开关切换 | | date | <Input type="date" /> | 日期选择 | | datetime | <Input type="datetime-local" /> | 日期时间选择 | | email | <Input type="email" /> | 邮箱输入 | | relation | <Select /> | 关联下拉选择 |

关联字段配置

interface RelationConfig {
  type: 'belongsTo' | 'hasMany' | 'belongsToMany'
  target: string         // 目标表名
  foreignKey?: string    // 外键字段名
  displayField?: string  // 下拉显示的字段
  showInList?: boolean   // 是否在列表中显示
}

示例:文章关联作者

{
  name: 'author',
  type: 'relation',
  comment: '作者',
  required: true,
  relation: {
    type: 'belongsTo',
    target: 'users',        // 关联 users 表
    foreignKey: 'author_id', // 外键字段
    displayField: 'name'     // 下拉显示用户姓名
  }
}

📡 API 配置

配置 API 基础 URL

request.ts 中配置:

// 创建自定义 request 实例
import axios from 'axios'

const request = axios.create({
  baseURL: 'http://your-api-url/api/cms',
  timeout: 10000
})

// 请求拦截器 - 自动添加 Token
request.interceptors.request.use((config) => {
  const token = localStorage.getItem('cms_token')
  if (token) {
    config.headers.Authorization = `Bearer ${token}`
  }
  return config
})

API 服务

import { modelApi, dataApi, authApi } from '@wecode-team/we0-cms'

// 模型 API
await modelApi.getModels()
await modelApi.createModel(data)
await modelApi.updateModel(data)
await modelApi.deleteModel(id)

// 数据 API
await dataApi.getTableData('users', { page: 1, limit: 10 })
await dataApi.createData('users', { name: 'John' })
await dataApi.updateData('users', { id: '1', name: 'Jane' })
await dataApi.deleteData('users', '1')

// 关联选项 API
await dataApi.getRelationOptions('users', { displayField: 'name' })

// 认证 API
await authApi.login({ username: 'admin', password: '123456' })
await authApi.verifyAuth()
await authApi.getCurrentUser()
await authApi.logout()

🎨 自定义样式

覆盖 CSS 变量

:root {
  --background: 0 0% 100%;
  --foreground: 222.2 84% 4.9%;
  --primary: 222.2 47.4% 11.2%;
  --primary-foreground: 210 40% 98%;
  /* ... 更多变量 */
}

.dark {
  --background: 222.2 84% 4.9%;
  --foreground: 210 40% 98%;
  /* ... 暗色模式变量 */
}

扩展组件

import { CmsLayoutShadcn } from '@wecode-team/we0-cms'

function CustomCms() {
  return (
    <div className="custom-wrapper">
      <header className="custom-header">
        <h1>我的 CMS</h1>
      </header>
      <CmsLayoutShadcn inputModels={modelData} skipAuth={true} />
    </div>
  )
}

🔐 认证流程

1. 登录流程

用户输入账号密码 → 调用 authApi.login() → 保存 Token 到 localStorage
                                              ↓
                                        跳转到数据管理页

2. Token 验证

页面加载 → 检查 localStorage 中的 Token → 调用 authApi.verifyAuth()
                                              ↓
                                    验证成功:显示内容
                                    验证失败:跳转登录页

3. 免登录模式

// 适用于已有鉴权系统的场景
<CmsLayoutShadcn inputModels={modelData} skipAuth={true} />

📱 响应式设计

组件内置响应式支持:

  • 桌面端:完整侧边栏 + 内容区域
  • 平板端:可折叠侧边栏
  • 移动端:底部抽屉式导航

🐛 常见问题

1. 样式不生效

确保引入了 CSS 文件:

import '@wecode-team/we0-cms/dist/index.css'

2. Tailwind 类名冲突

确保 Tailwind 配置包含了组件库的路径:

content: [
  './node_modules/@wecode-team/we0-cms/dist/**/*.{js,jsx}'
]

3. 关联字段不显示数据

检查模型配置中的 relation.displayField 是否正确设置为目标表中存在的字段。

4. API 请求失败

检查:

  1. Session ID 是否正确设置
  2. API 基础 URL 是否正确
  3. CORS 是否配置正确

📄 许可证

MIT

🔗 相关包