mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
Merge pull request #7814 from QKflame/feat-complete-i18n-example-code
完善国际化调试代码
This commit is contained in:
commit
c2e9063bcc
@ -9,9 +9,9 @@ import LayoutList from './layout/index';
|
||||
import themeConfig from 'amis-theme-editor-helper/lib/systemTheme/cxd';
|
||||
|
||||
// 测试组织属性配置面板的国际化,可以放开如下注释
|
||||
// import '../renderer/InputTextI18n';
|
||||
// import '../renderer/TextareaI18n';
|
||||
// import '../utils/overwriteSchemaTpl';
|
||||
// import './renderer/InputTextI18n';
|
||||
// import './renderer/TextareaI18n';
|
||||
// import './utils/overwriteSchemaTpl';
|
||||
// const i18nEnabled = true;
|
||||
const i18nEnabled = false;
|
||||
setThemeConfig(themeConfig);
|
||||
|
167
packages/amis-editor/examples/renderer/InputTextI18n.tsx
Normal file
167
packages/amis-editor/examples/renderer/InputTextI18n.tsx
Normal file
@ -0,0 +1,167 @@
|
||||
/**
|
||||
* @file client/renderer/InputTextI18n.tsx
|
||||
* @description 支持国际化的 input-text 组件
|
||||
*/
|
||||
|
||||
import {
|
||||
FormControlProps,
|
||||
FormItem,
|
||||
makeTranslator,
|
||||
autobind
|
||||
} from '../../../amis-core/src/index';
|
||||
import React from 'react';
|
||||
import {Icon, InputBox} from '../../../amis-ui/src/index';
|
||||
import {InputBoxProps} from '../../../amis-ui/src/components/InputBox';
|
||||
import cx from 'classnames';
|
||||
import {getEnv} from 'mobx-state-tree';
|
||||
import {pick} from 'lodash';
|
||||
|
||||
/** 语料 key 正则表达式 */
|
||||
export const corpusKeyReg =
|
||||
/^i18n:[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}$/;
|
||||
|
||||
interface InputTextI18nProps extends InputBoxProps {
|
||||
classPrefix: string;
|
||||
i18nEnabled?: boolean;
|
||||
disabled?: boolean;
|
||||
locale?: string;
|
||||
maxLength?: number;
|
||||
minLength?: number;
|
||||
translate?: (value: any) => any;
|
||||
onI18nChange?: (value: string) => void;
|
||||
}
|
||||
|
||||
export class InputTextI18n extends React.Component<InputTextI18nProps> {
|
||||
constructor(props: InputTextI18nProps) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
let {
|
||||
value,
|
||||
classPrefix,
|
||||
i18nEnabled,
|
||||
className,
|
||||
disabled,
|
||||
translate = makeTranslator(this.props.locale),
|
||||
placeholder,
|
||||
onI18nChange,
|
||||
...rest
|
||||
} = this.props;
|
||||
|
||||
const restProps = rest
|
||||
? pick(rest, [
|
||||
'onBlur',
|
||||
'placeholder',
|
||||
'disabled',
|
||||
'readOnly',
|
||||
'onClear',
|
||||
'hasError',
|
||||
'prefix',
|
||||
'children',
|
||||
'borderMode'
|
||||
])
|
||||
: {};
|
||||
|
||||
const isMatch = corpusKeyReg.test(value!);
|
||||
const _value = i18nEnabled ? translate(value) : value;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx(className, `${classPrefix}InputI18n-container`, {
|
||||
[`${classPrefix}InputI18n-multi-container`]: i18nEnabled
|
||||
})}
|
||||
>
|
||||
<div className={cx(`${classPrefix}InputI18n-inner-container`)}>
|
||||
<InputBox
|
||||
{...restProps}
|
||||
value={_value}
|
||||
clearable={false}
|
||||
onChange={this.onInputChange}
|
||||
placeholder={placeholder}
|
||||
disabled={disabled}
|
||||
></InputBox>
|
||||
{i18nEnabled && !disabled ? (
|
||||
<div
|
||||
className={cx(`${classPrefix}InputI18n-addon-container`, {
|
||||
[`${classPrefix}InputI18n-addon-active`]: isMatch
|
||||
})}
|
||||
onClick={this.onClickI18nBtn}
|
||||
>
|
||||
<Icon
|
||||
icon="corpus-i18n"
|
||||
className="icon cursor-pointer CorpusI18n-input-icon"
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{isMatch && i18nEnabled ? (
|
||||
<div
|
||||
className={cx(`${classPrefix}InputI18n-overlay`)}
|
||||
onClick={this.onClickI18nBtn}
|
||||
></div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@autobind
|
||||
onClickI18nBtn() {
|
||||
const {value} = this.props;
|
||||
if (corpusKeyReg.test(value!)) {
|
||||
this.props?.onChange?.('');
|
||||
this.props.onI18nChange?.('');
|
||||
return;
|
||||
}
|
||||
let _uuid = 'i18n:1189fb5d-ac5b-4558-b363-068ce5decc99';
|
||||
this.props?.onChange?.(_uuid);
|
||||
this.props.onI18nChange?.(_uuid);
|
||||
}
|
||||
|
||||
@autobind
|
||||
onInputChange(value: string) {
|
||||
this.props.onChange?.(value);
|
||||
}
|
||||
}
|
||||
|
||||
interface InputTextI18nControlProps extends FormControlProps {}
|
||||
|
||||
class InputTextI18nControl extends React.Component<InputTextI18nControlProps> {
|
||||
constructor(props: InputTextI18nControlProps) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
onChange,
|
||||
value,
|
||||
classPrefix,
|
||||
className,
|
||||
classnames,
|
||||
placeholder,
|
||||
disabled,
|
||||
...rest
|
||||
} = this.props;
|
||||
const {i18nEnabled} = getEnv((window as any).editorStore);
|
||||
|
||||
return (
|
||||
<InputTextI18n
|
||||
{...rest}
|
||||
i18nEnabled={i18nEnabled}
|
||||
onChange={onChange}
|
||||
classPrefix={classPrefix}
|
||||
classnames={classnames}
|
||||
value={value}
|
||||
placeholder={placeholder}
|
||||
className={className}
|
||||
disabled={disabled}
|
||||
></InputTextI18n>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@FormItem({
|
||||
type: 'input-text-i18n'
|
||||
})
|
||||
export class InputTextI18nRenderer extends InputTextI18nControl {}
|
83
packages/amis-editor/examples/renderer/TextareaI18n.tsx
Normal file
83
packages/amis-editor/examples/renderer/TextareaI18n.tsx
Normal file
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* @file client/renderer/TextAreaI18n.tsx
|
||||
* @description 支持国际化的 textarea 组件
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
autobind,
|
||||
FormControlProps,
|
||||
FormItem
|
||||
} from '../../../amis-core/src/index';
|
||||
import {Icon, Textarea} from '../../../amis-ui/src/index';
|
||||
import cx from 'classnames';
|
||||
|
||||
/** 语料 key 正则表达式 */
|
||||
export const corpusKeyReg =
|
||||
/^i18n:[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}$/;
|
||||
|
||||
export interface TextareaI18nProps extends FormControlProps {}
|
||||
|
||||
class TextareaI18n extends React.Component<TextareaI18nProps> {
|
||||
@autobind
|
||||
onClickI18nBtn() {
|
||||
const {value} = this.props;
|
||||
if (corpusKeyReg.test(value!)) {
|
||||
this.props?.onChange?.('');
|
||||
return;
|
||||
}
|
||||
let _uuid = 'i18n:1189fb5d-ac5b-4558-b363-068ce5decc99';
|
||||
this.props?.onChange?.(_uuid);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {value, onChange, className} = this.props;
|
||||
|
||||
const isMatch = corpusKeyReg.test(value!);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={cx(
|
||||
'TextareaI18n',
|
||||
className,
|
||||
'TextareaI18n-multi-container'
|
||||
)}
|
||||
>
|
||||
<Textarea
|
||||
value={value}
|
||||
clearable={false}
|
||||
onChange={onChange}
|
||||
></Textarea>
|
||||
|
||||
{
|
||||
<ul className={cx('TextareaI18n-footer')}>
|
||||
<li
|
||||
className={cx('TextareaI18n-footer-corpusIcon', {
|
||||
'TextareaI18n-footer-highlight-corpusIcon': isMatch
|
||||
})}
|
||||
onClick={this.onClickI18nBtn}
|
||||
>
|
||||
<a data-tooltip="多语言" data-position="top">
|
||||
<Icon icon="corpus-i18n" className="icon" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
}
|
||||
|
||||
{isMatch ? (
|
||||
<div
|
||||
className={cx('TextareaI18n-overlay')}
|
||||
onClick={this.onClickI18nBtn}
|
||||
></div>
|
||||
) : null}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@FormItem({
|
||||
type: 'textarea-i18n'
|
||||
})
|
||||
export class TextAreaI18nRenderer extends TextareaI18n {}
|
142
packages/amis-editor/examples/utils/overwriteSchemaTpl.tsx
Normal file
142
packages/amis-editor/examples/utils/overwriteSchemaTpl.tsx
Normal file
@ -0,0 +1,142 @@
|
||||
import {remarkTpl} from '../../src/index';
|
||||
import {getSchemaTpl, setSchemaTpl} from '../../../amis-editor-core/src/index';
|
||||
|
||||
/** 国际化组件类型 */
|
||||
enum I18nComptType {
|
||||
InputText = 'input-text',
|
||||
Textarea = 'textarea',
|
||||
TextareaFormula = 'textarea-formula',
|
||||
RichText = 'rich-text',
|
||||
ButtonLabel = 'button-label'
|
||||
}
|
||||
|
||||
/** 缓存已经重写过的 tpl 名称 */
|
||||
const overwriteNames: {[propName: string]: boolean} = {};
|
||||
|
||||
/** 重写 schema tpl */
|
||||
const overwriteSchemaTpl = (
|
||||
name: string,
|
||||
i18nType = I18nComptType.InputText,
|
||||
options?: {[key: string]: any}
|
||||
) => {
|
||||
if (overwriteNames[name]) {
|
||||
throw new Error(name + 'has been rewritten');
|
||||
}
|
||||
overwriteNames[name] = true;
|
||||
|
||||
const getType = () => {
|
||||
if (i18nType === I18nComptType.InputText) {
|
||||
return 'input-text-i18n';
|
||||
}
|
||||
if (i18nType === I18nComptType.Textarea) {
|
||||
return 'textarea-i18n';
|
||||
}
|
||||
return 'input-text-i18n';
|
||||
};
|
||||
|
||||
setSchemaTpl(
|
||||
name,
|
||||
getSchemaTpl(
|
||||
name,
|
||||
options
|
||||
? options
|
||||
: {
|
||||
type: getType()
|
||||
}
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
overwriteSchemaTpl('label');
|
||||
overwriteSchemaTpl('btnLabel');
|
||||
overwriteSchemaTpl('placeholder');
|
||||
overwriteSchemaTpl('startPlaceholder');
|
||||
overwriteSchemaTpl('endPlaceholder');
|
||||
overwriteSchemaTpl('option');
|
||||
overwriteSchemaTpl('description', I18nComptType.Textarea);
|
||||
overwriteSchemaTpl('pageTitle');
|
||||
overwriteSchemaTpl('pageSubTitle', I18nComptType.Textarea);
|
||||
overwriteSchemaTpl('tpl:rich-text', I18nComptType.RichText);
|
||||
overwriteSchemaTpl('prefix');
|
||||
overwriteSchemaTpl('suffix');
|
||||
overwriteSchemaTpl('unit');
|
||||
overwriteSchemaTpl('optionsTip');
|
||||
overwriteSchemaTpl('tableCellRemark');
|
||||
overwriteSchemaTpl('title');
|
||||
overwriteSchemaTpl('caption');
|
||||
overwriteSchemaTpl('imageCaption');
|
||||
overwriteSchemaTpl('inputBody');
|
||||
overwriteSchemaTpl('stepSubTitle');
|
||||
overwriteSchemaTpl('stepDescription');
|
||||
overwriteSchemaTpl('taskNameLabel');
|
||||
overwriteSchemaTpl('operationLabel');
|
||||
overwriteSchemaTpl('statusLabel');
|
||||
overwriteSchemaTpl('remarkLabel');
|
||||
overwriteSchemaTpl('inputArrayItem');
|
||||
overwriteSchemaTpl('actionPrevLabel');
|
||||
overwriteSchemaTpl('actionNextLabel');
|
||||
overwriteSchemaTpl('actionNextSaveLabel');
|
||||
overwriteSchemaTpl('actionFinishLabel');
|
||||
overwriteSchemaTpl('imgCaption', I18nComptType.Textarea);
|
||||
overwriteSchemaTpl('taskRemark', I18nComptType.Textarea);
|
||||
overwriteSchemaTpl('tooltip', I18nComptType.Textarea);
|
||||
overwriteSchemaTpl('anchorTitle');
|
||||
overwriteSchemaTpl('avatarText');
|
||||
overwriteSchemaTpl('cardTitle');
|
||||
overwriteSchemaTpl('cardSubTitle');
|
||||
overwriteSchemaTpl('cardsPlaceholder');
|
||||
overwriteSchemaTpl('cardDesc', I18nComptType.Textarea);
|
||||
overwriteSchemaTpl('imageTitle');
|
||||
overwriteSchemaTpl('imageDesc', I18nComptType.Textarea);
|
||||
overwriteSchemaTpl('fetchSuccess');
|
||||
overwriteSchemaTpl('fetchFailed');
|
||||
overwriteSchemaTpl('saveOrderSuccess');
|
||||
overwriteSchemaTpl('saveOrderFailed');
|
||||
overwriteSchemaTpl('quickSaveSuccess');
|
||||
overwriteSchemaTpl('quickSaveFailed');
|
||||
overwriteSchemaTpl('saveSuccess');
|
||||
overwriteSchemaTpl('saveFailed');
|
||||
overwriteSchemaTpl('validateFailed');
|
||||
overwriteSchemaTpl('tablePlaceholder');
|
||||
overwriteSchemaTpl('collapseOpenHeader');
|
||||
overwriteSchemaTpl('matrixColumnLabel');
|
||||
overwriteSchemaTpl('matrixRowLabel');
|
||||
overwriteSchemaTpl('matrixRowTitle');
|
||||
overwriteSchemaTpl('submitText');
|
||||
overwriteSchemaTpl('tpl:btnLabel', I18nComptType.ButtonLabel);
|
||||
overwriteSchemaTpl('switchOption');
|
||||
overwriteSchemaTpl('createBtnLabel');
|
||||
overwriteSchemaTpl('tableCellPlaceholder');
|
||||
overwriteSchemaTpl('addOnLabel');
|
||||
overwriteSchemaTpl('onText');
|
||||
overwriteSchemaTpl('offText');
|
||||
overwriteSchemaTpl('propertyTitle');
|
||||
overwriteSchemaTpl('propertyLabel');
|
||||
overwriteSchemaTpl('propertyContent');
|
||||
overwriteSchemaTpl('draggableTip');
|
||||
overwriteSchemaTpl('deleteConfirmText');
|
||||
overwriteSchemaTpl('optionsLabel');
|
||||
overwriteSchemaTpl('checkAllLabel');
|
||||
overwriteSchemaTpl('name');
|
||||
overwriteSchemaTpl('anchorNavTitle');
|
||||
|
||||
setSchemaTpl(
|
||||
'remark',
|
||||
remarkTpl({
|
||||
name: 'remark',
|
||||
label: '控件提示',
|
||||
labelRemark:
|
||||
'在输入控件旁展示提示,注意控件宽度需设置,否则提示触发图标将自动换行',
|
||||
i18nEnabled: true
|
||||
})
|
||||
);
|
||||
|
||||
setSchemaTpl(
|
||||
'labelRemark',
|
||||
remarkTpl({
|
||||
name: 'labelRemark',
|
||||
label: '标题提示',
|
||||
labelRemark: '在标题旁展示提示',
|
||||
i18nEnabled: true
|
||||
})
|
||||
);
|
Loading…
Reference in New Issue
Block a user