From 68a4e9b073713a5c85ed4c7e8370f8d7712991bf Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 26 Jan 2026 09:27:34 +0000
Subject: [PATCH 1/3] Initial plan
From 237274fe5d4894406f0b700e7003f0096438cb4e Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 26 Jan 2026 09:32:41 +0000
Subject: [PATCH 2/3] Add basic project structure and three essential
components
Co-authored-by: CheMingjun <18278955+CheMingjun@users.noreply.github.com>
---
.gitignore | 15 ++++++++
README.md | 67 +++++++++++++++++++++++++++++++-
mybricks.json | 14 +++++++
package.json | 37 ++++++++++++++++++
src/button/com.json | 38 +++++++++++++++++++
src/button/data.json | 6 +++
src/button/icon.svg | 3 ++
src/button/runtime.tsx | 86 ++++++++++++++++++++++++++++++++++++++++++
src/input/com.json | 54 ++++++++++++++++++++++++++
src/input/data.json | 6 +++
src/input/icon.svg | 4 ++
src/input/runtime.tsx | 71 ++++++++++++++++++++++++++++++++++
src/text/com.json | 41 ++++++++++++++++++++
src/text/data.json | 4 ++
src/text/icon.svg | 3 ++
src/text/runtime.tsx | 39 +++++++++++++++++++
tsconfig.json | 23 +++++++++++
typings.d.ts | 75 ++++++++++++++++++++++++++++++++++++
18 files changed, 585 insertions(+), 1 deletion(-)
create mode 100644 .gitignore
create mode 100644 mybricks.json
create mode 100644 package.json
create mode 100644 src/button/com.json
create mode 100644 src/button/data.json
create mode 100644 src/button/icon.svg
create mode 100644 src/button/runtime.tsx
create mode 100644 src/input/com.json
create mode 100644 src/input/data.json
create mode 100644 src/input/icon.svg
create mode 100644 src/input/runtime.tsx
create mode 100644 src/text/com.json
create mode 100644 src/text/data.json
create mode 100644 src/text/icon.svg
create mode 100644 src/text/runtime.tsx
create mode 100644 tsconfig.json
create mode 100644 typings.d.ts
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..856b010
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+node_modules
+package-lock.json
+
+.temp
+.temp-pub
+.vscode
+.DS_Store
+.history
+.VSCodeCounter
+
+yarn.lock
+.idea/
+
+dist/
+coverage/
diff --git a/README.md b/README.md
index ba47ae7..b958ee5 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,66 @@
-# comlib-pc-normal-lite
\ No newline at end of file
+# Mybricks PC端通用组件库 (Lite版本)
+
+
+
轻量级的PC端通用组件库,为MyBricks低代码平台提供基础组件支持
+
+
+## ✨ 特性
+
+- 🚀 轻量级设计,包含最常用的基础组件
+- 🎨 简洁的UI设计,开箱即用
+- 📦 零外部依赖(除React外)
+- 🔧 完整的TypeScript支持
+- 🌍 支持国际化
+
+## 📦 组件列表
+
+### 基础组件
+
+- **文本 (Text)**: 用于展示文本内容的基础组件
+- **按钮 (Button)**: 可点击的按钮组件,支持多种样式
+- **输入框 (Input)**: 用于接收用户输入的文本框组件
+
+## 🔨 开发
+
+### 安装依赖
+
+```bash
+npm install
+```
+
+### 启动开发服务器
+
+```bash
+npm run dev
+```
+
+### 构建
+
+```bash
+npm run build
+```
+
+## 📝 使用说明
+
+本组件库基于MyBricks平台开发,可在MyBricks编辑器中直接使用。
+
+### 环境依赖
+
+组件运行时需要以下环境方法:
+
+```typescript
+const env = {
+ i18n(text: string) {
+ // 多语言定制
+ return text;
+ }
+};
+```
+
+## 🤝 贡献
+
+欢迎提交 Issue 和 Pull Request!
+
+## 📄 License
+
+ISC
\ No newline at end of file
diff --git a/mybricks.json b/mybricks.json
new file mode 100644
index 0000000..46e92b7
--- /dev/null
+++ b/mybricks.json
@@ -0,0 +1,14 @@
+{
+ "title": "PC常规组件库(Lite)",
+ "description": "PC端通用组件库的轻量级版本,包含最基础和常用的组件",
+ "comAry": [
+ {
+ "title": "基础组件",
+ "comAry": [
+ "./src/text/com.json",
+ "./src/button/com.json",
+ "./src/input/com.json"
+ ]
+ }
+ ]
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..b0e53a3
--- /dev/null
+++ b/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "@mybricks/comlib-pc-normal-lite",
+ "version": "1.0.0",
+ "description": "PC端通用组件库(Lite版本)",
+ "main": "./dist/index.js",
+ "scripts": {
+ "dev": "mybricks dev",
+ "build": "mybricks build",
+ "publish": "mybricks publish"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/mybricks/comlib-pc-normal-lite.git"
+ },
+ "keywords": [
+ "mybricks",
+ "component-library",
+ "pc",
+ "lite",
+ "low-code"
+ ],
+ "author": "MyBricks",
+ "license": "ISC",
+ "bugs": {
+ "url": "https://github.com/mybricks/comlib-pc-normal-lite/issues"
+ },
+ "homepage": "https://github.com/mybricks/comlib-pc-normal-lite#readme",
+ "dependencies": {
+ "react": "^18.0.0",
+ "react-dom": "^18.0.0"
+ },
+ "devDependencies": {
+ "@types/react": "^18.0.0",
+ "@types/react-dom": "^18.0.0",
+ "typescript": "^5.0.0"
+ }
+}
diff --git a/src/button/com.json b/src/button/com.json
new file mode 100644
index 0000000..4d6da72
--- /dev/null
+++ b/src/button/com.json
@@ -0,0 +1,38 @@
+{
+ "title": "按钮",
+ "namespace": "mybricks.normal-pc-lite.button",
+ "version": "1.0.0",
+ "description": "可点击的按钮组件",
+ "author": "MyBricks",
+ "icon": "./icon.svg",
+ "data": "./data.json",
+ "runtime": "./runtime.tsx",
+ "inputs": [
+ {
+ "id": "setText",
+ "title": "设置文本",
+ "desc": "设置按钮文本",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "id": "setDisabled",
+ "title": "设置禁用",
+ "desc": "设置按钮是否禁用",
+ "schema": {
+ "type": "boolean"
+ }
+ }
+ ],
+ "outputs": [
+ {
+ "id": "click",
+ "title": "点击",
+ "desc": "按钮点击时触发",
+ "schema": {
+ "type": "any"
+ }
+ }
+ ]
+}
diff --git a/src/button/data.json b/src/button/data.json
new file mode 100644
index 0000000..38b3946
--- /dev/null
+++ b/src/button/data.json
@@ -0,0 +1,6 @@
+{
+ "text": "按钮",
+ "type": "primary",
+ "disabled": false,
+ "style": {}
+}
diff --git a/src/button/icon.svg b/src/button/icon.svg
new file mode 100644
index 0000000..b3944fe
--- /dev/null
+++ b/src/button/icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/button/runtime.tsx b/src/button/runtime.tsx
new file mode 100644
index 0000000..cf6988c
--- /dev/null
+++ b/src/button/runtime.tsx
@@ -0,0 +1,86 @@
+import React, { useEffect } from 'react';
+
+interface Data {
+ text: string;
+ type?: 'primary' | 'default' | 'dashed' | 'text' | 'link';
+ disabled?: boolean;
+ style?: React.CSSProperties;
+}
+
+export default function ({ data, inputs, outputs, env }: RuntimeParams) {
+ useEffect(() => {
+ inputs['setText'] && inputs['setText']((value: string) => {
+ data.text = value;
+ });
+
+ inputs['setDisabled'] && inputs['setDisabled']((value: boolean) => {
+ data.disabled = value;
+ });
+ }, []);
+
+ const handleClick = () => {
+ if (!data.disabled && outputs && outputs['click']) {
+ outputs['click']();
+ }
+ };
+
+ const getButtonStyle = (): React.CSSProperties => {
+ const baseStyle: React.CSSProperties = {
+ padding: '4px 15px',
+ fontSize: '14px',
+ borderRadius: '2px',
+ border: '1px solid #d9d9d9',
+ cursor: data.disabled ? 'not-allowed' : 'pointer',
+ transition: 'all 0.3s',
+ display: 'inline-block',
+ textAlign: 'center',
+ userSelect: 'none',
+ ...data.style
+ };
+
+ if (data.disabled) {
+ baseStyle.opacity = 0.6;
+ baseStyle.backgroundColor = '#f5f5f5';
+ baseStyle.color = 'rgba(0, 0, 0, 0.25)';
+ baseStyle.borderColor = '#d9d9d9';
+ } else {
+ switch (data.type) {
+ case 'primary':
+ baseStyle.backgroundColor = '#1890ff';
+ baseStyle.color = '#fff';
+ baseStyle.borderColor = '#1890ff';
+ break;
+ case 'dashed':
+ baseStyle.borderStyle = 'dashed';
+ baseStyle.backgroundColor = '#fff';
+ baseStyle.color = 'rgba(0, 0, 0, 0.85)';
+ break;
+ case 'text':
+ baseStyle.border = 'none';
+ baseStyle.backgroundColor = 'transparent';
+ baseStyle.color = 'rgba(0, 0, 0, 0.85)';
+ break;
+ case 'link':
+ baseStyle.border = 'none';
+ baseStyle.backgroundColor = 'transparent';
+ baseStyle.color = '#1890ff';
+ break;
+ default:
+ baseStyle.backgroundColor = '#fff';
+ baseStyle.color = 'rgba(0, 0, 0, 0.85)';
+ }
+ }
+
+ return baseStyle;
+ };
+
+ return (
+
+ );
+}
diff --git a/src/input/com.json b/src/input/com.json
new file mode 100644
index 0000000..304b6cd
--- /dev/null
+++ b/src/input/com.json
@@ -0,0 +1,54 @@
+{
+ "title": "输入框",
+ "namespace": "mybricks.normal-pc-lite.input",
+ "version": "1.0.0",
+ "description": "用于接收用户输入的文本框组件",
+ "author": "MyBricks",
+ "icon": "./icon.svg",
+ "data": "./data.json",
+ "runtime": "./runtime.tsx",
+ "inputs": [
+ {
+ "id": "setValue",
+ "title": "设置值",
+ "desc": "设置输入框的值",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "id": "setPlaceholder",
+ "title": "设置提示文本",
+ "desc": "设置输入框的提示文本",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "id": "setDisabled",
+ "title": "设置禁用",
+ "desc": "设置输入框是否禁用",
+ "schema": {
+ "type": "boolean"
+ }
+ }
+ ],
+ "outputs": [
+ {
+ "id": "onChange",
+ "title": "值变化",
+ "desc": "输入框值变化时触发",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "id": "onBlur",
+ "title": "失去焦点",
+ "desc": "输入框失去焦点时触发",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ]
+}
diff --git a/src/input/data.json b/src/input/data.json
new file mode 100644
index 0000000..b0c2c73
--- /dev/null
+++ b/src/input/data.json
@@ -0,0 +1,6 @@
+{
+ "value": "",
+ "placeholder": "请输入",
+ "disabled": false,
+ "style": {}
+}
diff --git a/src/input/icon.svg b/src/input/icon.svg
new file mode 100644
index 0000000..e4a1744
--- /dev/null
+++ b/src/input/icon.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/input/runtime.tsx b/src/input/runtime.tsx
new file mode 100644
index 0000000..3649b99
--- /dev/null
+++ b/src/input/runtime.tsx
@@ -0,0 +1,71 @@
+import React, { useEffect, useState } from 'react';
+
+interface Data {
+ value: string;
+ placeholder?: string;
+ disabled?: boolean;
+ style?: React.CSSProperties;
+}
+
+export default function ({ data, inputs, outputs, env }: RuntimeParams) {
+ const [value, setValue] = useState(data.value || '');
+
+ useEffect(() => {
+ inputs['setValue'] && inputs['setValue']((val: string) => {
+ const newValue = val !== undefined && val !== null ? String(val) : '';
+ data.value = newValue;
+ setValue(newValue);
+ });
+
+ inputs['setPlaceholder'] && inputs['setPlaceholder']((val: string) => {
+ data.placeholder = val;
+ });
+
+ inputs['setDisabled'] && inputs['setDisabled']((val: boolean) => {
+ data.disabled = val;
+ });
+ }, []);
+
+ const handleChange = (e: React.ChangeEvent) => {
+ const newValue = e.target.value;
+ data.value = newValue;
+ setValue(newValue);
+
+ if (outputs && outputs['onChange']) {
+ outputs['onChange'](newValue);
+ }
+ };
+
+ const handleBlur = () => {
+ if (outputs && outputs['onBlur']) {
+ outputs['onBlur'](value);
+ }
+ };
+
+ const inputStyle: React.CSSProperties = {
+ width: '100%',
+ padding: '4px 11px',
+ fontSize: '14px',
+ lineHeight: '1.5715',
+ color: 'rgba(0, 0, 0, 0.85)',
+ backgroundColor: data.disabled ? '#f5f5f5' : '#fff',
+ border: '1px solid #d9d9d9',
+ borderRadius: '2px',
+ transition: 'all 0.3s',
+ outline: 'none',
+ cursor: data.disabled ? 'not-allowed' : 'text',
+ ...data.style
+ };
+
+ return (
+
+ );
+}
diff --git a/src/text/com.json b/src/text/com.json
new file mode 100644
index 0000000..9d93c35
--- /dev/null
+++ b/src/text/com.json
@@ -0,0 +1,41 @@
+{
+ "title": "文本",
+ "namespace": "mybricks.normal-pc-lite.text",
+ "version": "1.0.0",
+ "description": "用于展示文本内容的基础组件",
+ "author": "MyBricks",
+ "icon": "./icon.svg",
+ "data": "./data.json",
+ "runtime": "./runtime.tsx",
+ "inputs": [
+ {
+ "id": "content",
+ "title": "设置内容",
+ "desc": "设置文本内容",
+ "schema": {
+ "type": "string"
+ },
+ "rels": [
+ "setContentDone"
+ ]
+ }
+ ],
+ "outputs": [
+ {
+ "id": "setContentDone",
+ "title": "设置内容完成",
+ "desc": "文本内容设置完成",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "id": "click",
+ "title": "点击",
+ "desc": "点击文本时触发",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ]
+}
diff --git a/src/text/data.json b/src/text/data.json
new file mode 100644
index 0000000..6fbc6cc
--- /dev/null
+++ b/src/text/data.json
@@ -0,0 +1,4 @@
+{
+ "content": "文本内容",
+ "style": {}
+}
diff --git a/src/text/icon.svg b/src/text/icon.svg
new file mode 100644
index 0000000..bc52076
--- /dev/null
+++ b/src/text/icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/text/runtime.tsx b/src/text/runtime.tsx
new file mode 100644
index 0000000..8cb09f9
--- /dev/null
+++ b/src/text/runtime.tsx
@@ -0,0 +1,39 @@
+import React, { useEffect } from 'react';
+
+interface Data {
+ content: string;
+ style?: React.CSSProperties;
+}
+
+export default function ({ data, inputs, outputs, env }: RuntimeParams) {
+ useEffect(() => {
+ inputs['content']((value: string, relOutputs) => {
+ let res = value;
+ if (res != undefined && typeof res !== 'string') {
+ res = JSON.stringify(res);
+ }
+ data.content = res;
+ if (relOutputs && relOutputs['setContentDone']) {
+ relOutputs['setContentDone'](res);
+ }
+ });
+ }, []);
+
+ const handleClick = () => {
+ if (outputs && outputs['click']) {
+ outputs['click'](data.content || '');
+ }
+ };
+
+ return (
+
+ {env?.i18n ? env.i18n(data.content || '') : data.content || ''}
+
+ );
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..58f17a8
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ "module": "es2015",
+ "target": "es5",
+ "lib": ["dom", "es2016", "dom.iterable", "esnext"],
+ "noImplicitAny": false,
+ "allowJs": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "experimentalDecorators": true,
+ "emitDecoratorMetadata": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": false,
+ "forceConsistentCasingInFileNames": true,
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react",
+ "baseUrl": "."
+ },
+ "exclude": ["node_modules", "dist", ".temp", ".temp-pub"]
+}
diff --git a/typings.d.ts b/typings.d.ts
new file mode 100644
index 0000000..243597c
--- /dev/null
+++ b/typings.d.ts
@@ -0,0 +1,75 @@
+declare module "*.less" {
+ const resource: { [key: string]: string };
+ export = resource;
+}
+
+declare module "*.css" {
+ const resource: { [key: string]: string };
+ export = resource;
+}
+
+interface RuntimeParams {
+ /** 环境注入 */
+ env: Env;
+
+ /** 组件的配置数据 */
+ data: T;
+
+ /** 组件的输入 */
+ inputs: Inputs;
+
+ /** 组件的输出 */
+ outputs: Outputs;
+
+ /** 插槽 */
+ slots?: Record;
+
+ /** 日志插件 */
+ logger?: Logger;
+
+ /** 用户输入的组件名称 */
+ title?: string;
+
+ /** 组件的外部样式 */
+ readonly style?: React.CSSProperties;
+}
+
+interface EditorResult {
+ data: T;
+ focusArea: any;
+ output: any;
+ input: any;
+ slot?: any;
+ diagram?: any;
+}
+
+interface Data {
+ [key: string]: any;
+}
+
+interface Env {
+ preview?: {};
+ edit?: {};
+ runtime?: any;
+ i18n?: (text: string) => string;
+ [x: string]: any;
+}
+
+interface Inputs {
+ [key: string]: (fn: (val: any, relOutputs?: any) => void) => void;
+}
+
+interface Outputs {
+ [key: string]: (val?: any) => void;
+}
+
+interface Slot {
+ render: (props?: any) => React.ReactNode;
+ [key: string]: any;
+}
+
+interface Logger {
+ info: (msg: string) => void;
+ warn: (msg: string) => void;
+ error: (msg: string) => void;
+}
From 214cb1a7eff9fc1dc193097d90d4118398be1a7d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 26 Jan 2026 09:34:34 +0000
Subject: [PATCH 3/3] Address code review feedback - use strict equality and
optional chaining
Co-authored-by: CheMingjun <18278955+CheMingjun@users.noreply.github.com>
---
.prettierrc | 10 ++++++++++
src/button/runtime.tsx | 4 ++--
src/input/runtime.tsx | 6 +++---
src/text/runtime.tsx | 2 +-
4 files changed, 16 insertions(+), 6 deletions(-)
create mode 100644 .prettierrc
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..1bdee18
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,10 @@
+{
+ "printWidth": 100,
+ "tabWidth": 2,
+ "useTabs": false,
+ "semi": true,
+ "singleQuote": true,
+ "trailingComma": "none",
+ "bracketSpacing": true,
+ "arrowParens": "always"
+}
diff --git a/src/button/runtime.tsx b/src/button/runtime.tsx
index cf6988c..11890b4 100644
--- a/src/button/runtime.tsx
+++ b/src/button/runtime.tsx
@@ -9,11 +9,11 @@ interface Data {
export default function ({ data, inputs, outputs, env }: RuntimeParams) {
useEffect(() => {
- inputs['setText'] && inputs['setText']((value: string) => {
+ inputs['setText']?.((value: string) => {
data.text = value;
});
- inputs['setDisabled'] && inputs['setDisabled']((value: boolean) => {
+ inputs['setDisabled']?.((value: boolean) => {
data.disabled = value;
});
}, []);
diff --git a/src/input/runtime.tsx b/src/input/runtime.tsx
index 3649b99..0dd752d 100644
--- a/src/input/runtime.tsx
+++ b/src/input/runtime.tsx
@@ -11,17 +11,17 @@ export default function ({ data, inputs, outputs, env }: RuntimeParams) {
const [value, setValue] = useState(data.value || '');
useEffect(() => {
- inputs['setValue'] && inputs['setValue']((val: string) => {
+ inputs['setValue']?.((val: string) => {
const newValue = val !== undefined && val !== null ? String(val) : '';
data.value = newValue;
setValue(newValue);
});
- inputs['setPlaceholder'] && inputs['setPlaceholder']((val: string) => {
+ inputs['setPlaceholder']?.((val: string) => {
data.placeholder = val;
});
- inputs['setDisabled'] && inputs['setDisabled']((val: boolean) => {
+ inputs['setDisabled']?.((val: boolean) => {
data.disabled = val;
});
}, []);
diff --git a/src/text/runtime.tsx b/src/text/runtime.tsx
index 8cb09f9..0221278 100644
--- a/src/text/runtime.tsx
+++ b/src/text/runtime.tsx
@@ -9,7 +9,7 @@ export default function ({ data, inputs, outputs, env }: RuntimeParams) {
useEffect(() => {
inputs['content']((value: string, relOutputs) => {
let res = value;
- if (res != undefined && typeof res !== 'string') {
+ if (res !== undefined && typeof res !== 'string') {
res = JSON.stringify(res);
}
data.content = res;