diff --git a/packages/arco-lib/src/components/TimePicker.tsx b/packages/arco-lib/src/components/TimePicker.tsx new file mode 100644 index 00000000..3d4bb797 --- /dev/null +++ b/packages/arco-lib/src/components/TimePicker.tsx @@ -0,0 +1,123 @@ +import { TimePicker as BaseTimePicker } from '@arco-design/web-react'; +import { implementRuntimeComponent } from '@sunmao-ui/runtime'; +import { css } from '@emotion/css'; +import { Type, Static } from '@sinclair/typebox'; +import { FALLBACK_METADATA, getComponentProps } from '../sunmao-helper'; +import { TimePickerPropsSpec as BaseTimePickerPropsSpec } from '../generated/types/TimePicker'; +import { Dayjs } from './DatePicker'; + +const TimePickerPropsSpec = Type.Object(BaseTimePickerPropsSpec); +const TimePickerStateSpec = Type.Object({ + visible: Type.Boolean(), + time: Type.Any(), + timeString: Type.Union([Type.Array(Type.String()), Type.String()]), +}); + +const exampleProperties: Static = { + disabled: false, + disableConfirm: false, + hideDisabledOptions: false, + step: { + hour: 1, + minute: 1, + second: 1, + }, + showNowButton: true, + placeholder: 'Please Select', + position: 'bl', + format: 'HH:mm:ss', + allowClear: false, + defaultValue: '18:24:23', + rangeDefaultValue: ['09:24:53', '18:44:33'], + range: false, + size: 'default', + use12Hours: false, + disabledTime: { + disabledHours: [0, 1, 2], + disabledMinutes: new Array(30).fill(0).map((e, i) => i), + disabledSeconds: [10], + }, + rangePlaceholder: ['Start date', 'End Date'], + useUtcOffset: false, + order: false, + utcOffset: 0, + timezone: '', +}; +const RangePicker = BaseTimePicker.RangePicker; + +export const TimePicker = implementRuntimeComponent({ + version: 'arco/v1', + metadata: { + ...FALLBACK_METADATA, + name: 'timePicker', + displayName: 'TimePicker', + exampleProperties, + annotations: { + category: 'Display', + }, + }, + spec: { + properties: TimePickerPropsSpec, + state: TimePickerStateSpec, + methods: {}, + slots: { + footer: { + slotProps: Type.Object({}), + }, + triggerElement: { + slotProps: Type.Object({}), + }, + }, + styleSlots: ['content'], + events: ['onChange', 'onClear', 'onVisibleChange'], + }, +})(props => { + const { + range, + disabledTime, + useUtcOffset, + utcOffset, + rangeDefaultValue, + rangePlaceholder, + ...cProps + } = getComponentProps(props); + const { elementRef, customStyle, slotsElements, callbackMap, mergeState } = props; + + const pickerProps = { + extra: slotsElements.footer, + utcOffset: useUtcOffset ? utcOffset : undefined, + onChange: (timeString: string | string[], time: Dayjs | Dayjs[]) => { + mergeState({ + time, + timeString, + }); + callbackMap?.onChange?.(); + }, + ...getDisabledTime(disabledTime), + ...cProps, + }; + + return ( + + {range ? ( + + ) : ( + + )} + + ); +}); + +function getDisabledTime( + disabledTime: Static +) { + return { + disabledHours: () => disabledTime.disabledHours, + disabledMinutes: () => disabledTime.disabledMinutes, + disabledSeconds: () => disabledTime.disabledSeconds, + }; +} diff --git a/packages/arco-lib/src/generated/types/TimePicker.ts b/packages/arco-lib/src/generated/types/TimePicker.ts new file mode 100644 index 00000000..630ce419 --- /dev/null +++ b/packages/arco-lib/src/generated/types/TimePicker.ts @@ -0,0 +1,168 @@ +import { Type } from '@sinclair/typebox'; +import { Category } from '../../constants/category'; +import { StringUnion } from '../../sunmao-helper'; +import { CoreWidgetName, CORE_VERSION } from '@sunmao-ui/editor-sdk'; + +const expressionWidget = `${CORE_VERSION}/${CoreWidgetName.Expression}`; +const DisabledTimeSpec = { + disabledHours: Type.Array(Type.Number(), { + title: 'Disabled Hours', + widget: expressionWidget, + }), + disabledMinutes: Type.Array(Type.Number(), { + title: 'Disabled Minutes', + widget: expressionWidget, + }), + disabledSeconds: Type.Array(Type.Number(), { + title: 'Disabled Seconds', + widget: expressionWidget, + }), +}; + +export const RangePickerPropsSpec = { + rangeDefaultValue: Type.Array(Type.Any(), { + title: 'Default Value', + category: Category.Basic, + conditions: [ + { + key: 'range', + value: true, + }, + ], + widget: expressionWidget, + }), + rangePlaceholder: Type.Optional( + Type.Array(Type.String(), { + title: 'Placeholder', + category: Category.Basic, + widget: expressionWidget, + conditions: [ + { + key: 'range', + value: true, + }, + ], + }) + ), + order: Type.Boolean({ + title: 'Order', + description: 'Whether the start and end times are automatically sorted', + category: Category.Behavior, + conditions: [ + { + key: 'range', + value: true, + }, + ], + }), +}; + +export const TimePickerPropsSpec = { + range: Type.Boolean({ + title: 'Range', + category: Category.Basic, + weight: 100, + }), + defaultValue: Type.Any({ + title: 'Default Value', + category: Category.Basic, + conditions: [ + { + key: 'range', + value: false, + }, + ], + }), + disabled: Type.Boolean({ + title: 'Disabled', + category: Category.Behavior, + }), + allowClear: Type.Boolean({ + title: 'Allow Clear', + category: Category.Behavior, + }), + disableConfirm: Type.Boolean({ + title: 'Disable Confirm', + category: Category.Behavior, + description: '', + }), + hideDisabledOptions: Type.Boolean({ + title: 'Hide Disabled Options', + category: Category.Behavior, + description: '', + }), + use12Hours: Type.Boolean({ + title: 'Use 12 Hours', + category: Category.Behavior, + }), + format: Type.String({ + title: 'Format', + category: Category.Basic, + description: ' Date format, refer to dayjs', + }), + step: Type.Object( + { + hour: Type.Number({ + title: 'Hour', + }), + minute: Type.Number({ + title: 'Minute', + }), + second: Type.Number({ + title: 'Second', + }), + }, + { + title: 'Step', + category: Category.Behavior, + widget: expressionWidget, + description: 'Set the hour/minute/second selection interval', + } + ), + position: StringUnion(['top', 'tl', 'tr', 'bottom', 'bl', 'br'], { + title: 'Position', + category: Category.Layout, + }), + placeholder: Type.String({ + title: 'Placeholder', + category: Category.Basic, + conditions: [ + { + key: 'range', + value: false, + }, + ], + }), + disabledTime: Type.Object(DisabledTimeSpec, { + title: 'Disabled Time', + category: Category.Behavior, + description: '', + }), + timezone: Type.String({ + title: 'Timezone', + category: Category.Behavior, + }), + useUtcOffset: Type.Boolean({ + title: 'Open UTC Offset', + category: Category.Behavior, + }), + utcOffset: Type.Number({ + title: 'UTC Offset', + category: Category.Behavior, + conditions: [ + { + key: 'useUtcOffset', + value: true, + }, + ], + }), + showNowButton: Type.Boolean({ + title: 'Show Now Button', + category: Category.Behavior, + }), + size: StringUnion(['mini', 'small', 'default', 'large'], { + title: 'Size', + category: Category.Layout, + }), + ...RangePickerPropsSpec, +}; diff --git a/packages/arco-lib/src/lib.ts b/packages/arco-lib/src/lib.ts index 25345189..b3f68a6a 100644 --- a/packages/arco-lib/src/lib.ts +++ b/packages/arco-lib/src/lib.ts @@ -38,8 +38,10 @@ import { Descriptions } from './components/Descriptions'; import { Row, Col } from './components/Grid'; import { Slider } from './components/Slider'; import { DatePicker } from './components/DatePicker'; +import { TimePicker } from './components/TimePicker'; import './style.css'; +import { MessageUtilMethodFactory } from './methods/Message'; export const components: SunmaoLib['components'] = [ Table, @@ -83,12 +85,15 @@ export const components: SunmaoLib['components'] = [ Col, Slider, DatePicker, + TimePicker, ]; export const traits: SunmaoLib['traits'] = []; export const modules: SunmaoLib['modules'] = []; +export const utilMethods: SunmaoLib['utilMethods'] = [MessageUtilMethodFactory]; export const ArcoDesignLib: SunmaoLib = { components, traits, modules, + utilMethods, };