Skip to content

Commit

Permalink
Merge pull request #47 from chenz24/feat/DatePicker
Browse files Browse the repository at this point in the history
feat: Add DatePicker component
  • Loading branch information
chenz24 authored Sep 17, 2021
2 parents aba6d3f + 3dc9737 commit c889493
Show file tree
Hide file tree
Showing 18 changed files with 670 additions and 3 deletions.
2 changes: 2 additions & 0 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@
"@tippyjs/react": "^4.2.5",
"classnames": "^2.3.1",
"clsx": "^1.1.1",
"dayjs": "^1.10.7",
"rc-dialog": "^8.6.0",
"rc-field-form": "^1.21.2",
"rc-input-number": "^7.3.0",
"rc-motion": "^2.4.4",
"rc-picker": "^2.5.18",
"rc-select": "^12.1.13",
"react-hot-toast": "^2.1.1",
"react-textarea-autosize": "^8.3.2",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { ModalLocale } from '../../Modal/locale';
// eslint-disable-next-line import/no-cycle
import { PickerLocale } from '../../DatePicker/generatePicker';

export interface ILocale {
Modal?: ModalLocale;
DatePicker?: PickerLocale;
}
4 changes: 4 additions & 0 deletions packages/components/src/ConfigProvider/locales/default.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
// eslint-disable-next-line import/no-cycle
import { ILocale } from '../LocaleProvider/types';
// eslint-disable-next-line import/no-cycle
import PickerLocale from '../../DatePicker/locales/en_US';

const localeValues: ILocale = {
Modal: {
okText: 'OK',
cancelText: 'Cancel',
justOkText: 'OK',
},
DatePicker: PickerLocale,
};

export default localeValues;
10 changes: 10 additions & 0 deletions packages/components/src/DatePicker/DatePicker.story.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as React from 'react';
import DatePicker from './DatePicker';

// const { MonthPicker } = DatePicker;

export default {
title: 'Components/DatePicker',
};

export const Basic = () => <DatePicker />;
18 changes: 18 additions & 0 deletions packages/components/src/DatePicker/DatePicker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/index.tsx
import { Dayjs } from 'dayjs';
import dayjsGenerateConfig from 'rc-picker/es/generate/dayjs';
// eslint-disable-next-line import/no-cycle
import generatePicker, {
PickerProps,
PickerDateProps,
RangePickerProps as BaseRangePickerProps,
} from './generatePicker';

export type DatePickerProps = PickerProps<Dayjs>;
export type MonthPickerProps = Omit<PickerDateProps<Dayjs>, 'picker'>;
export type WeekPickerProps = Omit<PickerDateProps<Dayjs>, 'picker'>;
export type RangePickerProps = BaseRangePickerProps<Dayjs>;

const DatePicker = generatePicker<Dayjs>(dayjsGenerateConfig);

export default DatePicker;
6 changes: 6 additions & 0 deletions packages/components/src/DatePicker/PickerButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from 'react';
import { Button, ButtonProps } from '../Button/Button';

export default function PickerButton(props: ButtonProps) {
return <Button size="sm" {...props} />;
}
6 changes: 6 additions & 0 deletions packages/components/src/DatePicker/PickerTag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from 'react';
import { Tag, TagProps } from '../Tag/Tag';

export default function PickerTag(props: TagProps) {
return <Tag {...props} />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import React, { FC, useImperativeHandle, useRef } from 'react';
import classNames from 'classnames';
import Calendar from '@kubed/icons/dist/calendar';
import Clock from '@kubed/icons/dist/clock';
import Close from '@kubed/icons/dist/close';
import Next from '@kubed/icons/dist/next';
import { RangePicker as RCRangePicker } from 'rc-picker';
import { GenerateConfig } from 'rc-picker/lib/generate';
import { getRangePlaceholder } from '../util';
import { RangePickerProps, getTimeProps, Components } from '.';
// import { CommonPickerMethods } from './interface';
import forwardRef from '../../utils/forwardRef';
import { useLocales } from '../../ConfigProvider/LocaleProvider/LocaleContext';

export default function generateRangePicker<DateType>(
generateConfig: GenerateConfig<DateType>
): FC<RangePickerProps<DateType>> {
// class RangePicker2 extends React.Component<RangePickerProps<DateType>> {
// static contextType = ConfigContext;
//
// context: ConfigConsumerProps;
//
// pickerRef = React.createRef<RCRangePicker<DateType>>();
//
// focus = () => {
// if (this.pickerRef.current) {
// this.pickerRef.current.focus();
// }
// };
//
// blur = () => {
// if (this.pickerRef.current) {
// this.pickerRef.current.blur();
// }
// };
//
// renderPicker = (contextLocale: PickerLocale) => {
// const locale = { ...contextLocale, ...this.props.locale };
// const { getPrefixCls, direction, getPopupContainer } = this.context;
// const {
// prefixCls: customizePrefixCls,
// getPopupContainer: customGetPopupContainer,
// className,
// size: customizeSize,
// bordered = true,
// placeholder,
// ...restProps
// } = this.props;
// const { format, showTime, picker } = this.props as any;
// const prefixCls = getPrefixCls('picker', customizePrefixCls);
//
// let additionalOverrideProps: any = {};
//
// additionalOverrideProps = {
// ...additionalOverrideProps,
// ...(showTime ? getTimeProps({ format, picker, ...showTime }) : {}),
// ...(picker === 'time' ? getTimeProps({ format, ...this.props, picker }) : {}),
// };
// const rootPrefixCls = getPrefixCls();
//
// return (
// <SizeContext.Consumer>
// {(size) => {
// const mergedSize = customizeSize || size;
//
// return (
// <RCRangePicker<DateType>
// separator={
// <span aria-label="to" className={`${prefixCls}-separator`}>
// <Next />
// </span>
// }
// ref={this.pickerRef}
// placeholder={getRangePlaceholder(picker, locale, placeholder)}
// suffixIcon={picker === 'time' ? <Clock /> : <Calendar />}
// clearIcon={<Close />}
// prevIcon={<span className={`${prefixCls}-prev-icon`} />}
// nextIcon={<span className={`${prefixCls}-next-icon`} />}
// superPrevIcon={<span className={`${prefixCls}-super-prev-icon`} />}
// superNextIcon={<span className={`${prefixCls}-super-next-icon`} />}
// allowClear
// transitionName={`${rootPrefixCls}-slide-up`}
// {...restProps}
// {...additionalOverrideProps}
// className={classNames(
// {
// [`${prefixCls}-${mergedSize}`]: mergedSize,
// [`${prefixCls}-borderless`]: !bordered,
// },
// className
// )}
// locale={locale!.lang}
// prefixCls={prefixCls}
// getPopupContainer={customGetPopupContainer || getPopupContainer}
// generateConfig={generateConfig}
// components={Components}
// direction={direction}
// />
// );
// }}
// </SizeContext.Consumer>
// );
// };
//
// render() {
// return (
// <LocaleReceiver componentName="DatePicker" defaultLocale={enUS}>
// {this.renderPicker}
// </LocaleReceiver>
// );
// }
// }

const RangePicker = forwardRef<RangePickerProps<DateType>, any>((props, ref) => {
const {
prefixCls: customizePrefixCls,
getPopupContainer: customGetPopupContainer,
className,
size: customizeSize,
bordered = true,
placeholder,
...restProps
} = props;
const { format, showTime, picker } = props as any;
const prefixCls = 'kubed-picker';
const rootPrefixCls = 'kubed-picker-root';

let additionalOverrideProps: any = {};

additionalOverrideProps = {
...additionalOverrideProps,
...(showTime ? getTimeProps({ format, picker, ...showTime }) : {}),
...(picker === 'time' ? getTimeProps({ format, ...this.props, picker }) : {}),
};

const pickerRef = useRef<RCRangePicker<DateType>>();
useImperativeHandle(ref, () => ({
focus: () => {
if (pickerRef.current) {
pickerRef.current.focus();
}
},
blur: () => {
if (pickerRef.current) {
pickerRef.current.blur();
}
},
}));

const locale = useLocales();
const { DatePicker: locales } = locale;

return (
<RCRangePicker<DateType>
separator={
<span aria-label="to" className={`${prefixCls}-separator`}>
<Next />
</span>
}
ref={pickerRef}
placeholder={getRangePlaceholder(picker, locales, placeholder)}
suffixIcon={picker === 'time' ? <Clock /> : <Calendar />}
clearIcon={<Close />}
prevIcon={<span className={`${prefixCls}-prev-icon`} />}
nextIcon={<span className={`${prefixCls}-next-icon`} />}
superPrevIcon={<span className={`${prefixCls}-super-prev-icon`} />}
superNextIcon={<span className={`${prefixCls}-super-next-icon`} />}
allowClear
transitionName={`${rootPrefixCls}-slide-up`}
{...restProps}
{...additionalOverrideProps}
className={classNames(
{
// [`${prefixCls}-${mergedSize}`]: mergedSize,
[`${prefixCls}-borderless`]: !bordered,
},
className
)}
locale={locales!.lang}
prefixCls={prefixCls}
// getPopupContainer={customGetPopupContainer || getPopupContainer}
generateConfig={generateConfig}
components={Components}
// direction={direction}
/>
);
});

return RangePicker;
}
Loading

0 comments on commit c889493

Please sign in to comment.