feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { mergeConfig } from 'vite';
|
||||
import svgr from 'vite-plugin-svgr';
|
||||
|
||||
/** @type { import('@storybook/react-vite').StorybookConfig } */
|
||||
const config = {
|
||||
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.tsx'],
|
||||
addons: [
|
||||
'@storybook/addon-links',
|
||||
'@storybook/addon-essentials',
|
||||
'@storybook/addon-onboarding',
|
||||
'@storybook/addon-interactions',
|
||||
],
|
||||
framework: {
|
||||
name: '@storybook/react-vite',
|
||||
options: {},
|
||||
},
|
||||
docs: {
|
||||
autodocs: 'tag',
|
||||
},
|
||||
viteFinal: config =>
|
||||
mergeConfig(config, {
|
||||
plugins: [
|
||||
svgr({
|
||||
svgrOptions: {
|
||||
native: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
};
|
||||
export default config;
|
||||
@@ -0,0 +1,14 @@
|
||||
/** @type { import('@storybook/react').Preview } */
|
||||
const preview = {
|
||||
parameters: {
|
||||
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/i,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default preview;
|
||||
@@ -0,0 +1,5 @@
|
||||
const { defineConfig } = require('@coze-arch/stylelint-config');
|
||||
|
||||
module.exports = defineConfig({
|
||||
extends: [],
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
# @coze-common/chat-uikit-shared
|
||||
|
||||
> Project template for react component with storybook.
|
||||
|
||||
## Features
|
||||
|
||||
- [x] eslint & ts
|
||||
- [x] esm bundle
|
||||
- [x] umd bundle
|
||||
- [x] storybook
|
||||
|
||||
## Commands
|
||||
|
||||
- init: `rush update`
|
||||
- dev: `npm run dev`
|
||||
- build: `npm run build`
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"operationSettings": [
|
||||
{
|
||||
"operationName": "test:cov",
|
||||
"outputFolderNames": ["coverage"]
|
||||
},
|
||||
{
|
||||
"operationName": "ts-check",
|
||||
"outputFolderNames": ["dist"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
const { defineConfig } = require('@coze-arch/eslint-config');
|
||||
|
||||
module.exports = defineConfig({
|
||||
packageRoot: __dirname,
|
||||
preset: 'web',
|
||||
rules: {},
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "@coze-common/chat-uikit-shared",
|
||||
"version": "0.0.1",
|
||||
"description": "chat uikit shared",
|
||||
"license": "Apache-2.0",
|
||||
"author": "gaoyuanhan.duty@bytedance.com",
|
||||
"maintainers": [],
|
||||
"main": "src/index.ts",
|
||||
"scripts": {
|
||||
"build": "exit 0",
|
||||
"lint": "eslint ./ --cache",
|
||||
"test": "vitest --run --passWithNoTests",
|
||||
"test:cov": "npm run test -- --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@coze-arch/bot-md-box-adapter": "workspace:*",
|
||||
"@coze-common/chat-core": "workspace:*",
|
||||
"@douyinfe/semi-icons": "^2.36.0",
|
||||
"ahooks": "^3.7.8",
|
||||
"classnames": "^2.3.2",
|
||||
"mitt": "^3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@coze-arch/bot-typings": "workspace:*",
|
||||
"@coze-arch/eslint-config": "workspace:*",
|
||||
"@coze-arch/stylelint-config": "workspace:*",
|
||||
"@coze-arch/ts-config": "workspace:*",
|
||||
"@coze-arch/vitest-config": "workspace:*",
|
||||
"@testing-library/jest-dom": "^6.1.5",
|
||||
"@testing-library/react": "^14.1.2",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@types/react": "18.2.37",
|
||||
"@types/react-dom": "18.2.15",
|
||||
"@vitest/coverage-v8": "~3.0.5",
|
||||
"react": "~18.2.0",
|
||||
"react-dom": "~18.2.0",
|
||||
"stylelint": "^15.11.0",
|
||||
"vite-plugin-svgr": "~3.3.0",
|
||||
"vitest": "~3.0.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18.2.0",
|
||||
"react-dom": ">=18.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FILE_TYPE_CONFIG } from '@coze-common/chat-core/shared/const';
|
||||
|
||||
const BYTES = 1024;
|
||||
export const MAX_FILE_MBYTE = 500;
|
||||
|
||||
export const DEFAULT_MAX_FILE_SIZE = MAX_FILE_MBYTE * BYTES * BYTES;
|
||||
|
||||
export const enum UploadType {
|
||||
IMAGE = 0,
|
||||
FILE = 1,
|
||||
}
|
||||
|
||||
export const ACCEPT_FILE_EXTENSION = FILE_TYPE_CONFIG.map(cnf => cnf.accept)
|
||||
.flat(1)
|
||||
.join(',');
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type PropsWithChildren, createContext } from 'react';
|
||||
|
||||
import mitt from 'mitt';
|
||||
import { useCreation } from 'ahooks';
|
||||
|
||||
import {
|
||||
type UIKitEventMap,
|
||||
type UIKitEventCenter,
|
||||
type UIKitEventProviderProps,
|
||||
} from './type';
|
||||
import { useObserveChatContainer } from './hooks';
|
||||
|
||||
export const UIKitEventContext = createContext<UIKitEventCenter | null>(null);
|
||||
|
||||
export const UIKitEventProvider: React.FC<
|
||||
PropsWithChildren<UIKitEventProviderProps>
|
||||
> = ({ chatContainerRef, children }) => {
|
||||
const eventCenter = useCreation(() => mitt<UIKitEventMap>(), []);
|
||||
|
||||
useObserveChatContainer({ eventCenter, chatContainerRef });
|
||||
|
||||
return (
|
||||
<UIKitEventContext.Provider value={eventCenter}>
|
||||
{children}
|
||||
</UIKitEventContext.Provider>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useEffect, type RefObject } from 'react';
|
||||
|
||||
import { type Emitter } from 'mitt';
|
||||
|
||||
import { UIKitEvents, type UIKitEventMap } from './type';
|
||||
|
||||
export const useObserveChatContainer = ({
|
||||
eventCenter,
|
||||
chatContainerRef,
|
||||
}: {
|
||||
eventCenter: Emitter<UIKitEventMap>;
|
||||
chatContainerRef: RefObject<HTMLDivElement>;
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
if (!chatContainerRef.current) {
|
||||
return;
|
||||
}
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
eventCenter.emit(UIKitEvents.WINDOW_RESIZE);
|
||||
});
|
||||
|
||||
resizeObserver.observe(chatContainerRef.current);
|
||||
|
||||
return () => {
|
||||
resizeObserver.disconnect();
|
||||
};
|
||||
}, []);
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { UIKitEventContext } from './context';
|
||||
|
||||
export const useUiKitEventCenter = () => useContext(UIKitEventContext);
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type RefObject } from 'react';
|
||||
|
||||
import { type Emitter } from 'mitt';
|
||||
|
||||
export enum UIKitEvents {
|
||||
WINDOW_RESIZE,
|
||||
AFTER_CARD_RENDER,
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- mitt 的类型不认 interface
|
||||
export type UIKitEventMap = {
|
||||
[UIKitEvents.WINDOW_RESIZE]: undefined;
|
||||
[UIKitEvents.AFTER_CARD_RENDER]: { messageId: string };
|
||||
};
|
||||
|
||||
export type UIKitEventCenter = Emitter<UIKitEventMap>;
|
||||
|
||||
export interface UIKitEventProviderProps {
|
||||
chatContainerRef: RefObject<HTMLDivElement>;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export {
|
||||
type ICardEmptyConfig,
|
||||
type ICopywritingConfig,
|
||||
type IMessage,
|
||||
type IBaseContentProps,
|
||||
type IContentConfig,
|
||||
type IContentConfigs,
|
||||
type ICardCopywritingConfig,
|
||||
type IFileCopywritingConfig,
|
||||
type IChatUploadCopywritingConfig,
|
||||
type IconType,
|
||||
Layout,
|
||||
} from './types/common';
|
||||
|
||||
export {
|
||||
type IContent,
|
||||
type ISuggestionContent,
|
||||
type IImageContent,
|
||||
type IFileContent,
|
||||
type IFunctionCallContent,
|
||||
type GetBotInfo,
|
||||
type MdBoxProps,
|
||||
ContentBoxType,
|
||||
} from './types/content';
|
||||
|
||||
export {
|
||||
type ISimpleFunctionContentCopywriting,
|
||||
type IChatInputCopywritingConfig,
|
||||
} from './types/copywriting';
|
||||
|
||||
export {
|
||||
type IEventCallbacksParams,
|
||||
type LinkEventData,
|
||||
type IOnLinkClickParams,
|
||||
type IOnImageClickParams,
|
||||
type IOnCancelUploadParams,
|
||||
type IOnRetryUploadParams,
|
||||
type IOnSuggestionClickParams,
|
||||
type IOnMessageRetryParams,
|
||||
type IOnCopyUploadParams,
|
||||
type IOnCardSendMsg,
|
||||
type IOnCardUpdateStatus,
|
||||
type MouseEventProps,
|
||||
type IEventCallbacks,
|
||||
} from './types/event';
|
||||
|
||||
export {
|
||||
type IFileInfo,
|
||||
type IFileUploadInfo,
|
||||
type IFileAttributeKeys,
|
||||
type IFileCardTooltipsCopyWritingConfig,
|
||||
} from './types/file';
|
||||
|
||||
export { useUiKitEventCenter } from './context/event-center';
|
||||
|
||||
export {
|
||||
UIKitEvents,
|
||||
type UIKitEventMap,
|
||||
type UIKitEventCenter,
|
||||
type UIKitEventProviderProps,
|
||||
} from './context/event-center/type';
|
||||
|
||||
export {
|
||||
UIKitEventContext,
|
||||
UIKitEventProvider,
|
||||
} from './context/event-center/context';
|
||||
|
||||
export { useObserveChatContainer } from './context/event-center/hooks';
|
||||
|
||||
export {
|
||||
UploadType,
|
||||
MAX_FILE_MBYTE,
|
||||
DEFAULT_MAX_FILE_SIZE,
|
||||
ACCEPT_FILE_EXTENSION,
|
||||
} from './constants/file';
|
||||
|
||||
export {
|
||||
type MentionList,
|
||||
type SendButtonProps,
|
||||
type SendFileMessagePayload,
|
||||
type SendTextMessagePayload,
|
||||
type UiKitChatInputButtonConfig,
|
||||
type UiKitChatInputButtonStatus,
|
||||
type IChatInputProps,
|
||||
type InputMode,
|
||||
} from './types/chat-input';
|
||||
|
||||
export {
|
||||
type AudioRecordProps,
|
||||
type AudioRecordEvents,
|
||||
type AudioRecordOptions,
|
||||
} from './types/chat-input/audio-record';
|
||||
|
||||
export {
|
||||
type InputNativeCallbacks,
|
||||
type InputState,
|
||||
type InputController,
|
||||
type OnBeforeProcessKeyDown,
|
||||
} from './types/chat-input/input-native-callbacks';
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export interface AudioRecordProps {
|
||||
isPointerMoveOut?: boolean;
|
||||
isRecording?: boolean;
|
||||
getVolume?: () => number;
|
||||
text?: string;
|
||||
}
|
||||
|
||||
type EventType = MouseEvent | TouchEvent | KeyboardEvent;
|
||||
type InteractionEventType = EventType | KeyboardEvent;
|
||||
|
||||
export interface AudioRecordEvents {
|
||||
onStart?: (eventType: InteractionEventType) => void;
|
||||
onEnd?: (eventType: InteractionEventType | undefined) => void;
|
||||
onMoveLeave?: () => void;
|
||||
onMoveEnter?: () => void;
|
||||
}
|
||||
|
||||
export interface AudioRecordOptions {
|
||||
getIsShortcutKeyDisabled?: () => boolean;
|
||||
/** 参考 ahooks useKeypress 入参 */
|
||||
shortcutKey?: string | number;
|
||||
enabled?: boolean;
|
||||
getActiveZoneTarget?: () => HTMLElement | null;
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type ClipboardEventHandler,
|
||||
type PropsWithChildren,
|
||||
type ReactNode,
|
||||
type ComponentType,
|
||||
type FocusEventHandler,
|
||||
} from 'react';
|
||||
|
||||
import { type IChatInputCopywritingConfig } from '../copywriting';
|
||||
import { type Layout } from '../common';
|
||||
import { type UploadType } from '../../constants/file';
|
||||
import { type InputNativeCallbacks } from './input-native-callbacks';
|
||||
import {
|
||||
type AudioRecordEvents,
|
||||
type AudioRecordOptions,
|
||||
type AudioRecordProps,
|
||||
} from './audio-record';
|
||||
|
||||
export type InputMode = 'input' | 'audio';
|
||||
|
||||
export type MentionList = { id: string }[];
|
||||
|
||||
export interface SendTextMessagePayload {
|
||||
text: string;
|
||||
mentionList: MentionList;
|
||||
}
|
||||
export interface SendFileMessagePayload {
|
||||
file: File;
|
||||
mentionList: MentionList;
|
||||
}
|
||||
|
||||
export interface UiKitChatInputButtonStatus {
|
||||
isSendButtonDisabled: boolean;
|
||||
isClearHistoryButtonDisabled: boolean;
|
||||
isClearContextButtonDisabled: boolean;
|
||||
isMoreButtonDisabled: boolean;
|
||||
}
|
||||
|
||||
export interface UiKitChatInputButtonConfig {
|
||||
isSendButtonVisible: boolean;
|
||||
isClearHistoryButtonVisible: boolean;
|
||||
isMoreButtonVisible: boolean;
|
||||
isClearContextButtonVisible: boolean;
|
||||
}
|
||||
|
||||
export interface SendButtonProps {
|
||||
isDisabled?: boolean;
|
||||
tooltipContent?: ReactNode;
|
||||
onClick: () => void;
|
||||
layout?: Layout;
|
||||
}
|
||||
|
||||
// export type InputMode = 'input' | 'audio';
|
||||
|
||||
export interface IChatInputProps {
|
||||
/**
|
||||
* submit 过程
|
||||
* 用户操作触发事件 -> 执行 submit -> 执行清空输入框内容
|
||||
* @returns false 阻止 submit 流程
|
||||
*/
|
||||
onBeforeSubmit?: () => boolean;
|
||||
/**
|
||||
* input focus 事件回调
|
||||
*/
|
||||
onFocus?: FocusEventHandler<HTMLTextAreaElement>;
|
||||
/**
|
||||
* input blur 事件回调
|
||||
*/
|
||||
onBlur?: FocusEventHandler<HTMLTextAreaElement>;
|
||||
/**
|
||||
* 发送消息Message事件回调
|
||||
*/
|
||||
onSendMessage?: (payload: SendTextMessagePayload) => void;
|
||||
|
||||
/**
|
||||
* 清除上下文事件回调
|
||||
*/
|
||||
onClearContext?: () => void;
|
||||
|
||||
/**
|
||||
* 清除历史事件回调
|
||||
*/
|
||||
onClearHistory?: () => void;
|
||||
|
||||
/**
|
||||
* 上传事件回调
|
||||
* @param uploadType 上传类型 [IMAGE=0 FILE=1]
|
||||
* @param file 文件
|
||||
* @returns void
|
||||
*/
|
||||
onUpload?: (uploadType: UploadType, payload: SendFileMessagePayload) => void;
|
||||
|
||||
/**
|
||||
* 整个输入框组件是否只读(包括按钮)
|
||||
*/
|
||||
isReadonly?: boolean;
|
||||
|
||||
/**
|
||||
* 输入框是否只读
|
||||
*/
|
||||
isInputReadonly?: boolean;
|
||||
|
||||
/**
|
||||
* 文案配置
|
||||
*/
|
||||
copywritingConfig?: IChatInputCopywritingConfig;
|
||||
|
||||
/**
|
||||
* 左侧插槽
|
||||
*/
|
||||
leftActions?: ReactNode;
|
||||
|
||||
/**
|
||||
* 右侧插槽
|
||||
*/
|
||||
rightActions?: ReactNode;
|
||||
|
||||
/**
|
||||
* 自定义发送按钮
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
CustomSendButton?: ComponentType<SendButtonProps>;
|
||||
|
||||
/**
|
||||
* 顶部插槽
|
||||
*/
|
||||
addonTop?: ReactNode;
|
||||
/**
|
||||
* 左侧插槽
|
||||
*/
|
||||
addonLeft?: ReactNode;
|
||||
/**
|
||||
* 整个 textarea 顶部插槽,mentionList 放在这里
|
||||
*/
|
||||
aboveOutside?: ReactNode;
|
||||
|
||||
/**
|
||||
* 内置按钮置灰状态
|
||||
*/
|
||||
buildInButtonStatus?: Partial<UiKitChatInputButtonStatus>;
|
||||
|
||||
/**
|
||||
* 内置按钮配置
|
||||
*/
|
||||
buildInButtonConfig?: Partial<UiKitChatInputButtonConfig>;
|
||||
/**
|
||||
* 输入框点击事件
|
||||
* @returns void
|
||||
*/
|
||||
onInputClick?: () => void;
|
||||
/**
|
||||
* @deprecated 废弃不消费
|
||||
*/
|
||||
className?: string;
|
||||
/**
|
||||
* 外容器的 classname
|
||||
*/
|
||||
wrapperClassName?: string;
|
||||
/**
|
||||
* 除了输入框中的文字 用户也输入了别的可以发送的内容
|
||||
* 目的是适配文件消息同时发送需求
|
||||
*/
|
||||
hasOtherContentToSend?: boolean;
|
||||
|
||||
/**
|
||||
* 布局方式
|
||||
*/
|
||||
layout: Layout;
|
||||
|
||||
/**
|
||||
* 可上传文件是否超过数量
|
||||
*/
|
||||
isFileCountExceedsLimit: (fileCount: number) => boolean;
|
||||
inputTooltip?: ComponentType<PropsWithChildren>;
|
||||
/**
|
||||
* 是否是背景图模式
|
||||
*/
|
||||
showBackground?: boolean;
|
||||
/**
|
||||
* 限制文件数量
|
||||
*/
|
||||
limitFileCount?: number;
|
||||
/**
|
||||
* 粘贴事件的回调
|
||||
*/
|
||||
onPaste?: ClipboardEventHandler<HTMLTextAreaElement>;
|
||||
inputNativeCallbacks?: InputNativeCallbacks;
|
||||
audioRecordEvents?: AudioRecordEvents;
|
||||
audioRecordState?: AudioRecordProps;
|
||||
audioRecordOptions?: AudioRecordOptions;
|
||||
inputMode?: InputMode;
|
||||
onInputModeChange?: (mode: InputMode) => void;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type KeyboardEvent, type KeyboardEventHandler } from 'react';
|
||||
|
||||
export interface InputState {
|
||||
inputText: string;
|
||||
isComposing: boolean;
|
||||
isDisabled: boolean;
|
||||
selection: { start: number; end: number };
|
||||
hasSelection: boolean;
|
||||
}
|
||||
|
||||
export interface InputController {
|
||||
readState: () => InputState;
|
||||
/**
|
||||
* by imperative layoutEffect
|
||||
*/
|
||||
requireSetMousePosition: (pos: number) => void;
|
||||
setInputText: (updater: string | ((pre: string) => string)) => void;
|
||||
focus: () => void;
|
||||
}
|
||||
|
||||
type ProcessRet =
|
||||
| {
|
||||
exit: boolean;
|
||||
}
|
||||
| undefined;
|
||||
|
||||
export type OnBeforeProcessKeyDown = (
|
||||
evt: KeyboardEvent<HTMLTextAreaElement>,
|
||||
) => ProcessRet;
|
||||
|
||||
export interface InputNativeCallbacks {
|
||||
onAfterProcessKeyUp?: KeyboardEventHandler<HTMLTextAreaElement>;
|
||||
onBeforeProcessKeyDown?: OnBeforeProcessKeyDown;
|
||||
getController?: (controller: InputController) => void;
|
||||
/**
|
||||
* 在 onChange 后触发,但是等待一个 Promise,避开闭包问题
|
||||
*/
|
||||
onAfterOnChange?: () => void;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type ForwardRefExoticComponent, type RefAttributes } from 'react';
|
||||
|
||||
import type { ContentType, Message } from '@coze-common/chat-core';
|
||||
import { type IconProps } from '@douyinfe/semi-icons';
|
||||
|
||||
import {
|
||||
type IFileAttributeKeys,
|
||||
type IFileCardTooltipsCopyWritingConfig,
|
||||
} from './file';
|
||||
import { type ISimpleFunctionContentCopywriting } from './copywriting';
|
||||
import { type ContentBoxType } from './content';
|
||||
|
||||
export type ICardEmptyConfig = Partial<{
|
||||
title: string;
|
||||
description: string;
|
||||
}>;
|
||||
|
||||
export interface ICopywritingConfig {
|
||||
cardEmpty?: ICardEmptyConfig;
|
||||
file?: IFileCardTooltipsCopyWritingConfig;
|
||||
}
|
||||
|
||||
export type IMessage = Message<ContentType>;
|
||||
|
||||
export interface IBaseContentProps {
|
||||
message: IMessage;
|
||||
readonly?: boolean;
|
||||
showBackground?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export interface IContentConfig<T = Record<string, unknown>> {
|
||||
enable?: boolean;
|
||||
copywriting?: T;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后续维护注意,需要扩展参数的类型的卡片默认关闭
|
||||
*/
|
||||
export type IContentConfigs = Partial<{
|
||||
[ContentBoxType.TAKO]: IContentConfig;
|
||||
[ContentBoxType.CARD]: IContentConfig<ICardCopywritingConfig> & {
|
||||
region: unknown;
|
||||
};
|
||||
[ContentBoxType.IMAGE]: IContentConfig;
|
||||
[ContentBoxType.TEXT]: IContentConfig;
|
||||
[ContentBoxType.FILE]: IContentConfig<IFileCopywritingConfig> & {
|
||||
fileAttributeKeys?: IFileAttributeKeys;
|
||||
};
|
||||
[ContentBoxType.SIMPLE_FUNCTION]: IContentConfig<ISimpleFunctionContentCopywriting>;
|
||||
}>;
|
||||
|
||||
export interface ICardCopywritingConfig {
|
||||
empty: ICardEmptyConfig;
|
||||
}
|
||||
|
||||
export interface IFileCopywritingConfig {
|
||||
tooltips: IFileCardTooltipsCopyWritingConfig;
|
||||
}
|
||||
|
||||
export type IChatUploadCopywritingConfig = Partial<{
|
||||
fileSizeReachLimitToast: string;
|
||||
fileExceedsLimitToast: string;
|
||||
fileEmptyToast: string;
|
||||
}>;
|
||||
|
||||
export enum Layout {
|
||||
MOBILE = 'mobile',
|
||||
PC = 'pc',
|
||||
}
|
||||
|
||||
export type IconType = ForwardRefExoticComponent<
|
||||
Omit<IconProps, 'ref' | 'svg'> & RefAttributes<HTMLSpanElement>
|
||||
>;
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type FileMessageContent,
|
||||
type ImageMessageContent,
|
||||
} from '@coze-common/chat-core';
|
||||
import { type MdBoxLazyProps } from '@coze-arch/bot-md-box-adapter/lazy';
|
||||
|
||||
import { type IMessage } from './common';
|
||||
|
||||
export type IContent = ISuggestionContent | IImageContent;
|
||||
|
||||
export type ISuggestionContent = IMessage[];
|
||||
|
||||
export type IImageContent = ImageMessageContent;
|
||||
|
||||
export interface IFileContent {
|
||||
file_list: Array<
|
||||
FileMessageContent['file_list'][0] & {
|
||||
upload_status?: number;
|
||||
upload_percent?: number;
|
||||
}
|
||||
>;
|
||||
}
|
||||
|
||||
export const enum ContentBoxType {
|
||||
TEXT = 1,
|
||||
IMAGE = 2,
|
||||
CARD = 3,
|
||||
FILE = 4,
|
||||
TAKO = 5,
|
||||
SUGGESTION = 100,
|
||||
SIMPLE_FUNCTION = 101,
|
||||
}
|
||||
|
||||
export interface IFunctionCallContent {
|
||||
name: string;
|
||||
arguments: {
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type GetBotInfo = (id: string) => { nickname: string } | undefined;
|
||||
|
||||
export type MdBoxProps = Pick<
|
||||
MdBoxLazyProps,
|
||||
'insertedElements' | 'enabledHtmlTags' | 'slots'
|
||||
>;
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type ReactNode } from 'react';
|
||||
|
||||
import { type IChatUploadCopywritingConfig } from './common';
|
||||
|
||||
export interface ISimpleFunctionContentCopywriting {
|
||||
using: string;
|
||||
}
|
||||
|
||||
export type IChatInputCopywritingConfig = Partial<{
|
||||
tooltip: Partial<{
|
||||
sendButtonTooltipContent: ReactNode | string;
|
||||
clearHistoryButtonTooltipContent: ReactNode | string;
|
||||
clearContextButtonTooltipContent: ReactNode | string;
|
||||
moreButtonTooltipContent: ReactNode | string;
|
||||
audioButtonTooltipContent: ReactNode | string;
|
||||
keyboardButtonTooltipContent: ReactNode | string;
|
||||
}>;
|
||||
inputPlaceholder: string;
|
||||
uploadConfig: IChatUploadCopywritingConfig;
|
||||
bottomTips: string;
|
||||
}>;
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type MouseEvent } from 'react';
|
||||
|
||||
import { type SendMessageOptions } from '@coze-common/chat-core';
|
||||
|
||||
import { type IMessage } from './common';
|
||||
|
||||
export interface IEventCallbacksParams<T = Record<string, unknown>> {
|
||||
message: IMessage;
|
||||
extra: T;
|
||||
}
|
||||
|
||||
export interface LinkEventData {
|
||||
url: string;
|
||||
parsedUrl: URL;
|
||||
exts: {
|
||||
// type: LinkType;
|
||||
wiki_link?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type IOnLinkClickParams = IEventCallbacksParams<LinkEventData>;
|
||||
|
||||
export type IOnImageClickParams = IEventCallbacksParams<{
|
||||
url: string;
|
||||
}>;
|
||||
|
||||
export type IOnCancelUploadParams = IEventCallbacksParams;
|
||||
|
||||
export type IOnRetryUploadParams = IEventCallbacksParams;
|
||||
|
||||
export type IOnSuggestionClickParams = IEventCallbacksParams<{
|
||||
text: string;
|
||||
mentionList: { id: string }[];
|
||||
}>;
|
||||
|
||||
export type IOnMessageRetryParams = IEventCallbacksParams;
|
||||
|
||||
export type IOnCopyUploadParams = IEventCallbacksParams<{ fileIndex?: number }>;
|
||||
|
||||
export type IOnCardSendMsg = IEventCallbacksParams<{
|
||||
msg: string;
|
||||
mentionList: { id: string }[];
|
||||
options?: SendMessageOptions;
|
||||
}>;
|
||||
export type IOnCardUpdateStatus = IEventCallbacksParams;
|
||||
|
||||
export interface MouseEventProps {
|
||||
element: HTMLElement;
|
||||
link: string;
|
||||
}
|
||||
|
||||
export type IEventCallbacks = Partial<{
|
||||
// 点击 md 中链接的回调函数
|
||||
onLinkClick: (
|
||||
params: IOnLinkClickParams,
|
||||
event: MouseEvent<Element, globalThis.MouseEvent>,
|
||||
) => void;
|
||||
// 图片点击事件响应
|
||||
onImageClick: (params: IOnImageClickParams) => void;
|
||||
// 取消上传事件响应
|
||||
onCancelUpload: (params: IOnCancelUploadParams) => void;
|
||||
// 恢复上传事件响应
|
||||
onRetryUpload: (params: IOnRetryUploadParams) => void;
|
||||
// 拷贝文件链接
|
||||
onCopyUpload: (params: IOnCopyUploadParams) => void;
|
||||
// 重新发送
|
||||
onMessageRetry: (params: IOnMessageRetryParams) => void;
|
||||
// 点击卡片按钮的事件响应
|
||||
onCardSendMsg: (params: IOnCardSendMsg) => void;
|
||||
// 更新卡片状态
|
||||
onCardUpdateStatus: (params: IOnCardUpdateStatus) => void;
|
||||
onCardLinkElementEnter?: (params: MouseEventProps) => void;
|
||||
onCardLinkElementLeave?: (params: MouseEventProps) => void;
|
||||
onMdBoxLinkElementEnter?: (params: MouseEventProps) => void;
|
||||
onMdBoxLinkElementLeave?: (params: MouseEventProps) => void;
|
||||
onMdBoxImageElementEnter?: (params: MouseEventProps) => void;
|
||||
onMdBoxImageElementLeave?: (params: MouseEventProps) => void;
|
||||
}>;
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type FileMessageContent } from '@coze-common/chat-core';
|
||||
|
||||
export type IFileInfo = FileMessageContent['file_list'][0] & {
|
||||
upload_status?: number;
|
||||
upload_percent?: number;
|
||||
};
|
||||
|
||||
export interface IFileUploadInfo {
|
||||
status: 'uploading' | 'uploaded' | 'failed';
|
||||
percent: number;
|
||||
}
|
||||
|
||||
export interface IFileAttributeKeys {
|
||||
statusKey: string;
|
||||
statusEnum: {
|
||||
successEnum: number;
|
||||
failEnum: number;
|
||||
cancelEnum: number;
|
||||
uploadingEnum: number;
|
||||
};
|
||||
percentKey: string;
|
||||
}
|
||||
|
||||
export interface IFileCardTooltipsCopyWritingConfig {
|
||||
cancel: string;
|
||||
copy: string;
|
||||
retry: string;
|
||||
}
|
||||
17
frontend/packages/common/chat-area/chat-uikit-shared/src/typings.d.ts
vendored
Normal file
17
frontend/packages/common/chat-area/chat-uikit-shared/src/typings.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/// <reference types='@coze-arch/bot-typings' />
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"extends": "@coze-arch/ts-config/tsconfig.web.json",
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"jsx": "react-jsx",
|
||||
"lib": ["DOM", "ESNext"],
|
||||
"module": "ESNext",
|
||||
"target": "ES2020",
|
||||
"moduleResolution": "bundler",
|
||||
"tsBuildInfoFile": "dist/tsconfig.build.tsbuildinfo"
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../../arch/bot-md-box-adapter/tsconfig.build.json"
|
||||
},
|
||||
{
|
||||
"path": "../../../arch/bot-typings/tsconfig.build.json"
|
||||
},
|
||||
{
|
||||
"path": "../chat-core/tsconfig.build.json"
|
||||
},
|
||||
{
|
||||
"path": "../../../../config/eslint-config/tsconfig.build.json"
|
||||
},
|
||||
{
|
||||
"path": "../../../../config/stylelint-config/tsconfig.build.json"
|
||||
},
|
||||
{
|
||||
"path": "../../../../config/ts-config/tsconfig.build.json"
|
||||
},
|
||||
{
|
||||
"path": "../../../../config/vitest-config/tsconfig.build.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"exclude": ["**/*"],
|
||||
"compilerOptions": {
|
||||
"composite": true
|
||||
},
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.build.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.misc.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "@coze-arch/ts-config/tsconfig.web.json",
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./",
|
||||
"outDir": "./dist",
|
||||
"jsx": "react-jsx",
|
||||
"lib": ["DOM", "ESNext"],
|
||||
"module": "ESNext",
|
||||
"target": "ES2020",
|
||||
"moduleResolution": "bundler"
|
||||
},
|
||||
"include": ["__tests__", "vitest.config.ts", "stories"],
|
||||
"exclude": ["./dist"],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.build.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { defineConfig } from '@coze-arch/vitest-config';
|
||||
|
||||
export default defineConfig({
|
||||
dirname: __dirname,
|
||||
preset: 'web',
|
||||
});
|
||||
Reference in New Issue
Block a user