From 637b3165cadb1f904e78e277699f0c3f11f3f7a4 Mon Sep 17 00:00:00 2001 From: SemmyWong <67748948+semmywong@users.noreply.github.com> Date: Tue, 18 Jan 2022 09:21:55 +0800 Subject: [PATCH] feat: add DatePicker into schema components (#161) * feat: add DatePicker into schema components * improve code Co-authored-by: chenos --- .../antd/date-picker/DatePicker.tsx | 27 ++++++++++ .../antd/date-picker/ReadPretty.tsx | 43 ++++++++++++++++ .../antd/date-picker/demos/demo1.tsx | 49 +++++++++++++++++++ .../antd/date-picker/demos/demo2.tsx | 41 ++++++++++++++++ .../antd/date-picker/index.md | 17 +++++++ .../antd/date-picker/index.ts | 1 + .../schema-component/antd/date-picker/util.ts | 42 ++++++++++++++++ .../client/src/schema-component/antd/index.ts | 1 + 8 files changed, 221 insertions(+) create mode 100644 packages/client/src/schema-component/antd/date-picker/DatePicker.tsx create mode 100644 packages/client/src/schema-component/antd/date-picker/ReadPretty.tsx create mode 100644 packages/client/src/schema-component/antd/date-picker/demos/demo1.tsx create mode 100644 packages/client/src/schema-component/antd/date-picker/demos/demo2.tsx create mode 100644 packages/client/src/schema-component/antd/date-picker/index.ts create mode 100644 packages/client/src/schema-component/antd/date-picker/util.ts diff --git a/packages/client/src/schema-component/antd/date-picker/DatePicker.tsx b/packages/client/src/schema-component/antd/date-picker/DatePicker.tsx new file mode 100644 index 000000000..7085e6353 --- /dev/null +++ b/packages/client/src/schema-component/antd/date-picker/DatePicker.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { DatePicker as AntdDatePicker } from 'antd'; +import type { + DatePickerProps as AntdDatePickerProps, + RangePickerProps as AntdRangePickerProps, +} from 'antd/lib/date-picker'; +import { connect, mapProps, mapReadPretty } from '@formily/react'; +import { ReadPretty } from './ReadPretty'; +import { mapDateFormat } from './util'; + +type ComposedDatePicker = React.FC & { + RangePicker?: React.FC; +}; + +export const DatePicker: ComposedDatePicker = connect( + AntdDatePicker, + mapProps(mapDateFormat()), + mapReadPretty(ReadPretty.DatePicker), +); + +DatePicker.RangePicker = connect( + AntdDatePicker.RangePicker, + mapProps(mapDateFormat()), + mapReadPretty(ReadPretty.DateRangePicker), +); + +export default DatePicker; diff --git a/packages/client/src/schema-component/antd/date-picker/ReadPretty.tsx b/packages/client/src/schema-component/antd/date-picker/ReadPretty.tsx new file mode 100644 index 000000000..5692870f5 --- /dev/null +++ b/packages/client/src/schema-component/antd/date-picker/ReadPretty.tsx @@ -0,0 +1,43 @@ +import { formatMomentValue, usePrefixCls } from '@formily/antd/esm/__builtins__'; +import { isArr } from '@formily/shared'; +import type { + DatePickerProps as AntdDatePickerProps, + RangePickerProps as AntdRangePickerProps, +} from 'antd/lib/date-picker'; +import cls from 'classnames'; +import moment from 'moment'; +import React from 'react'; +import { getDefaultFormat } from './util'; + +type Composed = { + DatePicker: React.FC; + DateRangePicker: React.FC; +}; + +export const ReadPretty: Composed = () => null; + +ReadPretty.DatePicker = (props: any) => { + if (!props.value) { + return
; + } + const prefixCls = usePrefixCls('description-date-picker', props); + const getLabels = () => { + const d = moment(props.value); + const labels = formatMomentValue(d.isValid() ? d : null, getDefaultFormat(props), props.placeholder); + return isArr(labels) ? labels.join('~') : labels; + }; + return
{getLabels()}
; +}; + +ReadPretty.DateRangePicker = (props: any) => { + const prefixCls = usePrefixCls('description-text', props); + const getLabels = () => { + const labels = formatMomentValue(props.value, props.format, props.placeholder); + return isArr(labels) ? labels.join('~') : labels; + }; + return ( +
+ {getLabels()} +
+ ); +}; diff --git a/packages/client/src/schema-component/antd/date-picker/demos/demo1.tsx b/packages/client/src/schema-component/antd/date-picker/demos/demo1.tsx new file mode 100644 index 000000000..7bc5049e9 --- /dev/null +++ b/packages/client/src/schema-component/antd/date-picker/demos/demo1.tsx @@ -0,0 +1,49 @@ +/** + * title: DatePicker + */ +import { FormItem } from '@formily/antd'; +import { DatePicker, SchemaComponent, SchemaComponentProvider } from '@nocobase/client'; +import React from 'react'; + +const schema = { + type: 'object', + properties: { + input: { + type: 'boolean', + title: `Editable`, + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + 'x-component-props': { + dateFormat: 'YYYY/MM/DD', + // showTime: true, + }, + 'x-reactions': { + target: 'read', + fulfill: { + state: { + value: '{{$self.value}}', + }, + }, + }, + }, + read: { + type: 'boolean', + title: `Read pretty`, + 'x-read-pretty': true, + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + 'x-component-props': { + dateFormat: 'YYYY/MM/DD', + // showTime: true, + }, + }, + }, +}; + +export default () => { + return ( + + + + ); +}; diff --git a/packages/client/src/schema-component/antd/date-picker/demos/demo2.tsx b/packages/client/src/schema-component/antd/date-picker/demos/demo2.tsx new file mode 100644 index 000000000..0c4944db2 --- /dev/null +++ b/packages/client/src/schema-component/antd/date-picker/demos/demo2.tsx @@ -0,0 +1,41 @@ +/** + * title: DatePicker.RangePicker + */ +import { FormItem } from '@formily/antd'; +import { DatePicker, SchemaComponent, SchemaComponentProvider } from '@nocobase/client'; +import React from 'react'; + +const schema = { + type: 'object', + properties: { + input: { + type: 'boolean', + title: `Editable`, + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker.RangePicker', + 'x-reactions': { + target: 'read', + fulfill: { + state: { + value: '{{$self.value}}', + }, + }, + }, + }, + read: { + type: 'boolean', + title: `Read pretty`, + 'x-read-pretty': true, + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker.RangePicker', + }, + }, +}; + +export default () => { + return ( + + + + ); +}; diff --git a/packages/client/src/schema-component/antd/date-picker/index.md b/packages/client/src/schema-component/antd/date-picker/index.md index 79d312068..9b55b9249 100644 --- a/packages/client/src/schema-component/antd/date-picker/index.md +++ b/packages/client/src/schema-component/antd/date-picker/index.md @@ -6,3 +6,20 @@ group: --- # DatePicker + +## Examples + +### DatePicker + + + +### RangePicker + + + +## API + +基于 antd 的 [DatePicker](https://ant.design/components/date-picker/#API),新增了以下扩展属性,用于支持 NocoBase 的日期字段设置。 + +- `dateFormat` 设置日期格式 +- `timeFormat` 设置时间格式 diff --git a/packages/client/src/schema-component/antd/date-picker/index.ts b/packages/client/src/schema-component/antd/date-picker/index.ts new file mode 100644 index 000000000..a48b62e4d --- /dev/null +++ b/packages/client/src/schema-component/antd/date-picker/index.ts @@ -0,0 +1 @@ +export * from './DatePicker'; diff --git a/packages/client/src/schema-component/antd/date-picker/util.ts b/packages/client/src/schema-component/antd/date-picker/util.ts new file mode 100644 index 000000000..d6c88f8ed --- /dev/null +++ b/packages/client/src/schema-component/antd/date-picker/util.ts @@ -0,0 +1,42 @@ +import type { DatePickerProps } from 'antd/lib/date-picker'; +import { formatMomentValue, momentable } from '@formily/antd/esm/__builtins__'; + +export const getDefaultFormat = (props: DatePickerProps & { dateFormat: string; timeFormat: string }) => { + if (props.format) { + return props.format; + } + if (props.dateFormat) { + if (props['showTime']) { + return `${props.dateFormat} ${props.timeFormat || 'HH:mm:ss'}`; + } + return props.dateFormat; + } + if (props['picker'] === 'month') { + return 'YYYY-MM'; + } else if (props['picker'] === 'quarter') { + return 'YYYY-\\QQ'; + } else if (props['picker'] === 'year') { + return 'YYYY'; + } else if (props['picker'] === 'week') { + return 'YYYY-wo'; + } + return props['showTime'] ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'; +}; + +export const mapDateFormat = function () { + return (props: any) => { + const format = getDefaultFormat(props) as any; + const onChange = props.onChange; + return { + ...props, + format: format, + + value: momentable(props.value, format === 'YYYY-wo' ? 'YYYY-w' : format), + onChange: (value: moment.Moment | moment.Moment[]) => { + if (onChange) { + onChange(formatMomentValue(value, format)); + } + }, + }; + }; +}; diff --git a/packages/client/src/schema-component/antd/index.ts b/packages/client/src/schema-component/antd/index.ts index 07ae84d29..2baa7d275 100644 --- a/packages/client/src/schema-component/antd/index.ts +++ b/packages/client/src/schema-component/antd/index.ts @@ -2,6 +2,7 @@ export * from './action'; export * from './block-item'; export * from './checkbox'; export * from './color-select'; +export * from './date-picker'; export * from './dnd-context'; export * from './form'; export * from './form-item';