@mybricks/plugin-ai 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -2
- package/src/agents/app.ts +188 -60
- package/src/agents/common.ts +428 -68
- package/src/agents/custom.ts +14 -0
- package/src/agents/index.ts +31 -1
- package/src/agents/knowledges/README.md +614 -0
- package/src/agents/knowledges/SUMMARY.md +527 -0
- package/src/agents/knowledges/index.ts +8 -0
- package/src/agents/knowledges/knowledge-base.ts +565 -0
- package/src/agents/knowledges/knowledge-node.ts +266 -0
- package/src/agents/knowledges/types.ts +208 -0
- package/src/agents/utils/config.ts +427 -0
- package/src/agents/workspace/coding-manager.ts +31 -0
- package/src/agents/workspace/components-manager.ts +124 -0
- package/src/agents/workspace/outline-focus.ts +188 -0
- package/src/agents/workspace/outline-info.ts +520 -0
- package/src/agents/workspace/page-tree-generator.ts +83 -0
- package/src/agents/workspace/workspace.ts +319 -0
- package/src/agents/workspace-by-knowledges/MIGRATION.md +568 -0
- package/src/agents/workspace-by-knowledges/README.md +521 -0
- package/src/agents/workspace-by-knowledges/index.ts +11 -0
- package/src/agents/workspace-by-knowledges/providers/component-docs-provider.ts +92 -0
- package/src/agents/workspace-by-knowledges/providers/focus-info-provider.ts +131 -0
- package/src/agents/workspace-by-knowledges/providers/index.ts +8 -0
- package/src/agents/workspace-by-knowledges/providers/project-info-provider.ts +151 -0
- package/src/agents/workspace-by-knowledges/test.ts +240 -0
- package/src/agents/workspace-by-knowledges/types.ts +56 -0
- package/src/agents/workspace-by-knowledges/utils/components-manager.ts +145 -0
- package/src/agents/workspace-by-knowledges/utils/index.ts +8 -0
- package/src/agents/workspace-by-knowledges/utils/outline-focus.ts +178 -0
- package/src/agents/workspace-by-knowledges/utils/outline-info.ts +521 -0
- package/src/agents/workspace-by-knowledges/workspace.ts +166 -0
- package/src/api/cloud-components.ts +129 -0
- package/src/api-record-replay/README.md +187 -0
- package/src/api-record-replay/index.ts +11 -0
- package/src/api-record-replay/manager.ts +168 -0
- package/src/api-record-replay/recorder.ts +117 -0
- package/src/api-record-replay/replayer.ts +148 -0
- package/src/components/attachments/index.less +117 -0
- package/src/components/attachments/index.tsx +136 -0
- package/src/components/icons/index.tsx +21 -1
- package/src/components/index.less +34 -0
- package/src/components/mention/index.less +23 -0
- package/src/components/mention/index.tsx +19 -0
- package/src/components/messages/index.less +444 -237
- package/src/components/messages/index.tsx +371 -88
- package/src/components/sender/index.less +203 -0
- package/src/components/sender/index.tsx +298 -0
- package/src/components/types.ts +31 -0
- package/src/constants/index.ts +8 -0
- package/src/context/RequestStatusTracker.ts +50 -0
- package/src/context/index.ts +68 -6
- package/src/{types.d.ts → global.d.ts} +40 -5
- package/src/index.tsx +212 -32
- package/src/preset/agents.ts +380 -0
- package/src/preset/createTemplates.ts +25 -0
- package/src/preset/index.ts +12 -0
- package/src/preset/prompts.ts +235 -0
- package/src/preset/requestAsStream.ts +246 -0
- package/src/preset/user.ts +6 -0
- package/src/startView/components/header/header.less +17 -0
- package/src/startView/components/header/header.tsx +15 -0
- package/src/startView/components/index.ts +1 -0
- package/src/startView/index.less +22 -204
- package/src/startView/index.tsx +35 -203
- package/src/tools/analyze-and-expand-prd.ts +192 -86
- package/src/tools/analyze-requirement-and-components.ts +589 -0
- package/src/tools/answer.ts +59 -0
- package/src/tools/build-process.ts +1174 -0
- package/src/tools/coding-subagent-as-tool.ts +119 -0
- package/src/tools/generate-ui-content.ts +1083 -0
- package/src/tools/index.ts +22 -19
- package/src/tools/open-dsl.ts +69 -0
- package/src/tools/refactor-ui-content.ts +801 -0
- package/src/tools/utils.ts +880 -28
- package/src/types/index.ts +4 -0
- package/src/view/components/header/header.less +36 -2
- package/src/view/components/header/header.tsx +47 -2
- package/src/view/components/index.ts +0 -2
- package/src/view/index.tsx +158 -8
- package/src/tools/answer-user.ts +0 -35
- package/src/tools/focus-element.ts +0 -47
- package/src/tools/generate-page.ts +0 -750
- package/src/tools/get-component-info-by-ids.ts +0 -166
- package/src/tools/get-component-info.ts +0 -53
- package/src/tools/get-components-doc-and-prd.ts +0 -137
- package/src/tools/get-focus-mybricks-dsl.ts +0 -26
- package/src/tools/get-mybricks-dsl.ts +0 -73
- package/src/tools/modify-component.ts +0 -385
- package/src/view/components/messages/messages.less +0 -228
- package/src/view/components/messages/messages.tsx +0 -172
- package/src/view/components/sender/sender.less +0 -44
- package/src/view/components/sender/sender.tsx +0 -62
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API 调用回放模块
|
|
3
|
+
* 根据记录的 JSON 序列执行回放
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { RecordedAction, RecordedActionType } from './recorder';
|
|
7
|
+
|
|
8
|
+
export interface ReplayOptions {
|
|
9
|
+
/** 是否忽略时间间隔,立即执行 */
|
|
10
|
+
ignoreDelay?: boolean;
|
|
11
|
+
/** 时间间隔的倍数(用于加速或减速回放) */
|
|
12
|
+
delayMultiplier?: number;
|
|
13
|
+
/** 每个操作执行前的回调 */
|
|
14
|
+
onBeforeAction?: (action: RecordedAction, index: number) => void;
|
|
15
|
+
/** 每个操作执行后的回调 */
|
|
16
|
+
onAfterAction?: (action: RecordedAction, index: number, result: any) => void;
|
|
17
|
+
/** 回放完成后的回调 */
|
|
18
|
+
onComplete?: () => void;
|
|
19
|
+
/** 回放出错时的回调 */
|
|
20
|
+
onError?: (error: Error, action: RecordedAction, index: number) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ReplayAPI {
|
|
24
|
+
createPage: (id: string, title: string, config?: any) => Promise<{ id: string; onProgress: Function; }>;
|
|
25
|
+
createCanvas: () => Promise<{ id: string; title: string; }>;
|
|
26
|
+
updatePage: (...params: any[]) => Promise<void>;
|
|
27
|
+
updateUiCom: (...params: any[]) => Promise<void>;
|
|
28
|
+
updateLogicCom: (...params: any[]) => Promise<void>;
|
|
29
|
+
createDiagram: (...params: any[]) => Promise<any>;
|
|
30
|
+
updateDiagram: (...params: any[]) => Promise<any>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 回放记录的 API 调用
|
|
35
|
+
* @param records 记录的 API 调用序列
|
|
36
|
+
* @param api API 实现对象
|
|
37
|
+
* @param options 回放选项
|
|
38
|
+
*/
|
|
39
|
+
export async function replay(
|
|
40
|
+
records: RecordedAction[],
|
|
41
|
+
api: ReplayAPI,
|
|
42
|
+
options: ReplayOptions = {}
|
|
43
|
+
): Promise<void> {
|
|
44
|
+
const {
|
|
45
|
+
ignoreDelay = false,
|
|
46
|
+
delayMultiplier = 1,
|
|
47
|
+
onBeforeAction,
|
|
48
|
+
onAfterAction,
|
|
49
|
+
onComplete,
|
|
50
|
+
onError,
|
|
51
|
+
} = options;
|
|
52
|
+
|
|
53
|
+
for (let i = 0; i < records.length; i++) {
|
|
54
|
+
const action = records[i];
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
// 执行前回调
|
|
58
|
+
onBeforeAction?.(action, i);
|
|
59
|
+
|
|
60
|
+
// 等待时间间隔
|
|
61
|
+
if (!ignoreDelay && action.delay > 0) {
|
|
62
|
+
const delay = action.delay * delayMultiplier;
|
|
63
|
+
await sleep(delay);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 执行 API 调用
|
|
67
|
+
let result: any;
|
|
68
|
+
switch (action.type) {
|
|
69
|
+
case 'createPage': {
|
|
70
|
+
const [id, title, config] = action.params;
|
|
71
|
+
result = await api.createPage(id, title, config);
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
case 'createCanvas': {
|
|
75
|
+
result = await api.createCanvas();
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
case 'updatePage': {
|
|
79
|
+
// updatePage 的参数是展开的,需要展开传递
|
|
80
|
+
result = await api.updatePage(...action.params);
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
case 'updateUiCom': {
|
|
84
|
+
// updateUiCom 的参数是展开的,需要展开传递
|
|
85
|
+
result = await api.updateUiCom(...action.params);
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case 'updateLogicCom': {
|
|
89
|
+
// updateLogicCom 的参数是展开的,需要展开传递
|
|
90
|
+
result = await api.updateLogicCom(...action.params);
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
case 'createDiagram': {
|
|
94
|
+
// createDiagram 的参数是展开的,需要展开传递
|
|
95
|
+
result = await api.createDiagram(...action.params);
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
case 'updateDiagram': {
|
|
99
|
+
// updateDiagram 的参数是展开的,需要展开传递
|
|
100
|
+
result = await api.updateDiagram(...action.params);
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
default:
|
|
104
|
+
throw new Error(`Unknown action type: ${(action as any).type}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 执行后回调
|
|
108
|
+
onAfterAction?.(action, i, result);
|
|
109
|
+
} catch (error) {
|
|
110
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
111
|
+
onError?.(err, action, i);
|
|
112
|
+
|
|
113
|
+
// 根据选项决定是否继续执行
|
|
114
|
+
// 默认继续执行,只记录错误
|
|
115
|
+
console.error(`Replay error at action ${i} (${action.type}):`, err);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// 完成回调
|
|
120
|
+
onComplete?.();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 从 JSON 字符串加载并回放
|
|
125
|
+
* @param jsonString JSON 字符串
|
|
126
|
+
* @param api API 实现对象
|
|
127
|
+
* @param options 回放选项
|
|
128
|
+
*/
|
|
129
|
+
export async function replayFromJSON(
|
|
130
|
+
jsonString: string,
|
|
131
|
+
api: ReplayAPI,
|
|
132
|
+
options: ReplayOptions = {}
|
|
133
|
+
): Promise<void> {
|
|
134
|
+
try {
|
|
135
|
+
const records: RecordedAction[] = JSON.parse(jsonString);
|
|
136
|
+
await replay(records, api, options);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
throw new Error(`Failed to parse replay JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* 睡眠函数
|
|
144
|
+
*/
|
|
145
|
+
function sleep(ms: number): Promise<void> {
|
|
146
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
147
|
+
}
|
|
148
|
+
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
.attachments {
|
|
2
|
+
display: flex;
|
|
3
|
+
// gap: 8px;
|
|
4
|
+
gap: 4px;
|
|
5
|
+
align-items: center;
|
|
6
|
+
|
|
7
|
+
.imageThumbnail {
|
|
8
|
+
cursor: pointer;
|
|
9
|
+
pointer-events: auto;
|
|
10
|
+
flex-shrink: 0;
|
|
11
|
+
// width: 56px;
|
|
12
|
+
aspect-ratio: 1;
|
|
13
|
+
// min-width: 56px;
|
|
14
|
+
// border-radius: 8px;
|
|
15
|
+
width: 32px;
|
|
16
|
+
height: 32px;
|
|
17
|
+
border-radius: 4px;
|
|
18
|
+
// border: 1px solid rgba(0, 0, 0, .13);
|
|
19
|
+
position: relative;
|
|
20
|
+
// overflow: hidden;
|
|
21
|
+
background: #fff;
|
|
22
|
+
|
|
23
|
+
img {
|
|
24
|
+
// width: 100%;
|
|
25
|
+
// height: 100%;
|
|
26
|
+
width: 32px;
|
|
27
|
+
height: 32px;
|
|
28
|
+
display: inline-block;
|
|
29
|
+
// background-repeat: no-repeat;
|
|
30
|
+
// background-size: cover;
|
|
31
|
+
overflow: hidden;
|
|
32
|
+
// object-fit: contain;
|
|
33
|
+
// background-size: cover;
|
|
34
|
+
// background-position: center;
|
|
35
|
+
// background-repeat: no-repeat;
|
|
36
|
+
border-radius: 4px;
|
|
37
|
+
object-fit: contain;
|
|
38
|
+
outline: 1px solid rgba(0, 0, 0, 0.13);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.imageDeleteContainer {
|
|
42
|
+
visibility: hidden;
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
position: absolute;
|
|
45
|
+
// top: 0;
|
|
46
|
+
// right: 0;
|
|
47
|
+
top: -4px;
|
|
48
|
+
right: -4px;
|
|
49
|
+
// padding: 4px;
|
|
50
|
+
z-index: 2;
|
|
51
|
+
|
|
52
|
+
.imageDeleteIcon {
|
|
53
|
+
width: 12px;
|
|
54
|
+
height: 12px;
|
|
55
|
+
border-radius: 50%;
|
|
56
|
+
background-color: rgba(0, 0, 0, .4);
|
|
57
|
+
display: flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
justify-content: center;
|
|
60
|
+
color: #ffffff;
|
|
61
|
+
|
|
62
|
+
svg {
|
|
63
|
+
width: 8px;
|
|
64
|
+
height: 8px;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&:hover {
|
|
68
|
+
opacity: 0.8;
|
|
69
|
+
background-color: var(--mybricks-color-primary);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.preview {
|
|
75
|
+
z-index: 2000;
|
|
76
|
+
position: absolute;
|
|
77
|
+
width: 300px;
|
|
78
|
+
background: #fff;
|
|
79
|
+
box-shadow: 0 5px 16px -4px rgba(0, 0, 0, 0.07059);
|
|
80
|
+
padding: 10px;
|
|
81
|
+
border-radius: 8px;
|
|
82
|
+
border: 1px solid #f1f1f1;
|
|
83
|
+
visibility: hidden;
|
|
84
|
+
|
|
85
|
+
img {
|
|
86
|
+
width: 280px;
|
|
87
|
+
height: fit-content;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
&:hover {
|
|
92
|
+
.preview {
|
|
93
|
+
visibility: visible;
|
|
94
|
+
}
|
|
95
|
+
.imageDeleteContainer {
|
|
96
|
+
visibility: visible;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.preview {
|
|
103
|
+
z-index: 2000;
|
|
104
|
+
position: absolute;
|
|
105
|
+
width: 300px;
|
|
106
|
+
background: #fff;
|
|
107
|
+
box-shadow: 0 5px 16px -4px rgba(0, 0, 0, 0.07059);
|
|
108
|
+
padding: 10px;
|
|
109
|
+
border-radius: 8px;
|
|
110
|
+
border: 1px solid #f1f1f1;
|
|
111
|
+
visibility: hidden;
|
|
112
|
+
|
|
113
|
+
img {
|
|
114
|
+
width: 280px;
|
|
115
|
+
height: fit-content;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useState, useMemo } from "react";
|
|
2
|
+
import { createPortal } from "react-dom";
|
|
3
|
+
import { Close } from "../icons";
|
|
4
|
+
import css from "./index.less";
|
|
5
|
+
import classNames from "classnames";
|
|
6
|
+
|
|
7
|
+
interface Attachment {
|
|
8
|
+
type: "image";
|
|
9
|
+
content: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface AttachmentsProps {
|
|
13
|
+
attachments: Attachment[];
|
|
14
|
+
className?: string;
|
|
15
|
+
onDelete?: (index: number) => void;
|
|
16
|
+
}
|
|
17
|
+
/** 附件图片 */
|
|
18
|
+
const AttachmentsList = (props: AttachmentsProps) => {
|
|
19
|
+
const { attachments, onDelete, className } = props;
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div className={classNames(css.attachments, className)}>
|
|
23
|
+
{attachments.map((attachment, index) => {
|
|
24
|
+
return <Attachment key={index} attachment={attachment} onDelete={onDelete ? () => onDelete(index) : undefined} />
|
|
25
|
+
})}
|
|
26
|
+
</div>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { AttachmentsList };
|
|
31
|
+
|
|
32
|
+
const Attachment = (props: { attachment: Attachment, onDelete?: () => void; }) => {
|
|
33
|
+
const imgRef = useRef<HTMLImageElement>(null);
|
|
34
|
+
const previewRef = useRef<HTMLDivElement>(null);
|
|
35
|
+
const { attachment, onDelete } = props;
|
|
36
|
+
const [previewBCR, setPreviewBCR] = useState<DOMRect | null>(null);
|
|
37
|
+
const [visible, setVisible] = useState(false);
|
|
38
|
+
|
|
39
|
+
const delayedTask = useMemo(() => {
|
|
40
|
+
return new DelayedTask<[boolean]>((visible) => {
|
|
41
|
+
setVisible(visible);
|
|
42
|
+
}, 50)
|
|
43
|
+
}, [])
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (visible) {
|
|
47
|
+
if (previewBCR) {
|
|
48
|
+
const imgBcr = imgRef.current!.getBoundingClientRect();
|
|
49
|
+
|
|
50
|
+
const topSpace = imgBcr.top - 4 - previewBCR.height;
|
|
51
|
+
|
|
52
|
+
if (topSpace > 0) {
|
|
53
|
+
previewRef.current!.style.top = `${topSpace}px`;
|
|
54
|
+
} else {
|
|
55
|
+
previewRef.current!.style.top = `${imgBcr.top + imgBcr.height}px`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (imgBcr.left + previewBCR.width > document.body.offsetWidth) {
|
|
59
|
+
previewRef.current!.style.left = `${imgBcr.left + imgBcr.width - previewBCR.width}px`
|
|
60
|
+
} else {
|
|
61
|
+
previewRef.current!.style.left = `${imgBcr.left}px`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
previewRef.current!.style.visibility = "visible";
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
previewRef.current!.style.visibility = "hidden";
|
|
68
|
+
}
|
|
69
|
+
}, [previewBCR, visible])
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<>
|
|
73
|
+
<div
|
|
74
|
+
className={css.imageThumbnail}
|
|
75
|
+
onMouseEnter={() => {
|
|
76
|
+
delayedTask.startNow(true);
|
|
77
|
+
}}
|
|
78
|
+
onMouseLeave={() => {
|
|
79
|
+
delayedTask.start(false);
|
|
80
|
+
}}
|
|
81
|
+
>
|
|
82
|
+
<img ref={imgRef} src={attachment.content} />
|
|
83
|
+
{onDelete && <div className={css.imageDeleteContainer} onClick={onDelete}>
|
|
84
|
+
<div className={css.imageDeleteIcon}>
|
|
85
|
+
<Close />
|
|
86
|
+
</div>
|
|
87
|
+
</div>}
|
|
88
|
+
</div>
|
|
89
|
+
{createPortal((
|
|
90
|
+
<div
|
|
91
|
+
ref={previewRef}
|
|
92
|
+
className={css.preview}
|
|
93
|
+
onMouseEnter={() => {
|
|
94
|
+
delayedTask.startNow(true);
|
|
95
|
+
}}
|
|
96
|
+
onMouseLeave={() => {
|
|
97
|
+
delayedTask.start(false);
|
|
98
|
+
}}
|
|
99
|
+
>
|
|
100
|
+
<img src={attachment.content} onLoad={(event) => {
|
|
101
|
+
setPreviewBCR((event.target as HTMLImageElement).parentElement!.getBoundingClientRect())
|
|
102
|
+
}} />
|
|
103
|
+
</div>
|
|
104
|
+
), document.body)}
|
|
105
|
+
</>
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
class DelayedTask<T extends unknown[]> {
|
|
110
|
+
private timerId: number | null = null;
|
|
111
|
+
constructor(private callback: (...args: T) => void, private delay: number) {}
|
|
112
|
+
|
|
113
|
+
start(...args: T) {
|
|
114
|
+
this.cancel();
|
|
115
|
+
this.timerId = setTimeout(() => {
|
|
116
|
+
this.callback(...args);
|
|
117
|
+
this.timerId = null;
|
|
118
|
+
}, this.delay) as unknown as number;
|
|
119
|
+
|
|
120
|
+
return this;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
cancel() {
|
|
124
|
+
if (this.timerId) {
|
|
125
|
+
clearTimeout(this.timerId);
|
|
126
|
+
this.timerId = null;
|
|
127
|
+
}
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
startNow(...args: T) {
|
|
132
|
+
this.cancel();
|
|
133
|
+
this.callback(...args);
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -21,4 +21,24 @@ const Success = () => {
|
|
|
21
21
|
return <svg role="presentation" xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1" viewBox="0 0 14 14"><path d="M12.25,7.000000238418579C12.25,9.899500238418579,9.8995,12.250000238418579,7,12.250000238418579C4.1005,12.250000238418579,1.75,9.899500238418579,1.75,7.000000238418579C1.75,4.100510238418579,4.1005,1.750000238418579,7,1.750000238418579C9.8995,1.750000238418579,12.25,4.100510238418579,12.25,7.000000238418579ZM11.08333,7.000000238418579C11.08333,4.744840238418579,9.25516,2.916670238418579,7,2.916670238418579C4.74484,2.916670238418579,2.91667,4.744840238418579,2.91667,7.000000238418579C2.91667,9.25516023841858,4.74484,11.08333023841858,7,11.08333023841858C9.25516,11.08333023841858,11.08333,9.25516023841858,11.08333,7.000000238418579ZM9.20146,6.202720238418579C9.28673,6.098500238418579,9.33333,5.9679902384185795,9.33333,5.833330238418579C9.33333,5.511170238418579,9.07217,5.250000238418579,8.75,5.250000238418579C8.575040000000001,5.250000238418579,8.4093,5.32853023841858,8.2984,5.464070238418579L6.37337,7.298400238418579L5.6624300000000005,6.587530238418579C5.55304,6.478130238418579,5.40471,6.416670238418579,5.25,6.416670238418579C4.92783,6.416670238418579,4.66667,6.677830238418579,4.66667,7.000000238418579C4.66667,7.154710238418579,4.72809,7.303090238418579,4.8377099999999995,7.412700238418579L6.00423,8.579140238418578C6.01794,8.59285023841858,6.03224,8.605870238418579,6.04724,8.61814023841858C6.29658,8.82215023841858,6.66412,8.785400238418578,6.86812,8.536060238418578L9.20146,6.202720238418579Z" fill="currentColor"></path></svg>
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
const Send = () => {
|
|
25
|
+
return <svg viewBox="0 0 1024 1024" version="1.1"><path d="M24.65 399.36L965.485 7.314a29.257 29.257 0 0 1 39.643 34.085L770.78 978.87a29.257 29.257 0 0 1-47.104 15.36L520.192 824.686a29.257 29.257 0 0 0-39.424 1.828L376.393 930.816a29.257 29.257 0 0 1-49.883-20.626V689.737a29.257 29.257 0 0 1 8.557-20.7L759.515 244.59 258.414 620.47a29.257 29.257 0 0 1-36.28-0.95L17.19 448.805a29.257 29.257 0 0 1 7.46-49.445z" fill="currentColor" p-id="5126"></path></svg>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const Delete = () => {
|
|
29
|
+
return <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16298"><path d="M928.814545 405.783273a28.858182 28.858182 0 0 0 0-40.773818l-309.992727-309.992728a28.858182 28.858182 0 0 0-40.820363 0l-451.118546 451.118546a115.246545 115.246545 0 0 0 0 163.048727l244.968727 243.432727a115.432727 115.432727 0 0 0 81.221819 33.512728h370.501818a28.811636 28.811636 0 1 0 0-57.669819h-238.266182c-51.339636 0-77.079273-62.045091-40.820364-98.443636l384.325818-384.232727zM436.968727 816.174545a57.623273 57.623273 0 0 1-81.501091 0l-187.810909-187.717818a57.623273 57.623273 0 0 1 0-81.501091l115.2-115.2 269.312 269.312-115.2 115.106909z" p-id="16299" fill="currentColor"></path></svg>
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const Export = () => {
|
|
33
|
+
return <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4683"><path d="M712.533333 371.2l-128 128-59.733333-59.733333 128-128L597.333333 256l-42.666666-42.666667h256v256l-42.666667-42.666666-55.466667-55.466667zM657.066667 256H768v110.933333V256h-110.933333zM298.666667 298.666667v426.666666h426.666666v-256l85.333334 85.333334v256H213.333333V213.333333h256l85.333334 85.333334H298.666667z" fill="currentColor" p-id="4684"></path></svg>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const Chat = () => {
|
|
37
|
+
return <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5661"><path d="M767.424 130.032 256.576 130.032c-70.4 0-128 57.6-128 128l0 335.632c0 70.4 57.6 128 128 128l118.352 0 0 172.288 213.328-172.288 179.152 0c70.4 0 128-57.6 128-128L895.408 258.032C895.424 187.632 837.824 130.032 767.424 130.032zM815.424 593.664c0 26.016-21.984 48-48 48L588.272 641.664 560 641.664l-22 17.76-83.056 67.088 0-4.848 0-80-80 0-118.352 0c-26.016 0-48-21.984-48-48L208.592 258.032c0-26.016 21.984-48 48-48l510.848 0c26.016 0 48 21.984 48 48L815.44 593.664z" p-id="5662" fill="currentColor"></path><path d="M347.888 425.872m-46.608 0a2.913 2.913 0 1 0 93.216 0 2.913 2.913 0 1 0-93.216 0Z" p-id="5663" fill="currentColor"></path><path d="M512 425.872m-46.608 0a2.913 2.913 0 1 0 93.216 0 2.913 2.913 0 1 0-93.216 0Z" p-id="5664" fill="currentColor"></path><path d="M676.096 425.872m-46.608 0a2.913 2.913 0 1 0 93.216 0 2.913 2.913 0 1 0-93.216 0Z" p-id="5665" fill="currentColor"></path></svg>
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const Code = () => {
|
|
41
|
+
return <svg viewBox="0 0 1024 1024" p-id="4803"><path d="M318.578 819.2L17.067 512l301.51-307.2 45.512 45.511L96.71 512 364.09 773.689z m386.844 0l-45.51-45.511L927.288 512 659.91 250.311l45.511-45.511L1006.933 512zM540.786 221.867l55.75 11.15-113.379 569.116-55.75-11.093z" fill="currentColor" p-id="4804"></path></svg>
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { ArrowUp, Attachment, Loading, Close, Success, Send, Delete, Export, Chat, Code }
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
.scroll-bar() {
|
|
2
|
+
&::-webkit-scrollbar-thumb {
|
|
3
|
+
background-color: transparent !important;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
&:hover {
|
|
7
|
+
background: transparent; //防止没有激活
|
|
8
|
+
&::-webkit-scrollbar-thumb {
|
|
9
|
+
background-color: rgba(0, 0, 0, 0.3) !important;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.loading-shimmer {
|
|
15
|
+
-webkit-text-fill-color: transparent;
|
|
16
|
+
animation-duration: 3s;
|
|
17
|
+
animation-iteration-count: infinite;
|
|
18
|
+
animation-name: loading-shimmer;
|
|
19
|
+
background: #adadad linear-gradient(to right, #adadad 0, #1a1a1abf 40%, #1a1a1abf 60%, #adadad 100%);
|
|
20
|
+
-webkit-background-clip: text;
|
|
21
|
+
background-clip: text;
|
|
22
|
+
background-repeat: no-repeat;
|
|
23
|
+
background-size: 50% 200%;
|
|
24
|
+
display: inline-block;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@keyframes loading-shimmer {
|
|
28
|
+
0% {
|
|
29
|
+
background-position: -100% 0;
|
|
30
|
+
}
|
|
31
|
+
100% {
|
|
32
|
+
background-position: 250% 0;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
.mention {
|
|
2
|
+
cursor: pointer;
|
|
3
|
+
color: var(--mybricks-color-primary);
|
|
4
|
+
font-size: 12px;
|
|
5
|
+
font-weight: 500;
|
|
6
|
+
line-height: 20px;
|
|
7
|
+
border-radius: 10px;
|
|
8
|
+
// max-width: 88px;
|
|
9
|
+
// width: fit-content;
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
// white-space: nowrap;
|
|
12
|
+
// text-overflow: ellipsis;
|
|
13
|
+
height: 20px;
|
|
14
|
+
display: inline-flex;
|
|
15
|
+
max-width: 100%;
|
|
16
|
+
|
|
17
|
+
.text {
|
|
18
|
+
white-space: nowrap;
|
|
19
|
+
text-overflow: ellipsis;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
// padding: 0 5px; /* 添加内边距 */
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Mention } from "../types";
|
|
3
|
+
import css from "./index.less";
|
|
4
|
+
|
|
5
|
+
interface MentionTagProps {
|
|
6
|
+
mention: Mention
|
|
7
|
+
focusarea?: boolean;
|
|
8
|
+
onClick?: (mention: Mention) => void;
|
|
9
|
+
}
|
|
10
|
+
const MentionTag = (props: MentionTagProps) => {
|
|
11
|
+
const { mention, focusarea, onClick } = props;
|
|
12
|
+
return (
|
|
13
|
+
<div className={css.mention} onClick={() => onClick?.(mention)}>
|
|
14
|
+
<div className={css.text}>{`@${mention.title || mention.name}`}{focusarea && mention.focusArea ? `(${mention.focusArea.title || "区域"})` : ""}</div>
|
|
15
|
+
</div>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export { MentionTag }
|