Skip to content

Commit

Permalink
Merge pull request #252 from sunshineLixun/dev
Browse files Browse the repository at this point in the history
feat: 新增DatePicker原子化组件
  • Loading branch information
sendya authored Nov 10, 2022
2 parents 1127fa6 + 695fd39 commit b3e16be
Show file tree
Hide file tree
Showing 31 changed files with 1,428 additions and 91 deletions.
32 changes: 26 additions & 6 deletions packages/pro-field/src/components/DatePicker/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { defineComponent, type App, DefineComponent, Plugin } from 'vue';
import Dayjs from 'dayjs';
import dayjs from 'dayjs';
import { fieldDatePickerProps, FieldDatePickerProps } from './types';
import { DatePicker } from 'ant-design-vue';
import { getSlot } from '@ant-design-vue/pro-utils';
Expand All @@ -10,13 +10,22 @@ const formatDate = (text: any, format: any) => {
return '-';
}
if (typeof format === 'function') {
return format(Dayjs(text));
return format(dayjs(text));
} else {
return Dayjs(text).format(format || 'YYYY-MM-DD');
return dayjs(text).format(format || 'YYYY-MM-DD');
}
};

export const slots = ['suffixIcon', 'prevIcon', 'nextIcon', 'superPrevIcon', 'superNextIcon'];
export const slots = [
'suffixIcon',
'prevIcon',
'nextIcon',
'superPrevIcon',
'superNextIcon',
'renderExtraFooter',
'dateRender',
'monthCellRender',
];

const FieldDatePicker = defineComponent({
name: 'FieldDatePicker',
Expand All @@ -29,16 +38,23 @@ const FieldDatePicker = defineComponent({
const nextIcon = getSlot<() => VueNode>(slots, props.fieldProps as Record<string, any>, 'nextIcon');
const superPrevIcon = getSlot<() => VueNode>(slots, props.fieldProps as Record<string, any>, 'superPrevIcon');
const superNextIcon = getSlot<() => VueNode>(slots, props.fieldProps as Record<string, any>, 'superNextIcon');
const renderExtraFooter = getSlot<() => VueNode>(
slots,
props.fieldProps as Record<string, any>,
'renderExtraFooter'
);
const dateRender = getSlot<() => VueNode>(slots, props.fieldProps as Record<string, any>, 'dateRender');
const monthCellRender = getSlot<() => VueNode>(slots, props.fieldProps as Record<string, any>, 'monthCellRender');

const render = getSlot(slots, props.fieldProps as Record<string, any>, 'render') as any;
const renderFormItem = getSlot(slots, props.fieldProps as Record<string, any>, 'renderFormItem') as any;

return () => {
const { mode, text, dateFormat, fieldProps } = props;
const { mode, text, fieldProps } = props;
const { placeholder, format } = fieldProps || {};

if (mode === 'read') {
const dom = formatDate(text, format || dateFormat);
const dom = formatDate(text, format);
if (render) {
return render(text, { mode, ...fieldProps }, <>{dom}</>);
}
Expand All @@ -53,8 +69,12 @@ const FieldDatePicker = defineComponent({
nextIcon,
superPrevIcon,
superNextIcon,
renderExtraFooter,
dateRender,
monthCellRender,
}}
{...fieldProps}
format={format}
placeholder={placeholder || '请选择'}
allowClear
/>
Expand Down
10 changes: 5 additions & 5 deletions packages/pro-field/src/components/DatePicker/types.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import type { ExtractPropTypes, PropType } from 'vue';
import type { Dayjs } from 'dayjs';
import type { CommonProps, DatePickerProps } from 'ant-design-vue/es/date-picker/generatePicker/props';
import { proFieldFC } from '../typings';

export const fieldDatePickerProps = {
...proFieldFC,
/** 日期格式化 */
dateFormat: {
type: String,
},
fieldProps: {
type: Object as PropType<CommonProps<any> & DatePickerProps<any>>,
type: Object as PropType<CommonProps<Dayjs> & DatePickerProps<Dayjs>>,
},
picker: {
type: String as PropType<CommonProps<Dayjs>['picker']>,
},
};

Expand Down
103 changes: 103 additions & 0 deletions packages/pro-field/src/components/RangePicker/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { defineComponent, type App, DefineComponent, Plugin } from 'vue';
import dayjs from 'dayjs';
import { fieldRangePickerProps, FieldRangePickerProps, RangesType } from './types';
import { RangePicker } from 'ant-design-vue';
import { getSlot } from '@ant-design-vue/pro-utils';
import type { VueNode } from 'ant-design-vue/lib/_util/type';

const formatDate = (text: any, format: any) => {
if (!text) {
return '-';
}
if (typeof format === 'function') {
return format(dayjs(text));
} else {
return dayjs(text).format(format || 'YYYY-MM-DD');
}
};

export const slots = [
'suffixIcon',
'prevIcon',
'nextIcon',
'superPrevIcon',
'superNextIcon',
'renderExtraFooter',
'dateRender',
];

const FieldRangePicker = defineComponent({
name: 'FieldRangePicker',
inheritAttrs: false,
props: fieldRangePickerProps,
slots,
setup(props, { slots }) {
const suffixIcon = getSlot<() => VueNode>(slots, props.fieldProps as Record<string, any>, 'suffixIcon');
const prevIcon = getSlot<() => VueNode>(slots, props.fieldProps as Record<string, any>, 'prevIcon');
const nextIcon = getSlot<() => VueNode>(slots, props.fieldProps as Record<string, any>, 'nextIcon');
const superPrevIcon = getSlot<() => VueNode>(slots, props.fieldProps as Record<string, any>, 'superPrevIcon');
const superNextIcon = getSlot<() => VueNode>(slots, props.fieldProps as Record<string, any>, 'superNextIcon');
const renderExtraFooter = getSlot<() => VueNode>(
slots,
props.fieldProps as Record<string, any>,
'renderExtraFooter'
);
const dateRender = getSlot<() => VueNode>(slots, props.fieldProps as Record<string, any>, 'dateRender');

const render = getSlot(slots, props.fieldProps as Record<string, any>, 'render') as any;
const renderFormItem = getSlot(slots, props.fieldProps as Record<string, any>, 'renderFormItem') as any;

return () => {
const { mode, text, fieldProps } = props;
const { placeholder, ranges, format = 'YYYY-MM-DD' } = fieldProps || {};
const [startText, endText] = Array.isArray(text) ? text : [];

if (mode === 'read') {
const parsedStartText: string = startText ? formatDate(startText, format) : '';
const parsedEndText: string = endText ? formatDate(endText, format) : '';
const dom = (
<div>
<div>{parsedStartText || '-'}</div>
<div>{parsedEndText || '-'}</div>
</div>
);
if (render) {
return render(text, { mode, ...fieldProps }, <>{dom}</>);
}
return dom;
}
if (mode === 'edit' || mode === 'update') {
const dom = (
<RangePicker
v-slots={{
suffixIcon,
prevIcon,
nextIcon,
superPrevIcon,
superNextIcon,
renderExtraFooter,
dateRender,
}}
{...fieldProps}
format={format}
ranges={ranges as RangesType}
placeholder={placeholder || ['请选择', '请选择']}
allowClear
/>
);
if (renderFormItem) {
return renderFormItem(text, { mode, ...fieldProps }, dom);
}
return dom;
}
return null;
};
},
});

FieldRangePicker.install = (app: App) => {
app.component(FieldRangePicker.name, FieldRangePicker);
return app;
};

export default FieldRangePicker as DefineComponent<FieldRangePickerProps> & Plugin;
21 changes: 21 additions & 0 deletions packages/pro-field/src/components/RangePicker/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { ExtractPropTypes, PropType } from 'vue';
import type { Dayjs } from 'dayjs';
import { rangePickerProps, type CommonProps } from 'ant-design-vue/es/date-picker/generatePicker/props';
import { proFieldFC } from '../typings';

const rangeProps = rangePickerProps<Dayjs>();

export type RangePickerProps = Partial<ExtractPropTypes<typeof rangeProps>>;

export const fieldRangePickerProps = {
...proFieldFC,
fieldProps: {
type: Object as PropType<CommonProps<Dayjs> & RangePickerProps>,
},
};

export type FieldRangePickerProps = Partial<ExtractPropTypes<typeof fieldRangePickerProps>>;

export type RangePickerValueType = [string, string] | [Dayjs, Dayjs];

export type RangesType = Record<string, [Dayjs, Dayjs] | (() => [Dayjs, Dayjs])>;
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getSlot } from '@ant-design-vue/pro-utils';
export const slots = ['default'];

const SearchSelect = defineComponent({
inheritAttrs: false,
props: searchSelectProps,
slots,
setup(props, { slots }) {
Expand Down
10 changes: 3 additions & 7 deletions packages/pro-field/src/components/Select/hooks/useFetchData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,9 @@ export const useFetchData = (props: FieldSelectProps) => {
const { request } = props;
watchEffect(() => {
loading.value = true;
request(
{
...props.params,
keyWords: defaultKeyWords.value,
},
props
)
request({
keyWords: defaultKeyWords.value,
})
.then((data) => {
options.value = data;
})
Expand Down
5 changes: 1 addition & 4 deletions packages/pro-field/src/components/Select/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ export const fieldSelectProps = {
fieldProps: {
type: Object as PropType<SearchSelectProps>,
},
// 请求参数
params: {
type: Object as PropType<Record<string, any>>,
},
// 请求
request: {
type: Function as PropType<ProFieldRequestData>,
Expand All @@ -24,6 +20,7 @@ export const fieldSelectProps = {
export type FieldSelectProps = Partial<ExtractPropTypes<typeof fieldSelectProps>>;

const FieldSelect = defineComponent({
inheritAttrs: false,
props: fieldSelectProps,
slots: ['render', 'renderFormItem'],
setup(props, { slots }) {
Expand Down
69 changes: 69 additions & 0 deletions packages/pro-field/src/components/TimePicker/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { defineComponent, type App, DefineComponent, Plugin } from 'vue';
import dayjs from 'dayjs';
import { fieldTimePickerProps, FieldTimePickerProps } from './types';
import { TimePicker } from 'ant-design-vue';
import { getSlot, VueText } from '@ant-design-vue/pro-utils';
import type { VueNode } from 'ant-design-vue/lib/_util/type';

export const slots = ['renderExtraFooter', 'suffixIcon', 'clearIcon'];

const FieldTimePicker = defineComponent({
name: 'FieldDatePicker',
inheritAttrs: false,
props: fieldTimePickerProps,
slots,
setup(props, { slots }) {
const suffixIcon = getSlot<() => VueNode>(slots, props.fieldProps as Record<string, any>, 'suffixIcon');
const clearIcon = getSlot<() => VueNode>(slots, props.fieldProps as Record<string, any>, 'clearIcon');
const renderExtraFooter = getSlot<() => VueNode>(
slots,
props.fieldProps as Record<string, any>,
'renderExtraFooter'
);

const render = getSlot(slots, props.fieldProps as Record<string, any>, 'render') as any;
const renderFormItem = getSlot(slots, props.fieldProps as Record<string, any>, 'renderFormItem') as any;

return () => {
const { mode, text, fieldProps } = props;
const { placeholder } = fieldProps || {};

const finalFormat = fieldProps?.format || 'HH:mm:ss';

if (mode === 'read') {
const dom = <span>{text ? dayjs(text as VueText, finalFormat).format(finalFormat) : '-'}</span>;
if (render) {
return render(text, { mode, ...fieldProps }, <span>{dom}</span>);
}
return dom;
}
if (mode === 'edit' || mode === 'update') {
const dom = (
<TimePicker
v-slots={{
suffixIcon,
renderExtraFooter,
clearIcon,
}}
{...fieldProps}
format={finalFormat}
placeholder={placeholder || '请选择'}
allowClear
/>
);
if (renderFormItem) {
return renderFormItem(text, { mode, ...fieldProps }, dom);
}
return dom;
}
return null;
};
},
});

FieldTimePicker.install = (app: App) => {
app.component(FieldTimePicker.name, FieldTimePicker);
return app;
};

export default FieldTimePicker as DefineComponent<FieldTimePickerProps> & Plugin;
13 changes: 13 additions & 0 deletions packages/pro-field/src/components/TimePicker/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { ExtractPropTypes, PropType } from 'vue';
import type { Dayjs } from 'dayjs';
import type { TimePickerProps } from 'ant-design-vue/es/time-picker/time-picker';
import { proFieldFC } from '../typings';

export const fieldTimePickerProps = {
...proFieldFC,
fieldProps: {
type: Object as PropType<TimePickerProps<Dayjs>>,
},
};

export type FieldTimePickerProps = Partial<ExtractPropTypes<typeof fieldTimePickerProps>>;
Loading

0 comments on commit b3e16be

Please sign in to comment.