Skip to content

Commit

Permalink
Async components (plotly#692)
Browse files Browse the repository at this point in the history
  • Loading branch information
Marc-Andre-Rivet committed Nov 4, 2019
1 parent 22c7eef commit 5b7023e
Show file tree
Hide file tree
Showing 18 changed files with 753 additions and 597 deletions.
3 changes: 3 additions & 0 deletions packages/dash-core-components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
### Added
- [#692](https://github.com/plotly/dash-core-components/pull/692) Async DatePickerSingle, DatePickerRange, Dropdown, Markdown, Upload components

### Updated
- [#693](https://github.com/plotly/dash-core-components/pull/693) Upgraded plotly.js to 1.51.1
- [Feature release 1.51.0](https://github.com/plotly/plotly.js/releases/tag/v1.51.0) which contains:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,37 @@

_this_module = _sys.modules[__name__]

_js_dist = [
async_resources = [
'datepicker',
'dropdown',
'graph',
'markdown',
'upload'
]

_js_dist = []

_js_dist.extend([{
'relative_package_path': 'async~{}.js'.format(async_resource),
'external_url': (
'https://unpkg.com/dash-core-components@{}'
'/dash_core_components/async~{}.js'
).format(__version__, async_resource),
'namespace': 'dash_core_components',
'async': True
} for async_resource in async_resources])

_js_dist.extend([{
'relative_package_path': 'async~{}.js.map'.format(async_resource),
'external_url': (
'https://unpkg.com/dash-core-components@{}'
'/dash_core_components/async~{}.js.map'
).format(__version__, async_resource),
'namespace': 'dash_core_components',
'dynamic': True
} for async_resource in async_resources])

_js_dist.extend([
{
'relative_package_path': 'highlight.pack.js',
'namespace': 'dash_core_components'
Expand Down Expand Up @@ -106,7 +136,7 @@
'namespace': 'dash_core_components',
'dynamic': True
},
]
])

for _component in __all__:
setattr(locals()[_component], '_js_dist', _js_dist)
182 changes: 9 additions & 173 deletions packages/dash-core-components/src/components/DatePickerRange.react.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import 'react-dates/initialize';
import {DateRangePicker} from 'react-dates';
import PropTypes from 'prop-types';
import React, {Component} from 'react';
import uniqid from 'uniqid';
import React, {Component, lazy, Suspense} from 'react';
import LazyLoader from '../utils/LazyLoader';

import convertToMoment from '../utils/convertToMoment';
const RealDatePickerRange = lazy(LazyLoader.datePickerRange);

/**
* DatePickerRange is a tailor made component designed for selecting
Expand All @@ -18,176 +16,11 @@ import convertToMoment from '../utils/convertToMoment';
* which can be found here: https://github.com/airbnb/react-dates
*/
export default class DatePickerRange extends Component {
constructor(props) {
super(props);
this.propsToState = this.propsToState.bind(this);
this.onDatesChange = this.onDatesChange.bind(this);
this.isOutsideRange = this.isOutsideRange.bind(this);
this.state = {
focused: false,
start_date_id: props.start_date_id || uniqid(),
end_date_id: props.end_date_id || uniqid(),
};
}

propsToState(newProps) {
this.setState({
start_date: newProps.start_date,
end_date: newProps.end_date,
});
}

componentWillReceiveProps(newProps) {
this.propsToState(newProps);
}

componentWillMount() {
this.propsToState(this.props);
}

onDatesChange({startDate: start_date, endDate: end_date}) {
const {setProps, updatemode, clearable} = this.props;

const oldMomentDates = convertToMoment(this.state, [
'start_date',
'end_date',
]);

if (start_date && !start_date.isSame(oldMomentDates.start_date)) {
if (updatemode === 'singledate') {
setProps({start_date: start_date.format('YYYY-MM-DD')});
} else {
this.setState({start_date: start_date.format('YYYY-MM-DD')});
}
}

if (end_date && !end_date.isSame(oldMomentDates.end_date)) {
if (updatemode === 'singledate') {
setProps({end_date: end_date.format('YYYY-MM-DD')});
} else if (updatemode === 'bothdates') {
setProps({
start_date: this.state.start_date,
end_date: end_date.format('YYYY-MM-DD'),
});
}
}

if (
clearable &&
!start_date &&
!end_date &&
(oldMomentDates.start_date !== start_date ||
oldMomentDates.end_date !== end_date)
) {
setProps({start_date: null, end_date: null});
}
}

isOutsideRange(date) {
const {min_date_allowed, max_date_allowed} = this.props;

return (
(min_date_allowed && date.isBefore(min_date_allowed)) ||
(max_date_allowed && date.isAfter(max_date_allowed))
);
}

render() {
const {focusedInput} = this.state;

const {
calendar_orientation,
clearable,
day_size,
disabled,
display_format,
end_date_placeholder_text,
first_day_of_week,
is_RTL,
minimum_nights,
month_format,
number_of_months_shown,
reopen_calendar_on_clear,
show_outside_days,
start_date_placeholder_text,
stay_open_on_select,
with_full_screen_portal,
with_portal,
loading_state,
id,
style,
className,
start_date_id,
end_date_id,
} = this.props;

const {initial_visible_month} = convertToMoment(this.props, [
'initial_visible_month',
]);

const {start_date, end_date} = convertToMoment(this.state, [
'start_date',
'end_date',
]);
const verticalFlag = calendar_orientation !== 'vertical';

const DatePickerWrapperStyles = {
position: 'relative',
display: 'inline-block',
...style,
};

return (
<div
id={id}
style={DatePickerWrapperStyles}
className={className}
data-dash-is-loading={
(loading_state && loading_state.is_loading) || undefined
}
>
<DateRangePicker
daySize={day_size}
disabled={disabled}
displayFormat={display_format}
enableOutsideDays={show_outside_days}
endDate={end_date}
endDatePlaceholderText={end_date_placeholder_text}
firstDayOfWeek={first_day_of_week}
focusedInput={focusedInput}
initialVisibleMonth={() => {
if (initial_visible_month) {
return initial_visible_month;
} else if (end_date && focusedInput === 'endDate') {
return end_date;
} else if (start_date && focusedInput === 'startDate') {
return start_date;
}
return start_date;
}}
isOutsideRange={this.isOutsideRange}
isRTL={is_RTL}
keepOpenOnDateSelect={stay_open_on_select}
minimumNights={minimum_nights}
monthFormat={month_format}
numberOfMonths={number_of_months_shown}
onDatesChange={this.onDatesChange}
onFocusChange={focusedInput =>
this.setState({focusedInput})
}
orientation={calendar_orientation}
reopenPickerOnClearDates={reopen_calendar_on_clear}
showClearDates={clearable}
startDate={start_date}
startDatePlaceholderText={start_date_placeholder_text}
withFullScreenPortal={
with_full_screen_portal && verticalFlag
}
withPortal={with_portal && verticalFlag}
startDateId={start_date_id || this.state.start_date_id}
endDateId={end_date_id || this.state.end_date_id}
/>
</div>
<Suspense fallback={null}>
<RealDatePickerRange {...this.props} />
</Suspense>
);
}
}
Expand Down Expand Up @@ -446,3 +279,6 @@ DatePickerRange.defaultProps = {
persisted_props: ['start_date', 'end_date'],
persistence_type: 'local',
};

export const propTypes = DatePickerRange.propTypes;
export const defaultProps = DatePickerRange.defaultProps;
114 changes: 9 additions & 105 deletions packages/dash-core-components/src/components/DatePickerSingle.react.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import 'react-dates/initialize';

import {SingleDatePicker} from 'react-dates';
import moment from 'moment';
import PropTypes from 'prop-types';
import React, {Component} from 'react';
import React, {Component, lazy, Suspense} from 'react';
import LazyLoader from '../utils/LazyLoader';

import convertToMoment from '../utils/convertToMoment';
const RealDateSingleRange = lazy(LazyLoader.datePickerSingle);

/**
* DatePickerSingle is a tailor made component designed for selecting
Expand All @@ -18,108 +15,12 @@ import convertToMoment from '../utils/convertToMoment';
* This component is based off of Airbnb's react-dates react component
* which can be found here: https://github.com/airbnb/react-dates
*/

export default class DatePickerSingle extends Component {
constructor() {
super();
this.isOutsideRange = this.isOutsideRange.bind(this);
this.onDateChange = this.onDateChange.bind(this);
this.state = {focused: false};
}

isOutsideRange(date) {
const {max_date_allowed, min_date_allowed} = convertToMoment(
this.props,
['max_date_allowed', 'min_date_allowed']
);

return (
(min_date_allowed && date.isBefore(min_date_allowed)) ||
(max_date_allowed && date.isAfter(max_date_allowed))
);
}

onDateChange(date) {
const {setProps} = this.props;
const payload = {date: date ? date.format('YYYY-MM-DD') : null};
setProps(payload);
}

render() {
const {focused} = this.state;

const {
calendar_orientation,
clearable,
day_size,
disabled,
display_format,
first_day_of_week,
is_RTL,
month_format,
number_of_months_shown,
placeholder,
reopen_calendar_on_clear,
show_outside_days,
stay_open_on_select,
with_full_screen_portal,
with_portal,
loading_state,
id,
style,
className,
} = this.props;

const {date, initial_visible_month} = convertToMoment(this.props, [
'date',
'initial_visible_month',
]);

const verticalFlag = calendar_orientation !== 'vertical';

const DatePickerWrapperStyles = {
position: 'relative',
display: 'inline-block',
...style,
};

return (
<div
id={id}
style={DatePickerWrapperStyles}
className={className}
data-dash-is-loading={
(loading_state && loading_state.is_loading) || undefined
}
>
<SingleDatePicker
date={date}
onDateChange={this.onDateChange}
focused={focused}
onFocusChange={({focused}) => this.setState({focused})}
initialVisibleMonth={() =>
date || initial_visible_month || moment()
}
isOutsideRange={this.isOutsideRange}
numberOfMonths={number_of_months_shown}
withPortal={with_portal && verticalFlag}
withFullScreenPortal={
with_full_screen_portal && verticalFlag
}
firstDayOfWeek={first_day_of_week}
enableOutsideDays={show_outside_days}
monthFormat={month_format}
displayFormat={display_format}
placeholder={placeholder}
showClearDate={clearable}
disabled={disabled}
keepOpenOnDateSelect={stay_open_on_select}
reopenPickerOnClearDate={reopen_calendar_on_clear}
isRTL={is_RTL}
orientation={calendar_orientation}
daySize={day_size}
/>
</div>
<Suspense fallback={null}>
<RealDateSingleRange {...this.props} />
</Suspense>
);
}
}
Expand Down Expand Up @@ -335,3 +236,6 @@ DatePickerSingle.defaultProps = {
persisted_props: ['date'],
persistence_type: 'local',
};

export const propTypes = DatePickerSingle.propTypes;
export const defaultProps = DatePickerSingle.defaultProps;
Loading

0 comments on commit 5b7023e

Please sign in to comment.