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

auto focus on calendar input when opening picker #438

Merged
Merged
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
21 changes: 11 additions & 10 deletions examples/antd-calendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,15 @@ class Demo extends React.Component {
({ value }) => {
return (
<span tabIndex="0">
<input
placeholder="please select"
style={{ width: 250 }}
disabled={state.disabled}
readOnly
tabIndex="-1"
className="ant-calendar-picker-input ant-input"
value={value && value.format(getFormat(state.showTime)) || ''}
/>
<input
placeholder="please select"
style={{ width: 250 }}
disabled={state.disabled}
readOnly
tabIndex="-1"
className="ant-calendar-picker-input ant-input"
value={value && value.format(getFormat(state.showTime)) || ''}
/>
</span>
);
}
Expand Down Expand Up @@ -208,7 +208,7 @@ class DemoMultiFormat extends React.Component {
return (<div style={{ width: 400, margin: 20 }}>
<div style={{ marginBottom: 10 }}>
Accepts multiple input formats
<br/>
<br />
<small>{multiFormats.join(', ')}</small>
</div>
<Calendar
Expand All @@ -218,6 +218,7 @@ class DemoMultiFormat extends React.Component {
format={multiFormats}
value={state.value}
onChange={this.onChange}
focusablePanel={false}
/>
</div>);
}
Expand Down
15 changes: 14 additions & 1 deletion src/Calendar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class Calendar extends React.Component {
renderFooter: PropTypes.func,
renderSidebar: PropTypes.func,
clearIcon: PropTypes.node,
focusablePanel: PropTypes.bool,
}

static defaultProps = {
Expand All @@ -61,8 +62,10 @@ class Calendar extends React.Component {
timePicker: null,
onOk: noop,
onPanelChange: noop,
focusablePanel: true,
}


constructor(props) {
super(props);

Expand All @@ -73,6 +76,12 @@ class Calendar extends React.Component {
};
}

componentDidMount() {
if (this.props.showDateInput) {
this.saveFocusElement(DateInput.getInstance());
}
}

onPanelChange = (value, mode) => {
const { props, state } = this;
if (!('mode' in props)) {
Expand Down Expand Up @@ -279,13 +288,17 @@ class Calendar extends React.Component {
clearIcon={clearIcon}
/>
) : null;

const children = [];
if (props.renderSidebar) {
children.push(props.renderSidebar());
}
children.push(<div className={`${prefixCls}-panel`} key="panel">
{dateInputElement}
<div className={`${prefixCls}-date-panel`}>
<div
tabIndex={this.props.focusablePanel ? 0 : undefined}
className={`${prefixCls}-date-panel`}
>
<CalendarHeader
locale={locale}
mode={mode}
Expand Down
8 changes: 6 additions & 2 deletions src/date/DateInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default class DateInput extends React.Component {

componentDidUpdate() {
if (this.state.hasFocus && !this.state.invalid &&
!(cachedSelectionStart === 0 && cachedSelectionEnd === 0)) {
!(cachedSelectionStart === 0 && cachedSelectionEnd === 0)) {
dateInputInstance.setSelectionRange(cachedSelectionStart, cachedSelectionEnd);
}
}
Expand Down Expand Up @@ -131,6 +131,10 @@ export default class DateInput extends React.Component {
return newState;
}

static getInstance() {
return dateInputInstance;
}

getRootDOMNode = () => {
return ReactDOM.findDOMNode(this);
}
Expand Down Expand Up @@ -170,7 +174,7 @@ export default class DateInput extends React.Component {
title={locale.clear}
onClick={this.onClear}
>
{clearIcon || <span className={`${prefixCls}-clear-btn`}/>}
{clearIcon || <span className={`${prefixCls}-clear-btn`} />}
</a>
) : null}
</div>
Expand Down
8 changes: 7 additions & 1 deletion src/mixin/CommonMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,17 @@ export const commonMixinWrapper = ComposeComponent => class extends ComposeCompo
}

focus = () => {
if (this.rootInstance) {
if (this.focusElement) {
this.focusElement.focus();
} else if (this.rootInstance) {
this.rootInstance.focus();
}
}

saveFocusElement = (focusElement) => {
this.focusElement = focusElement;
}

saveRoot = (root) => {
this.rootInstance = root;
}
Expand Down
23 changes: 21 additions & 2 deletions tests/Picker.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,19 @@ describe('DatePicker', () => {
onChange={noop}
readOnly
value={value && `${value[0] &&
value[0].format(format)} - ${value[1] && value[1].format(format)}`}
value[0].format(format)} - ${value[1] && value[1].format(format)}`}
/>);
}

function renderPicker(props) {
function renderPicker(props, calendarProps) {
return mount(
<DatePicker
calendar={
<Calendar
locale={CalendarLocale}
showOk
showClear
{...calendarProps}
/>
}
defaultValue={VALUE}
Expand Down Expand Up @@ -184,4 +185,22 @@ describe('DatePicker', () => {
picker.find('.rc-calendar-clear-btn').simulate('click');
expect(picker.state().open).toBe(false);
});

it('auto focuses the calendar input when opening', () => {
jest.useFakeTimers();
const picker = renderPicker({ value: moment() });
picker.find('.rc-calendar-picker-input').simulate('click');
jest.runAllTimers();
expect(document.activeElement).toBeDefined();
expect(document.activeElement.classList).toContain('rc-calendar-input');
});

it('auto focuses the calendar div when date input is not shown', () => {
jest.useFakeTimers();
const picker = renderPicker({ value: moment() }, { showDateInput: false });
picker.find('.rc-calendar-picker-input').simulate('click');
jest.runAllTimers();
expect(document.activeElement).toBeDefined();
expect(document.activeElement.classList).toContain('rc-calendar');
});
});
5 changes: 5 additions & 0 deletions tests/__snapshots__/Calendar.spec.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ exports[`Calendar controlled panels render controlled panels correctly 1`] = `
</div>
<div
class="rc-calendar-date-panel"
tabindex="0"
>
<div
class="rc-calendar-header"
Expand Down Expand Up @@ -996,6 +997,7 @@ exports[`Calendar controlled panels render controlled panels correctly 2`] = `
</div>
<div
class="rc-calendar-date-panel"
tabindex="0"
>
<div
class="rc-calendar-header"
Expand Down Expand Up @@ -1962,6 +1964,7 @@ exports[`Calendar render render correctly 1`] = `
</div>
<div
class="rc-calendar-date-panel"
tabindex="0"
>
<div
class="rc-calendar-header"
Expand Down Expand Up @@ -2730,6 +2733,7 @@ exports[`Calendar render render correctly 2`] = `
</div>
<div
class="rc-calendar-date-panel"
tabindex="0"
>
<div
class="rc-calendar-header"
Expand Down Expand Up @@ -3498,6 +3502,7 @@ exports[`Calendar render render correctly 3`] = `
</div>
<div
class="rc-calendar-date-panel"
tabindex="0"
>
<div
class="rc-calendar-header"
Expand Down
Loading