Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support milliseconds picker column (#149) #151

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,12 @@ API
| showHour | Boolean | true | whether show hour | |
| showMinute | Boolean | true | whether show minute |
| showSecond | Boolean | true | whether show second |
| showMillisecond | Boolean | false | whether show millisecond |
| format | String | - | moment format |
| disabledHours | Function | - | disabled hour options |
| disabledMinutes | Function | - | disabled minute options |
| disabledSeconds | Function | - | disabled second options |
| disabledMilliseconds | Function | - | disabled millisecond options |
| use12Hours | Boolean | false | 12 hours display mode |
| hideDisabledOptions | Boolean | false | whether hide disabled options |
| onChange | Function | null | called when time-picker a different value |
Expand All @@ -85,10 +87,11 @@ API
| hourStep | Number | 1 | interval between hours in picker |
| minuteStep | Number | 1 | interval between minutes in picker |
| secondStep | Number | 1 | interval between seconds in picker |
| millisecondStep | Number | 1 | interval between milliseconds in picker |
| focusOnOpen | Boolean | false | automatically focus the input when the picker opens |
| inputReadOnly | Boolean | false | set input to read only |
| inputIcon | ReactNode | | specific the time-picker icon. |
| clearIcon | ReactNode | | specific the clear icon. |
| inputReadOnly | Boolean | false | set input to read only |
| inputIcon | ReactNode | | specific the select icon. |
| clearIcon | ReactNode | | specific the clear icon. |

## Test Case

Expand Down
4 changes: 4 additions & 0 deletions assets/index/Panel.less
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@
&-narrow {
max-width: 113px;
}

&-wide {
width: 227px;
}
}
6 changes: 6 additions & 0 deletions examples/disabled.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,25 @@ function disabledSeconds(h, m) {
return [h + (m % 60)];
}

function disabledMilliseconds() {
return [1, 5, 10];
}

const App = () => (
<>
<h3>Disabled picker</h3>
<TimePicker defaultValue={now} disabled onChange={onChange} />
<h3>Disabled options</h3>
<TimePicker
showSecond={showSecond}
showMillisecond
defaultValue={now}
className="xxx"
onChange={onChange}
disabledHours={disabledHours}
disabledMinutes={disabledMinutes}
disabledSeconds={disabledSeconds}
disabledMilliseconds={disabledMilliseconds}
/>
</>
);
Expand Down
1 change: 1 addition & 0 deletions examples/format.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const App = () => (
<TimePicker defaultValue={moment()} showHour={false} />
<TimePicker defaultValue={moment()} showMinute={false} />
<TimePicker defaultValue={moment()} showSecond={false} />
<TimePicker defaultValue={moment()} showMillisecond />

<TimePicker defaultValue={moment()} showMinute={false} showSecond={false} />
<TimePicker defaultValue={moment()} showHour={false} showSecond={false} />
Expand Down
33 changes: 32 additions & 1 deletion src/Combobox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ class Combobox extends Component {
}
}
onAmPmChange(ampm);
} else {
} else if (type === 'second') {
value.second(+itemValue);
} else {
itemValue += '0';
value.millisecond(+itemValue);
}
onChange(value);
};
Expand Down Expand Up @@ -154,6 +157,33 @@ class Combobox extends Component {
);
}

getMillisecondSelect(millisecond) {
const {
prefixCls,
millisecondOptions,
disabledMilliseconds,
showMillisecond,
defaultOpenValue,
value: propValue,
} = this.props;
if (!showMillisecond) {
return null;
}
const value = propValue || defaultOpenValue;
const disabledOptions = disabledMilliseconds(value.hour(), value.minute(), value.second());

return (
<Select
prefixCls={prefixCls}
options={millisecondOptions.map(option => formatOption(option, disabledOptions))}
selectedIndex={millisecondOptions.indexOf(Math.floor(millisecond / 10))}
type="millisecond"
onSelect={this.onItemChange}
onMouseEnter={() => this.onEnterSelectPanel('millisecond')}
/>
);
}

getAMPMSelect() {
const { prefixCls, use12Hours, format, isAM, onEsc } = this.props;
if (!use12Hours) {
Expand Down Expand Up @@ -187,6 +217,7 @@ class Combobox extends Component {
{this.getHourSelect(value.hour())}
{this.getMinuteSelect(value.minute())}
{this.getSecondSelect(value.second())}
{this.getMillisecondSelect(value.millisecond())}
{this.getAMPMSelect(value.hour())}
</div>
);
Expand Down
20 changes: 16 additions & 4 deletions src/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@ class Header extends Component {
hourOptions,
minuteOptions,
secondOptions,
millisecondOptions,
disabledHours,
disabledMinutes,
disabledSeconds,
disabledMilliseconds,
onChange,
} = this.props;

Expand All @@ -76,13 +78,15 @@ class Header extends Component {
value
.hour(parsed.hour())
.minute(parsed.minute())
.second(parsed.second());
.second(parsed.second())
.millisecond(parsed.millisecond());

// if time value not allowed, response warning.
if (
hourOptions.indexOf(value.hour()) < 0 ||
minuteOptions.indexOf(value.minute()) < 0 ||
secondOptions.indexOf(value.second()) < 0
secondOptions.indexOf(value.second()) < 0 ||
millisecondOptions.indexOf(value.millisecond()) < 0
) {
this.setState({
invalid: true,
Expand All @@ -94,10 +98,16 @@ class Header extends Component {
const disabledHourOptions = disabledHours();
const disabledMinuteOptions = disabledMinutes(value.hour());
const disabledSecondOptions = disabledSeconds(value.hour(), value.minute());
const disabledMillisecondOptions = disabledMilliseconds(
value.hour(),
value.minute(),
value.second(),
);
if (
(disabledHourOptions && disabledHourOptions.indexOf(value.hour()) >= 0) ||
(disabledMinuteOptions && disabledMinuteOptions.indexOf(value.minute()) >= 0) ||
(disabledSecondOptions && disabledSecondOptions.indexOf(value.second()) >= 0)
(disabledSecondOptions && disabledSecondOptions.indexOf(value.second()) >= 0) ||
(disabledMillisecondOptions && disabledMillisecondOptions.indexOf(value.millisecond()) >= 0)
) {
this.setState({
invalid: true,
Expand All @@ -109,13 +119,15 @@ class Header extends Component {
if (
originalValue.hour() !== value.hour() ||
originalValue.minute() !== value.minute() ||
originalValue.second() !== value.second()
originalValue.second() !== value.second() ||
originalValue.millisecond() !== value.millisecond()
) {
// keep other fields for rc-calendar
const changedValue = originalValue.clone();
changedValue.hour(value.hour());
changedValue.minute(value.minute());
changedValue.second(value.second());
changedValue.millisecond(value.millisecond());
onChange(changedValue);
}
} else if (originalValue !== value) {
Expand Down
30 changes: 27 additions & 3 deletions src/Panel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import classNames from 'classnames';
import Header from './Header';
import Combobox from './Combobox';

function noop() {}
function noop() { }

function generateOptions(length, disabledOptions, hideDisabledOptions, step = 1) {
const arr = [];
Expand All @@ -16,7 +16,7 @@ function generateOptions(length, disabledOptions, hideDisabledOptions, step = 1)
return arr;
}

function toNearestValidTime(time, hourOptions, minuteOptions, secondOptions) {
function toNearestValidTime(time, hourOptions, minuteOptions, secondOptions, millisecondOptions) {
const hour = hourOptions
.slice()
.sort((a, b) => Math.abs(time.hour() - a) - Math.abs(time.hour() - b))[0];
Expand All @@ -26,7 +26,10 @@ function toNearestValidTime(time, hourOptions, minuteOptions, secondOptions) {
const second = secondOptions
.slice()
.sort((a, b) => Math.abs(time.second() - a) - Math.abs(time.second() - b))[0];
return moment(`${hour}:${minute}:${second}`, 'HH:mm:ss');
const millisecond = millisecondOptions
.slice()
.sort((a, b) => Math.abs(time.millisecond() - a) - Math.abs(time.millisecond() - b))[0];
return moment(`${hour}:${minute}:${second}:${millisecond}`, 'HH:mm:ss:SS');
}

class Panel extends Component {
Expand All @@ -36,6 +39,7 @@ class Panel extends Component {
disabledHours: noop,
disabledMinutes: noop,
disabledSeconds: noop,
disabledMilliseconds: noop,
defaultOpenValue: moment(),
use12Hours: false,
addon: noop,
Expand Down Expand Up @@ -104,10 +108,12 @@ class Panel extends Component {
placeholder,
disabledMinutes,
disabledSeconds,
disabledMilliseconds,
hideDisabledOptions,
showHour,
showMinute,
showSecond,
showMillisecond,
format,
defaultOpenValue,
clearText,
Expand All @@ -119,6 +125,7 @@ class Panel extends Component {
hourStep,
minuteStep,
secondStep,
millisecondStep,
inputReadOnly,
clearIcon,
} = this.props;
Expand All @@ -129,6 +136,11 @@ class Panel extends Component {
value ? value.hour() : null,
value ? value.minute() : null,
);
const disabledMillisecondOptions = disabledMilliseconds(
value ? value.hour() : null,
value ? value.minute() : null,
value ? value.second() : null,
);
const hourOptions = generateOptions(24, disabledHourOptions, hideDisabledOptions, hourStep);
const minuteOptions = generateOptions(
60,
Expand All @@ -142,12 +154,19 @@ class Panel extends Component {
hideDisabledOptions,
secondStep,
);
const millisecondOptions = generateOptions(
100,
disabledMillisecondOptions,
hideDisabledOptions,
millisecondStep,
);

const validDefaultOpenValue = toNearestValidTime(
defaultOpenValue,
hourOptions,
minuteOptions,
secondOptions,
millisecondOptions,
);

return (
Expand All @@ -164,9 +183,11 @@ class Panel extends Component {
hourOptions={hourOptions}
minuteOptions={minuteOptions}
secondOptions={secondOptions}
millisecondOptions={millisecondOptions}
disabledHours={this.disabledHours}
disabledMinutes={disabledMinutes}
disabledSeconds={disabledSeconds}
disabledMilliseconds={disabledMilliseconds}
onChange={this.onChange}
focusOnOpen={focusOnOpen}
onKeyDown={onKeyDown}
Expand All @@ -183,12 +204,15 @@ class Panel extends Component {
showHour={showHour}
showMinute={showMinute}
showSecond={showSecond}
showMillisecond={showMillisecond}
hourOptions={hourOptions}
minuteOptions={minuteOptions}
secondOptions={secondOptions}
millisecondOptions={millisecondOptions}
disabledHours={this.disabledHours}
disabledMinutes={disabledMinutes}
disabledSeconds={disabledSeconds}
disabledMilliseconds={disabledMilliseconds}
onCurrentSelectPanelChange={this.onCurrentSelectPanelChange}
use12Hours={use12Hours}
onEsc={onEsc}
Expand Down
Loading