| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 | 
							- /* eslint-disable max-len */
 
- /* eslint-disable react/no-did-update-set-state */
 
- import React from 'react';
 
- import PropTypes from 'prop-types';
 
- import { format as dateFnsFormat } from 'date-fns';
 
- import { noop } from 'lodash';
 
- import BaseComponent, { BaseProps } from '../_base/baseComponent';
 
- import { strings } from '@douyinfe/semi-foundation/timePicker/constants';
 
- import ScrollList from '../scrollList/index';
 
- import ScrollItem from '../scrollList/scrollItem';
 
- import ComboboxFoundation, { formatOption } from '@douyinfe/semi-foundation/timePicker/ComboxFoundation';
 
- import LocaleConsumer from '../locale/localeConsumer';
 
- import { TimePickerProps } from './TimePicker';
 
- import { Locale } from '../locale/interface';
 
- export type ComboboxProps = Pick<TimePickerProps, 'format' | 'prefixCls' | 'disabledHours' |
 
- 'disabledMinutes' |
 
- 'disabledSeconds' |
 
- 'hideDisabledOptions' |
 
- 'use12Hours' |
 
- 'scrollItemProps' |
 
- 'panelFooter' |
 
- 'panelHeader'> & BaseProps & {
 
-     defaultOpenValue?: TimePickerProps['value'];
 
-     showHour?: boolean;
 
-     showMinute?: boolean;
 
-     showSecond?: boolean;
 
-     onChange?: (value: { isAM: boolean; value: string; timeStampValue: number }) => void;
 
-     onCurrentSelectPanelChange?: (range: string) => void;
 
-     isAM?: boolean;
 
-     timeStampValue?: any;
 
- };
 
- export interface ComboboxState {
 
-     showHour: boolean;
 
-     showMinute: boolean;
 
-     showSecond: boolean;
 
-     hourOptions: number[];
 
-     minuteOptions: number[];
 
-     secondOptions: number[];
 
- }
 
- export type FormatOptionReturn = ReturnType<typeof formatOption>;
 
- export interface AMPMOptionItem {
 
-     value: string;
 
-     text: string;
 
- }
 
- class Combobox extends BaseComponent<ComboboxProps, ComboboxState> {
 
-     static propTypes = {
 
-         format: PropTypes.string,
 
-         defaultOpenValue: PropTypes.object,
 
-         prefixCls: PropTypes.string,
 
-         onChange: PropTypes.func,
 
-         showHour: PropTypes.bool,
 
-         showMinute: PropTypes.bool,
 
-         showSecond: PropTypes.bool,
 
-         disabledHours: PropTypes.func,
 
-         disabledMinutes: PropTypes.func,
 
-         disabledSeconds: PropTypes.func,
 
-         hideDisabledOptions: PropTypes.bool,
 
-         onCurrentSelectPanelChange: PropTypes.func,
 
-         use12Hours: PropTypes.bool,
 
-         isAM: PropTypes.bool,
 
-         timeStampValue: PropTypes.any,
 
-         scrollItemProps: PropTypes.object,
 
-     };
 
-     static defaultProps = {
 
-         disabledHours: noop,
 
-         disabledMinutes: noop,
 
-         disabledSeconds: noop,
 
-         format: strings.DEFAULT_FORMAT,
 
-     };
 
-     foundation: ComboboxFoundation;
 
-     constructor(props: ComboboxProps) {
 
-         super(props);
 
-         this.foundation = new ComboboxFoundation(this.adapter);
 
-         this.state = {
 
-             ...this.foundation.initData(),
 
-         };
 
-     }
 
-     componentDidUpdate(prevProps: ComboboxProps, prevState: ComboboxState) {
 
-         if (prevProps.timeStampValue !== this.props.timeStampValue || prevProps.format !== this.props.format) {
 
-             this.setState({
 
-                 ...this.foundation.initData(),
 
-             });
 
-         }
 
-     }
 
-     componentWillUnmount() {
 
-         // this.foundation.destroy();
 
-     }
 
-     componentDidMount() {
 
-         // this.foundation.init();
 
-     }
 
-     cacheRefCurrent = (key: string, current: ScrollItem<FormatOptionReturn> | ScrollItem<AMPMOptionItem>) => {
 
-         if (key && typeof key === 'string') {
 
-             this.adapter.setCache(key, current);
 
-         }
 
-     };
 
-     reselect = () => {
 
-         const currentKeys = ['ampm', 'hour', 'minute', 'second'];
 
-         currentKeys.forEach(key => {
 
-             const current = this.adapter.getCache(key);
 
-             if (current && current.scrollToIndex) {
 
-                 current.scrollToIndex();
 
-             }
 
-         });
 
-     };
 
-     onItemChange = ({ type, value, disabled }: { type?: string; value: string; disabled?: boolean; }) => {
 
-         // eslint-disable-next-line prefer-const
 
-         let { onChange, use12Hours, isAM, format, timeStampValue } = this.props;
 
-         const transformValue = this.foundation.getDisplayDateFromTimeStamp(timeStampValue);
 
-         // TODO: foundation
 
-         if (type === 'hour') {
 
-             if (use12Hours) {
 
-                 if (isAM) {
 
-                     transformValue.setHours(Number(value) % 12);
 
-                 } else {
 
-                     transformValue.setHours((Number(value) % 12) + 12);
 
-                 }
 
-             } else {
 
-                 transformValue.setHours(Number(value));
 
-             }
 
-         } else if (type === 'minute') {
 
-             transformValue.setMinutes(Number(value));
 
-         } else if (type === 'ampm') {
 
-             const ampm = value.toUpperCase();
 
-             if (use12Hours) {
 
-                 if (ampm === 'PM') {
 
-                     isAM = false;
 
-                     transformValue.getHours() < 12 && transformValue.setHours((transformValue.getHours() % 12) + 12);
 
-                 }
 
-                 if (ampm === 'AM') {
 
-                     isAM = true;
 
-                     transformValue.getHours() >= 12 && transformValue.setHours(transformValue.getHours() - 12);
 
-                 }
 
-             }
 
-         } else {
 
-             transformValue.setSeconds(Number(value));
 
-         }
 
-         onChange &&
 
-             onChange({
 
-                 isAM,
 
-                 value: dateFnsFormat(transformValue, format && format.replace(/(\s+)A/g, '$1a')), // dateFns only supports "h: mm: ss a"
 
-                 timeStampValue: Number(transformValue),
 
-             });
 
-     };
 
-     onEnterSelectPanel = (range: string) => {
 
-         const { onCurrentSelectPanelChange } = this.props;
 
-         onCurrentSelectPanelChange(range);
 
-     };
 
-     renderHourSelect(hour: number, locale: Locale['TimePicker']) {
 
-         const { prefixCls, disabledHours, use12Hours, scrollItemProps } = this.props;
 
-         const { showHour, hourOptions } = this.state;
 
-         if (!showHour) {
 
-             return null;
 
-         }
 
-         const disabledOptions = disabledHours();
 
-         let hourOptionsAdj,
 
-             hourAdj;
 
-         if (use12Hours) {
 
-             hourOptionsAdj = [12].concat(hourOptions.filter(h => h < 12 && h > 0));
 
-             hourAdj = hour % 12 || 12;
 
-         } else {
 
-             hourOptionsAdj = hourOptions;
 
-             hourAdj = hour;
 
-         }
 
-         const transformHour = (value: string) => value + locale.hour;
 
-         const className = `${prefixCls}-list-hour`;
 
-         return (
 
-             <ScrollItem<FormatOptionReturn>
 
-                 ref={current => this.cacheRefCurrent('hour', current)}
 
-                 mode={'wheel'}
 
-                 transform={transformHour}
 
-                 cycled={true}
 
-                 className={className}
 
-                 list={hourOptionsAdj.map(option => formatOption(option, disabledOptions))}
 
-                 selectedIndex={hourOptionsAdj.indexOf(hourAdj)}
 
-                 type="hour"
 
-                 onSelect={this.onItemChange}
 
-                 {...scrollItemProps}
 
-             />
 
-         );
 
-     }
 
-     renderMinuteSelect(minute: number, locale: Locale['TimePicker']) {
 
-         const { prefixCls, disabledMinutes, timeStampValue, scrollItemProps } = this.props;
 
-         const { showMinute, minuteOptions } = this.state;
 
-         if (!showMinute) {
 
-             return null;
 
-         }
 
-         const value = new Date(timeStampValue);
 
-         const disabledOptions = disabledMinutes && disabledMinutes(value.getHours());
 
-         const className = `${prefixCls}-list-minute`;
 
-         const transformMinute = (min: string) => min + locale.minute;
 
-         return (
 
-             <ScrollItem<FormatOptionReturn>
 
-                 ref={current => this.cacheRefCurrent('minute', current)}
 
-                 mode={'wheel'}
 
-                 transform={transformMinute}
 
-                 cycled={true}
 
-                 list={minuteOptions.map(option => formatOption(option, disabledOptions))}
 
-                 selectedIndex={minuteOptions.indexOf(minute)}
 
-                 type="minute"
 
-                 onSelect={this.onItemChange}
 
-                 className={className}
 
-                 {...scrollItemProps}
 
-             />
 
-         );
 
-     }
 
-     renderSecondSelect(second: number, locale: Locale['TimePicker']) {
 
-         const { prefixCls, disabledSeconds, timeStampValue, scrollItemProps } = this.props;
 
-         const { showSecond, secondOptions } = this.state;
 
-         if (!showSecond) {
 
-             return null;
 
-         }
 
-         const value = new Date(timeStampValue);
 
-         const disabledOptions = disabledSeconds && disabledSeconds(value.getHours(), value.getMinutes());
 
-         const className = `${prefixCls}-list-second`;
 
-         const transformSecond = (sec: number) => String(sec) + locale.second;
 
-         return (
 
-             <ScrollItem<FormatOptionReturn>
 
-                 ref={current => this.cacheRefCurrent('second', current)}
 
-                 mode={'wheel'}
 
-                 transform={transformSecond}
 
-                 cycled={true}
 
-                 list={secondOptions.map(option => formatOption(option, disabledOptions))}
 
-                 selectedIndex={secondOptions.indexOf(second)}
 
-                 className={className}
 
-                 type="second"
 
-                 onSelect={this.onItemChange}
 
-                 {...scrollItemProps}
 
-             />
 
-         );
 
-     }
 
-     renderAMPMSelect(locale: Locale['TimePicker'], localeCode: string) {
 
-         const { prefixCls, use12Hours, isAM, scrollItemProps } = this.props;
 
-         if (!use12Hours) {
 
-             return null;
 
-         }
 
-         const AMPMOptions: AMPMOptionItem[] = [
 
-             {
 
-                 value: 'AM',
 
-                 text: locale.AM || '上午',
 
-             },
 
-             {
 
-                 value: 'PM',
 
-                 text: locale.PM || '下午',
 
-             },
 
-         ];
 
-         const selected = isAM ? 0 : 1;
 
-         const className = `${prefixCls}-list-ampm`;
 
-         return (
 
-             <ScrollItem<AMPMOptionItem>
 
-                 ref={current => this.cacheRefCurrent('ampm', current)}
 
-                 mode={'wheel'}
 
-                 className={className}
 
-                 cycled={false}
 
-                 list={AMPMOptions}
 
-                 selectedIndex={selected}
 
-                 type="ampm"
 
-                 onSelect={this.onItemChange}
 
-                 {...scrollItemProps}
 
-             />
 
-         );
 
-     }
 
-     getDisplayDateFromTimeStamp = (timeStampValue: Date | string) => this.foundation.getDisplayDateFromTimeStamp(timeStampValue);
 
-     render() {
 
-         const { timeStampValue, panelHeader, panelFooter } = this.props;
 
-         const value = this.getDisplayDateFromTimeStamp(timeStampValue);
 
-         return (
 
-             <LocaleConsumer componentName="TimePicker">
 
-                 {(locale: Locale['TimePicker'], localeCode: Locale['code']) => (
 
-                     <ScrollList header={panelHeader} footer={panelFooter}>
 
-                         {this.renderAMPMSelect(locale, localeCode)}
 
-                         {this.renderHourSelect(value.getHours(), locale)}
 
-                         {this.renderMinuteSelect(value.getMinutes(), locale)}
 
-                         {this.renderSecondSelect(value.getSeconds(), locale)}
 
-                     </ScrollList>
 
-                 )}
 
-             </LocaleConsumer>
 
-         );
 
-     }
 
- }
 
- export default Combobox;
 
 
  |