Skip to content

Commit

Permalink
feat(FormRender): support readonly status
Browse files Browse the repository at this point in the history
  • Loading branch information
Barrior committed Jan 4, 2024
1 parent 189e682 commit 5ba6ab3
Show file tree
Hide file tree
Showing 17 changed files with 164 additions and 2 deletions.
7 changes: 7 additions & 0 deletions packages/form-render-react/src/components/Description.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { FC, ReactNode } from 'react'

const Description: FC<{ children: ReactNode }> = ({ children }) => {
return <>{children}</>
}

export default Description
6 changes: 6 additions & 0 deletions packages/form-render-react/src/constants/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,9 @@ export type IActionsLoading = typeof ACTIONS_DEFAULT_LOADING_STATE
* Actions 渲染器名称
*/
export const ACTIONS_RENDER_TYPE = '__FORM_RENDER_ACTIONS__'

/**
* 默认时间展示格式
*/
export const DEFAULT_DATE_FORMAT = 'YYYY-MM-DD'
export const DEFAULT_DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'
2 changes: 2 additions & 0 deletions packages/form-render-react/src/locale/en_US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ export default {
reset: 'Reset',
placeholderInput: 'Please enter ${title}',
placeholderSelect: 'Please select ${title}',
comma: ',',
displayDate: '${start} to ${end}',
},
}
2 changes: 2 additions & 0 deletions packages/form-render-react/src/locale/zh_CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ export default {
reset: '重置',
placeholderInput: '请输入${title}',
placeholderSelect: '请选择${title}',
comma: ',',
displayDate: '${start} 至 ${end}',
},
}
11 changes: 11 additions & 0 deletions packages/form-render-react/src/renderers/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,25 @@ import type { IOpenComponentParams } from '@schema-render/core-react'
import { Checkbox as AntCheckbox } from 'antd'
import React from 'react'

import Description from '../components/Description'
import { getOptionsLabels } from '../utils'

type IValue = Array<string | number | boolean>

const Checkbox: React.FC<IOpenComponentParams<IValue>> = ({
schema,
disabled,
readonly,
value,
onChange,
locale,
}) => {
// 只读态
if (readonly) {
const labels = getOptionsLabels(schema.renderOptions?.options, value)
return <Description>{labels.join(locale.FormRender.comma)}</Description>
}

return (
<AntCheckbox.Group
{...schema.renderOptions}
Expand Down
20 changes: 20 additions & 0 deletions packages/form-render-react/src/renderers/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import { DatePicker as AntDatePicker } from 'antd'
import dayjs from 'dayjs'
import React, { useMemo } from 'react'

import Description from '../components/Description'
import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT } from '../constants'

const DatePicker: React.FC<IOpenComponentParams<string>> = ({
schema,
value,
onChange,
disabled,
readonly,
locale,
validator,
}) => {
Expand All @@ -20,6 +24,22 @@ const DatePicker: React.FC<IOpenComponentParams<string>> = ({
[schema.title, locale.FormRender.placeholderSelect]
)

// 只读态
if (readonly) {
return (
<Description>
{value
? dayjs(value).format(
schema.renderOptions?.format ||
(schema.renderOptions?.showTime
? DEFAULT_DATE_TIME_FORMAT
: DEFAULT_DATE_FORMAT)
)
: ''}
</Description>
)
}

return (
<AntDatePicker
allowClear
Expand Down
24 changes: 24 additions & 0 deletions packages/form-render-react/src/renderers/DateRangePicker.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import type { IOpenComponentParams } from '@schema-render/core-react'
import { utils } from '@schema-render/core-react'
import { DatePicker } from 'antd'
import type { Dayjs } from 'dayjs'
import dayjs from 'dayjs'
import React from 'react'

import Description from '../components/Description'
import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT } from '../constants'

function toISOString(date: Dayjs | string | null) {
return dayjs(date).toISOString()
}
Expand All @@ -13,8 +17,28 @@ const DateRangePicker: React.FC<IOpenComponentParams<[string, string]>> = ({
value,
onChange,
disabled,
readonly,
validator,
locale,
}) => {
// 只读态
if (readonly) {
let displayText = ''

if (utils.isArray(value) && value[0] && value[1]) {
const defaultFormat = schema.renderOptions?.showTime
? DEFAULT_DATE_TIME_FORMAT
: DEFAULT_DATE_FORMAT
const format = schema.renderOptions?.format || defaultFormat
displayText = utils.templateCompiled(locale.FormRender.displayDate, {
start: dayjs(value?.[0]).format(format),
end: dayjs(value?.[1]).format(format),
})
}

return <Description>{displayText}</Description>
}

return (
<DatePicker.RangePicker
allowClear
Expand Down
8 changes: 8 additions & 0 deletions packages/form-render-react/src/renderers/InputNumber.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { utils } from '@schema-render/core-react'
import { InputNumber as AntInputNumber } from 'antd'
import React, { useMemo } from 'react'

import Description from '../components/Description'

const InputNumber: React.FC<IOpenComponentParams<number>> = ({
schema,
disabled,
readonly,
value,
onChange,
validator,
Expand All @@ -19,6 +22,11 @@ const InputNumber: React.FC<IOpenComponentParams<number>> = ({
[schema.title, locale.FormRender.placeholderInput]
)

// 只读态
if (readonly) {
return <Description>{value}</Description>
}

return (
<AntInputNumber
style={{ width: '100%' }}
Expand Down
8 changes: 8 additions & 0 deletions packages/form-render-react/src/renderers/InputText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { utils } from '@schema-render/core-react'
import { Input } from 'antd'
import React, { useMemo } from 'react'

import Description from '../components/Description'

const InputText: React.FC<IOpenComponentParams<string>> = ({
schema,
disabled,
readonly,
value,
onChange,
validator,
Expand All @@ -28,6 +31,11 @@ const InputText: React.FC<IOpenComponentParams<string>> = ({
}
}

// 只读态
if (readonly) {
return <Description>{value}</Description>
}

return (
<Input
placeholder={placeholder}
Expand Down
8 changes: 8 additions & 0 deletions packages/form-render-react/src/renderers/Password.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { utils } from '@schema-render/core-react'
import { Input } from 'antd'
import React, { useMemo } from 'react'

import Description from '../components/Description'

const Password: React.FC<IOpenComponentParams<string>> = ({
schema,
disabled,
readonly,
value,
onChange,
validator,
Expand All @@ -28,6 +31,11 @@ const Password: React.FC<IOpenComponentParams<string>> = ({
}
}

// 只读态
if (readonly) {
return <Description>{value}</Description>
}

return (
<Input.Password
placeholder={placeholder}
Expand Down
10 changes: 10 additions & 0 deletions packages/form-render-react/src/renderers/Radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import type { RadioChangeEvent } from 'antd'
import { Radio as AntRadio } from 'antd'
import React from 'react'

import Description from '../components/Description'
import { getOptionsLabels } from '../utils'

export interface IOptions {
value: string | number
label: string
Expand All @@ -12,6 +15,7 @@ export interface IOptions {
const Radio: React.FC<IOpenComponentParams<IOptions['value']>> = ({
schema,
disabled,
readonly,
value,
onChange,
}) => {
Expand All @@ -22,6 +26,12 @@ const Radio: React.FC<IOpenComponentParams<IOptions['value']>> = ({
onChange(e.target.value)
}

// 只读态
if (readonly) {
const labels = getOptionsLabels(options, [value])
return <Description>{labels[0]}</Description>
}

return (
<AntRadio.Group value={value} onChange={onRadioChange} disabled={disabled}>
{options.map((item) => {
Expand Down
3 changes: 2 additions & 1 deletion packages/form-render-react/src/renderers/Rate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Rate as AntRate } from 'antd'
const Rate: React.FC<IOpenComponentParams<number>> = ({
schema,
disabled,
readonly,
value,
onChange,
}) => {
Expand All @@ -12,7 +13,7 @@ const Rate: React.FC<IOpenComponentParams<number>> = ({
{...schema.renderOptions}
value={value ?? 0}
onChange={(val) => onChange(val)}
disabled={disabled}
disabled={disabled || readonly}
/>
)
}
Expand Down
10 changes: 10 additions & 0 deletions packages/form-render-react/src/renderers/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ import { utils } from '@schema-render/core-react'
import { Select as AntSelect } from 'antd'
import React, { useMemo } from 'react'

import Description from '../components/Description'
import { getOptionsLabels } from '../utils'

const Select: React.FC<IOpenComponentParams<string>> = ({
schema,
disabled,
readonly,
value,
onChange,
locale,
Expand All @@ -19,6 +23,12 @@ const Select: React.FC<IOpenComponentParams<string>> = ({
[schema.title, locale.FormRender.placeholderSelect]
)

// 只读态
if (readonly) {
const labels = getOptionsLabels(schema.renderOptions?.options, [value])
return <Description>{labels.join(locale.FormRender?.comma)}</Description>
}

return (
<AntSelect
allowClear
Expand Down
10 changes: 10 additions & 0 deletions packages/form-render-react/src/renderers/SelectMultiple.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ import { utils } from '@schema-render/core-react'
import { Select as AntSelect } from 'antd'
import React, { useMemo } from 'react'

import Description from '../components/Description'
import { getOptionsLabels } from '../utils'

const SelectMultiple: React.FC<IOpenComponentParams<string[]>> = ({
schema,
disabled,
readonly,
value,
onChange,
validator,
Expand All @@ -19,6 +23,12 @@ const SelectMultiple: React.FC<IOpenComponentParams<string[]>> = ({
[schema.title, locale.FormRender.placeholderSelect]
)

// 只读态
if (readonly) {
const labels = getOptionsLabels(schema.renderOptions?.options, value)
return <Description>{labels.join(locale.FormRender?.comma)}</Description>
}

return (
<AntSelect
allowClear
Expand Down
3 changes: 2 additions & 1 deletion packages/form-render-react/src/renderers/Switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React from 'react'
const Switch: React.FC<IOpenComponentParams<boolean>> = ({
schema,
disabled,
readonly,
value,
onChange,
}) => {
Expand All @@ -13,7 +14,7 @@ const Switch: React.FC<IOpenComponentParams<boolean>> = ({
{...schema.renderOptions}
checked={value}
onChange={(val) => onChange(val)}
disabled={disabled}
disabled={disabled || readonly}
/>
)
}
Expand Down
8 changes: 8 additions & 0 deletions packages/form-render-react/src/renderers/TextArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { utils } from '@schema-render/core-react'
import { Input } from 'antd'
import React, { useMemo } from 'react'

import Description from '../components/Description'

const TextArea: React.FC<IOpenComponentParams<string>> = ({
schema,
disabled,
readonly,
value,
onChange,
validator,
Expand All @@ -28,6 +31,11 @@ const TextArea: React.FC<IOpenComponentParams<string>> = ({
}
}

// 只读态
if (readonly) {
return <Description>{value}</Description>
}

return (
<Input.TextArea
rows={3}
Expand Down
26 changes: 26 additions & 0 deletions packages/form-render-react/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { IBaseSchema, IRootSchema } from '@schema-render/core-react'
import { utils } from '@schema-render/core-react'
import type { CheckboxOptionType } from 'antd'

import { ACTIONS_RENDER_TYPE } from '../constants'
import type { IInnerFormRenderProps } from '../typings'
Expand Down Expand Up @@ -37,3 +38,28 @@ export function calcActionsMarginLeft({
}
return 0
}

/**
* 获取 Antd options 选项 label 数据
* @param options Antd options
* @param values label 对应的 value 值,可以多个
*/
export function getOptionsLabels(
options?: CheckboxOptionType[],
values?: (CheckboxOptionType['value'] | undefined)[]
) {
const labels: string[] = []

if (utils.isArray(values) && utils.isArray(options)) {
values.forEach((value) => {
if (!utils.isNil(value)) {
const result = utils.find<CheckboxOptionType>(options, { value })
if (result) {
labels.push(result.label as string)
}
}
})
}

return labels
}

0 comments on commit 5ba6ab3

Please sign in to comment.