feat: manually mirror opencoze's code from bytedance

Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
fanlv
2025-07-20 17:36:12 +08:00
commit 890153324f
14811 changed files with 1923430 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
/*
* 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 { connect, mapProps } from '@formily/react';
import { FileUpload as FileUploadAdapter } from '../../file-upload';
export const FileUpload = connect(
FileUploadAdapter,
mapProps({ validateStatus: true }),
);

View 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.
*/
export { FileUpload } from './file-upload';

View File

@@ -0,0 +1,49 @@
.form-item {
margin-bottom: 8px;
}
.form-item-label {
margin-bottom: 4px;
font-size: 12px;
overflow-wrap: break-word;
.form-item-label-top {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 2px;
}
.top-left {
display: flex;
align-items: center;
}
.tag {
flex-shrink: 0;
margin-left: 4px;
}
}
.label-tooltip {
color: var(--coz-fg-secondary);
margin-left: 2px;
}
.form-item-label-text {
font-weight: 500;
color: #1D1C23;
}
.form-item-label-asterisk {
color: var(--coz-fg-hglt-red);
}
.form-item-feedback-wrap {
min-height: 16px;
margin-top: 4px;
line-height: 16px;
overflow-wrap: break-word;
}
.form-item-feedback-text {
color: var(--coz-fg-hglt-red);
}

View File

@@ -0,0 +1,121 @@
/*
* 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.
*/
/**
* test run test form 布局的 FormItem
*/
import React, { type FC, type ReactNode, type PropsWithChildren } from 'react';
import { connect, mapProps } from '@formily/react';
import { isDataField } from '@formily/core';
import { IconCozInfoCircle } from '@coze-arch/coze-design/icons';
import { Tooltip, Typography, Tag } from '@coze-arch/coze-design';
import styles from './index.module.less';
export interface FormItemProps {
required?: boolean;
label?: ReactNode;
description?: ReactNode;
tag?: ReactNode;
tooltip?: ReactNode;
feedbackText?: ReactNode;
action?: ReactNode;
}
export const FormItemAdapter: FC<PropsWithChildren<FormItemProps>> = props => {
const {
required,
label,
feedbackText,
description,
tooltip,
tag,
action,
children,
} = props;
return (
<div className={styles['form-item']}>
<div className={styles['form-item-label']}>
<div className={styles['form-item-label-top']}>
<div className={styles['top-left']}>
<span className={styles['form-item-label-text']}>{label}</span>
{required ? (
<span className={styles['form-item-label-asterisk']}>*</span>
) : null}
{tooltip ? (
<Tooltip content={tooltip}>
<IconCozInfoCircle className={styles['label-tooltip']} />
</Tooltip>
) : null}
{tag ? (
<Tag className={styles.tag} size="mini" color="primary">
{tag}
</Tag>
) : null}
</div>
{action}
</div>
{description ? (
<Typography.Text
size="small"
type="secondary"
ellipsis={{
showTooltip: true,
}}
>
{description}
</Typography.Text>
) : null}
</div>
<div>{children}</div>
{feedbackText ? (
<div className={styles['form-item-feedback-wrap']}>
<Typography.Text
size="small"
className={styles['form-item-feedback-text']}
>
{feedbackText}
</Typography.Text>
</div>
) : null}
</div>
);
};
const FormItem = connect(
FormItemAdapter,
mapProps(
{
title: 'label',
required: true,
tag: true,
description: true,
} as any,
(props, field) => ({
...props,
feedbackText:
isDataField(field) && field.selfErrors?.length
? field.selfErrors
: undefined,
}),
),
);
export { FormItem };

View File

@@ -0,0 +1,41 @@
.form-section :global .coz-icon-button-mini {
line-height: 0px;
}
.form-section {
border-bottom: 1px solid var(--coz-stroke-primary);
}
.section-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 16px 10px 2px;
}
.section-title {
display: flex;
align-items: center;
column-gap: 4px;
cursor: pointer;
.title-collapsible {
color: var(--coz-fg-secondary);
font-size: 12px;
margin-right: -2px;
}
.is-close {
transform: rotate(-90deg);
}
.title-tooltip {
font-size: 14px;
color: var(--coz-fg-secondary);
}
}
.section-context {
padding: 0 16px 10px 16px ;
}

View File

@@ -0,0 +1,83 @@
/*
* 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 React, { useState } from 'react';
import cls from 'classnames';
import {
IconCozArrowDownFill,
IconCozInfoCircle,
} from '@coze-arch/coze-design/icons';
import { Collapsible, Tooltip, Typography } from '@coze-arch/coze-design';
import css from './index.module.less';
export interface FormSectionProps {
title?: React.ReactNode;
tooltip?: React.ReactNode;
action?: React.ReactNode;
collapsible?: boolean;
}
export const FormSection: React.FC<
React.PropsWithChildren<FormSectionProps>
> = ({ title, tooltip, action, collapsible, children }) => {
const [isOpen, setIsOpen] = useState(true);
const handleExpand = () => {
setIsOpen(!isOpen);
};
return (
<div className={css['form-section']}>
<div className={css['section-header']}>
<div
className={css['section-title']}
onClick={collapsible ? handleExpand : undefined}
>
{collapsible ? (
<IconCozArrowDownFill
className={cls(css['title-collapsible'], {
[css['is-close']]: !isOpen,
})}
/>
) : null}
<Typography.Text strong>{title}</Typography.Text>
{tooltip ? (
<Tooltip content={tooltip}>
<IconCozInfoCircle className={css['title-tooltip']} />
</Tooltip>
) : null}
</div>
{action ? (
<div
className={css['section-action']}
onClick={e => {
e.stopPropagation();
}}
>
{action}
</div>
) : null}
</div>
<Collapsible keepDOM fade isOpen={isOpen}>
<div className={css['section-context']}>{children}</div>
</Collapsible>
</div>
);
};

View File

@@ -0,0 +1,21 @@
.full-input :global {
.editor-kit-toolbar-v2-wrapper {
padding: 0 2px;
button {
margin: 0 2px;
}
}
.editor-kit-container {
font-size: 12px;
}
}
.full-input {
min-height: 120px;
border: 1px solid var(--coz-stroke-plus);
}
.modal-full-input {
min-height: 570px;
}

View File

@@ -0,0 +1,153 @@
/*
* 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 { useState, useEffect, useRef, Suspense } from 'react';
import { nanoid } from 'nanoid';
import cls from 'classnames';
import { connect, mapProps } from '@formily/react';
import type { Editor } from '@coze-common/md-editor-adapter';
import {
delta2md,
md2html,
LazyEditorFullInputInner,
ToolbarItemEnum,
} from '@coze-common/md-editor-adapter';
import { Modal } from '@coze-arch/coze-design';
import css from './full-input.module.less';
export interface InnerFullInputProps {
value?: string;
disabled?: boolean;
/** 是否可以展开,默认 true */
expand?: boolean;
className?: string;
onChange: (v?: string) => void;
onExpand?: () => void;
}
export type FullInputProps = InnerFullInputProps & {
modalTitle?: string;
};
const InnerFullInputAdapter: React.FC<FullInputProps> = ({
className,
disabled,
expand = true,
value,
onChange,
...props
}) => {
const editorRef = useRef<Editor | null>(null);
const businessKeyRef = useRef(nanoid());
const innerValueRef = useRef<string | undefined>();
const handleChange = (v: string) => {
if (!editorRef.current) {
return;
}
/**
* deltas => md
*/
const content = editorRef.current.getContent();
const { markdown } = delta2md(content.deltas[0], content.deltas);
/**
* change 可能来自用户输入或者初始化,做一下 diff 来保证性能
*/
if (markdown !== innerValueRef.current) {
innerValueRef.current = markdown;
onChange(markdown);
}
};
useEffect(() => {
if (value !== innerValueRef.current) {
innerValueRef.current = value || '';
/**
* md => html
*/
editorRef.current?.setHTML(md2html(value || ''));
}
}, [value]);
return (
<Suspense fallback={null}>
<LazyEditorFullInputInner
field="full-input"
className={cls(css['full-input'], className)}
businessKey={businessKeyRef.current}
noToolbar={disabled}
noExpand={!expand}
getEditor={editor => {
editorRef.current = editor;
}}
disabled={disabled}
onChange={handleChange}
registerToolItem={items =>
items
.filter(i => (i as any)?.type !== ToolbarItemEnum.Image)
.map(i => {
const item = i as any;
if (item?.type && item.extraPropsToBuiltinComp) {
item.extraPropsToBuiltinComp = {
...item.extraPropsToBuiltinComp,
size: 'extra-small',
};
}
return item;
})
}
{...props}
/>
</Suspense>
);
};
const FullInputAdapter: React.FC<FullInputProps> = ({
expand,
modalTitle,
...props
}) => {
const [modalVisible, setModalVisible] = useState(false);
return (
<>
<Modal
visible={modalVisible}
centered
title={modalTitle}
onCancel={() => setModalVisible(false)}
>
<InnerFullInputAdapter
expand={false}
className={css['modal-full-input']}
{...props}
/>
</Modal>
<InnerFullInputAdapter
expand={expand}
onExpand={() => setModalVisible(true)}
{...props}
/>
</>
);
};
export const FullInput = connect(
FullInputAdapter,
mapProps({ validateStatus: true }),
);

View 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.
*/
export { FullInput } from './full-input';

View File

@@ -0,0 +1,28 @@
/*
* 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.
*/
// components
export { Input } from './input';
export { FileUpload } from './file-upload';
export { Switch } from './switch';
export { InputInteger, InputNumber } from './input-number';
export { VoiceSelect } from './voice-select';
export { TextArea } from './text-area';
export { FullInput } from './full-input';
// decorators
export { FormItem } from './form-item';
export { FormSection } from './form-section';
export { InputTime } from './input-time';

View File

@@ -0,0 +1,26 @@
.buttons {
display: flex;
flex-direction: column;
width: 24px;
}
.button {
font-size: 12px;
color: rgba(var(--coze-fg-3), var(--coze-fg-3-alpha));
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
&:hover {
background-color: rgba(var(--coze-bg-5), var(--coze-bg-5-alpha));
}
&.up {
border-top-left-radius: var(--coze-5);
border-top-right-radius: var(--coze-5);
}
&.down {
border-bottom-left-radius: var(--coze-5);
border-bottom-right-radius: var(--coze-5);
}
}

View File

@@ -0,0 +1,148 @@
/*
* 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 { useRef, useMemo, useEffect } from 'react';
import cls from 'classnames';
import BigNumber, { type BigNumber as IBigNumber } from 'bignumber.js';
import {
IconCozArrowDown,
IconCozArrowUp,
} from '@coze-arch/coze-design/icons';
import { Input, type InputProps } from '@coze-arch/coze-design';
import css from './base-input-number-v2.module.less';
export interface InputNumberV2Props {
value?: string;
style?: React.CSSProperties;
placeholder?: string;
validateStatus?: InputProps['validateStatus'];
disabled?: boolean;
'data-testid'?: string;
onChange?: (v?: string) => void;
onBlur?: () => void;
onFocus?: () => void;
/** 整型 */
int?: boolean;
}
/** 是否是合法的数字字符串 */
function isValidNumber(str: string) {
try {
const value = new BigNumber(str);
return !value.isNaN();
} catch {
return false;
}
}
function normalizeNumber(str?: string) {
if (!str || !isValidNumber(str)) {
return;
}
return new BigNumber(str);
}
export const InputNumberV2Adapter: React.FC<InputNumberV2Props> = ({
int,
onChange,
onBlur,
...props
}) => {
const isShowButtons = useMemo(() => !props.disabled, [props.disabled]);
const verifiedRef = useRef<undefined | IBigNumber>(
normalizeNumber(props.value),
);
const fixed = (num: IBigNumber, innerInt?: boolean) =>
innerInt ? num.toFixed(0, BigNumber.ROUND_DOWN) : num.toFixed();
const handleBlur = () => {
if (props.value === '' || props.value === undefined) {
/** 失焦时若值为空,则同时清空验证值 */
verifiedRef.current = undefined;
if (props.value === '') {
// 如果是空字符串需要主动转换为 undefined
onChange?.(undefined);
}
} else {
/** 失焦时若值不为空,则需要验证值的合法性 */
/**
* 1. 若值本身合法,则对值做格式化
* 2. 若值不合法,则采纳最近一次的合法值
* 3. 若都没有,则返回 undefined
*/
let next: undefined | string;
const nextBig = normalizeNumber(props.value) || verifiedRef.current;
if (nextBig) {
next = fixed(nextBig, int);
}
if (next !== props.value) {
onChange?.(next);
}
}
onBlur?.();
};
const handlePlus = () => {
let next = '1';
if (verifiedRef.current) {
const nextNum = verifiedRef.current.plus('1');
next = fixed(nextNum, int);
}
onChange?.(next);
};
const handleMinus = () => {
let next = '0';
if (verifiedRef.current) {
const nextNum = verifiedRef.current.minus('1');
next = fixed(nextNum, int);
}
onChange?.(next);
};
/** 当值发生变化,需要把值同步到合法数字 */
useEffect(() => {
if (props.value === '' || props.value === undefined) {
verifiedRef.current = undefined;
}
const next = normalizeNumber(props.value);
if (next) {
verifiedRef.current = normalizeNumber(props.value);
}
}, [props.value]);
return (
<Input
onChange={onChange}
onBlur={handleBlur}
suffix={
<div className={css.buttons}>
<div className={cls(css.button, css.up)} onClick={handlePlus}>
<IconCozArrowUp />
</div>
<div className={cls(css.button, css.down)} onClick={handleMinus}>
<IconCozArrowDown />
</div>
</div>
}
hideSuffix={!isShowButtons}
{...props}
/>
);
};

View File

@@ -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 { useCallback } from 'react';
import { CozInputNumber, type InputNumberProps } from '@coze-arch/coze-design';
export type BaseInputNumberAdapterProps = {
value?: number | string;
onChange?: (v?: number | string) => void;
} & Pick<InputNumberProps, 'precision'>;
export const BaseInputNumberAdapter: React.FC<BaseInputNumberAdapterProps> = ({
onChange,
...props
}) => {
const handleChange = useCallback(
(v: number | string) => {
onChange?.(v === '' ? undefined : v);
},
[onChange],
);
return (
<CozInputNumber
onChange={handleChange}
{...props}
size="small"
style={{ width: '100%' }}
/>
);
};

View File

@@ -0,0 +1,18 @@
/*
* 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 { InputInteger } from './input-integer';
export { InputNumber } from './input-number';

View File

@@ -0,0 +1,30 @@
/*
* 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 React from 'react';
import { connect } from '@formily/react';
import {
BaseInputNumberAdapter,
type BaseInputNumberAdapterProps,
} from './base-input-number';
const InputIntegerAdapter: React.FC<BaseInputNumberAdapterProps> = props => (
<BaseInputNumberAdapter {...props} precision={0.1} />
);
export const InputInteger = connect(InputIntegerAdapter);

View File

@@ -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 { connect } from '@formily/react';
import { BaseInputNumberAdapter } from './base-input-number';
export const InputNumber = connect(BaseInputNumberAdapter);

View 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.
*/
export { InputTime, type InputTimeProps } from './time';

View File

@@ -0,0 +1,6 @@
.input-time {
width: 100%;
:global .semi-select {
width: 100%;
}
}

View File

@@ -0,0 +1,50 @@
/*
* 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 React from 'react';
import cls from 'classnames';
import { DatePicker } from '@coze-arch/coze-design';
import css from './time.module.less';
export interface InputTimeProps {
className?: string;
value?: string;
onChange?: (v?: string) => void;
}
export const InputTime: React.FC<InputTimeProps> = ({
className,
value,
onChange,
...props
}) => (
<DatePicker
className={cls(css['input-time'], className)}
type="dateTime"
size="small"
showClear={false}
showSuffix={false}
value={value}
onChange={(_date, dateString) => {
if (typeof dateString === 'string' || dateString === undefined) {
onChange?.(dateString);
}
}}
{...props}
/>
);

View 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.
*/
export { Input } from './input';

View File

@@ -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 { connect, mapProps } from '@formily/react';
import { Input as InputCore } from '@coze-arch/coze-design';
const InputAdapter = props => <InputCore size="small" {...props} />;
export const Input = connect(InputAdapter, mapProps({ validateStatus: true }));

View 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.
*/
export { Switch } from './switch';

View File

@@ -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 React from 'react';
import { connect } from '@formily/react';
import { Switch as CozSwitch } from '@coze-arch/coze-design';
export interface SwitchProps {
value?: boolean;
onChange?: (v: boolean) => void;
}
const SwitchAdapter: React.FC<SwitchProps> = ({ value, ...props }) => (
<CozSwitch checked={value} {...props} size="small" />
);
export const Switch = connect(SwitchAdapter);

View 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.
*/
export { TextArea } from './text-area';

View File

@@ -0,0 +1,6 @@
.text-area-small {
textarea {
font-size: 12px;
line-height: 20px;
}
}

View File

@@ -0,0 +1,47 @@
/*
* 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 cls from 'classnames';
import { connect, mapProps } from '@formily/react';
import { TextArea as TextAreaCore } from '@coze-arch/coze-design';
import css from './text-area.module.less';
export interface TextAreaProps {
size?: string;
className?: string;
}
const TextAreaAdapter: React.FC<TextAreaProps> = ({
size,
className,
...props
}) => (
<TextAreaCore
className={cls(
{
[css['text-area-small']]: size === 'small',
},
className,
)}
{...props}
/>
);
export const TextArea = connect(
TextAreaAdapter,
mapProps({ validateStatus: true }),
);

View File

@@ -0,0 +1,25 @@
/*
* 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 { connect, mapProps } from '@formily/react';
import { VoiceSelect as VoiceSelectBase } from '@coze-workflow/components';
const VoiceSelectAdapter = props => <VoiceSelectBase {...props} />;
export const VoiceSelect = connect(
VoiceSelectAdapter,
mapProps({ validateStatus: true }),
);