diff --git a/components/autocomplete/theme.css b/components/autocomplete/theme.css
index 543bf82..50fdb93 100644
--- a/components/autocomplete/theme.css
+++ b/components/autocomplete/theme.css
@@ -3,7 +3,6 @@
@import './config.css';
.menu {
- box-shadow: 0 1px 6px rgba(0,0,0,.2);
border-radius: 4px;
z-index: 1050;
float: left;
@@ -15,8 +14,7 @@
color: rgba(0,0,0,.65);
background: #fff;
overflow: hidden;
- min-width: 120px;
- position: absolute;
+ width: 100%;
}
.menuItem {
diff --git a/components/date_select/DateRangeSelect.js b/components/date_select/DateRangeSelect.js
new file mode 100644
index 0000000..b3671f9
--- /dev/null
+++ b/components/date_select/DateRangeSelect.js
@@ -0,0 +1,147 @@
+import React, { Component, PropTypes } from 'react';
+import theme from './theme.css';
+import moment from 'moment';
+import allRanges from './ranges.js';
+import pick from 'ramda/src/pick';
+
+const popupAlign = {
+ points: ['tl', 'bl'],
+ offset: [0, 10],
+};
+
+const factory = (Trigger, SelectInput, DateRange) => {
+ class DateRangeSelect extends Component {
+
+ static propTypes = {
+ startDate: PropTypes.object,
+ endDate: PropTypes.object,
+ minDate: PropTypes.object,
+ maxDate: PropTypes.object,
+ onChange: PropTypes.func,
+ ranges: PropTypes.arrayOf(
+ PropTypes.oneOf(['今日', '昨日', '近7日', '近30天', '近三个月', '近一年'])
+ ),
+ theme: PropTypes.shape({
+ DaySelected: PropTypes.object,
+ DayInRange: PropTypes.object,
+ })
+ }
+
+ static defaultProps = {
+ minDate: moment('2016-03-01'),
+ maxDate: moment(),
+ ranges: ['今日', '昨日', '近7日', '近30天', '近三个月', '近一年'],
+ onChange: () => void 0,
+ }
+
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ ranges: pick(props.ranges, allRanges),
+ startDate: 'startDate' in props ? props.startDate : moment(),
+ endDate: 'endDate' in props ? props.endDate : moment(),
+ open: false,
+ };
+
+ this.defaultTheme = {
+ DaySelected: {
+ background: theme.DaySelected_background,
+ },
+ DayInRange: {
+ background: theme.DayInRange_background,
+ color: theme.DayInRange_color,
+ },
+ };
+ }
+
+ componentWillReceiveProps(nextProps) {
+ if ('startDate' in nextProps) {
+ this.setState({ startDate: nextProps.startDate });
+ }
+
+ if ('endDate' in nextProps) {
+ this.setState({ date: nextProps.endDate });
+ }
+
+ if (nextProps.ranges !== this.props.ranges) {
+ this.setState({ ranges: pick(nextProps.ranges, allRanges) })
+ }
+ }
+
+ handleSelectToggle = () => {
+ this.setState({ open: !this.state.open });
+ }
+
+ handleRangeSelect = ({ startDate, endDate }) => {
+ const props = this.props;
+
+ if (!('startDate' in props)) {
+ this.setState({ startDate });
+ }
+
+ if (!('endDate' in this.props)) {
+ this.setState({ endDate });
+ }
+
+ this.handleSelectToggle();
+ props.onChange(startDate, endDate);
+ }
+
+ getDateRange = () => {
+ const {
+ theme,
+ minDate,
+ maxDate,
+ } = this.props;
+
+ const {
+ ranges,
+ startDate,
+ endDate,
+ } = this.state;
+
+ return (
+
+ );
+ }
+
+ render() {
+ const {
+ open,
+ startDate,
+ endDate,
+ } = this.state;
+
+ const dateRange = this.getDateRange();
+ const selectedItem = {label: startDate.format('YYYY年MM月D日') + '~' + endDate.format('YYYY年MM月D日')};
+
+ return (
+
+
+
+ );
+ }
+ }
+
+ return DateRangeSelect;
+};
+
+export {factory as dateRangeSelectFactory};
diff --git a/components/date_select/DateSelect.js b/components/date_select/DateSelect.js
new file mode 100644
index 0000000..5690892
--- /dev/null
+++ b/components/date_select/DateSelect.js
@@ -0,0 +1,104 @@
+import React, { Component, PropTypes } from 'react';
+import theme from './theme.css';
+import moment from 'moment';
+
+const popupAlign = {
+ points: ['tl', 'bl'],
+ offset: [0, 10],
+};
+
+const factory = (Trigger, SelectInput, Calendar) => {
+ class DateSelect extends Component {
+
+ static propTypes = {
+ date: PropTypes.object,
+ minDate: PropTypes.object,
+ maxDate: PropTypes.object,
+ onChange: PropTypes.func,
+ theme: PropTypes.shape({
+ DaySelected: PropTypes.object,
+ })
+ }
+
+ static defaultProps = {
+ minDate: moment('2016-03-01'),
+ maxDate: moment(),
+ onChange: () => void 0,
+ }
+
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ date: 'date' in props ? props.date : moment(),
+ open: false,
+ }
+
+ this.defaultTheme = {
+ DaySelected: {
+ background: theme.DaySelected_background
+ }
+ };
+ }
+
+ componentWillReceiveProps(nextProps) {
+ if ('date' in nextProps) {
+ this.setState({ date: nextProps.date });
+ }
+ }
+
+ handleSelectToggle = () => {
+ this.setState({ open: !this.state.open });
+ }
+
+ handleDateSelect = (date) => {
+ this.handleSelectToggle();
+
+ if (!('date' in this.props)) {
+ this.setState({ date });
+ }
+
+ this.props.onChange(date);
+ }
+
+ getCalendar = () => {
+ const {
+ minDate,
+ maxDate,
+ } = this.props;
+
+ return (
+
+ );
+ }
+
+ render() {
+ const state = this.state;
+ const calendar = this.getCalendar();
+ const selectedItem = {label: state.date.format('YYYY年MM月D日')};
+
+ return (
+
+
+
+ );
+ }
+ }
+
+ return DateSelect;
+};
+
+export {factory as dateSelectFactory};
diff --git a/components/date_select/index.js b/components/date_select/index.js
new file mode 100644
index 0000000..35b75ba
--- /dev/null
+++ b/components/date_select/index.js
@@ -0,0 +1,13 @@
+import {dateSelectFactory} from './DateSelect';
+import {dateRangeSelectFactory} from './DateRangeSelect';
+import { Calendar, DateRange } from 'react-date-range';
+
+import Trigger from '../trigger';
+import SelectInput from '../select_input';
+
+const DateSelect = dateSelectFactory(Trigger, SelectInput, Calendar);
+const DateRangeSelect = dateRangeSelectFactory(Trigger, SelectInput, DateRange);
+
+export default DateSelect;
+export { DateSelect };
+export { DateRangeSelect };
diff --git a/components/date_select/ranges.js b/components/date_select/ranges.js
new file mode 100644
index 0000000..7ac0a5a
--- /dev/null
+++ b/components/date_select/ranges.js
@@ -0,0 +1,50 @@
+export default {
+ '今日': {
+ startDate(e) {
+ return e;
+ },
+ endDate(e) {
+ return e;
+ },
+ },
+ '昨日': {
+ startDate(e) {
+ return e.add(-1, 'days');
+ },
+ endDate(e) {
+ return e.add(-1, 'days');
+ },
+ },
+ '近7日': {
+ startDate(e) {
+ return e.add(-7, 'days');
+ },
+ endDate(e) {
+ return e;
+ },
+ },
+ '近30日': {
+ startDate(e) {
+ return e.add(-1, 'months');
+ },
+ endDate(e) {
+ return e;
+ },
+ },
+ '近三个月': {
+ startDate(e) {
+ return e.add(-3, 'months');
+ },
+ endDate(e) {
+ return e;
+ },
+ },
+ '近一年': {
+ startDate(e) {
+ return e.add(-1, 'years');
+ },
+ endDate(e) {
+ return e;
+ },
+ },
+};
diff --git a/components/date_select/theme.css b/components/date_select/theme.css
new file mode 100644
index 0000000..95ea72e
--- /dev/null
+++ b/components/date_select/theme.css
@@ -0,0 +1,8 @@
+@import '../colors.css';
+@import '../variables.css';
+
+:export {
+ DaySelected_background: var(--color-primary);
+ DayInRange_background: var(--palette-cyan-200);
+ DayInRange_color: var(--color-white);
+}
diff --git a/components/identifiers.js b/components/identifiers.js
index b49f376..7dc9fcc 100644
--- a/components/identifiers.js
+++ b/components/identifiers.js
@@ -3,6 +3,7 @@ export const RIPPLE = 'CQRIPPLE';
export const ICON = 'CQICON';
export const SELECT = 'CQSELECT';
export const SELECT_INPUT = 'CQSELECTINPUT';
+export const DATESELECT = 'CQDATESELECT';
export const MENU = 'CQMENU';
export const POPUP = 'CQPOPUP';
export const OVERLAY = 'CQOVERLAY';
diff --git a/components/popup/popup.js b/components/popup/popup.js
index 3bd0e68..5f91cbe 100644
--- a/components/popup/popup.js
+++ b/components/popup/popup.js
@@ -98,8 +98,6 @@ class Popup extends React.Component {
const {children, theme, active, onMouseEnter, onMouseLeave} = this.props;
const newProps = {
- key: 'popup',
- ref: 'popup',
onMouseEnter,
onMouseLeave,
};
@@ -107,7 +105,7 @@ class Popup extends React.Component {
const classes = classnames(theme.popup, {
[theme.active]: active});
- return
{React.cloneElement(children, newProps)}
;
+ return {React.cloneElement(children, newProps)}
;
}
getPopupDomNode = () => {
diff --git a/components/popup/theme.css b/components/popup/theme.css
index 54dc2b9..cfc7018 100644
--- a/components/popup/theme.css
+++ b/components/popup/theme.css
@@ -4,6 +4,8 @@
opacity: 0.01;
transform: translate(0, 10px);
opacity: 0;
+ position: absolute;
+ box-shadow: 0 1px 6px rgba(0,0,0,.2);
transition:
opacity var(--animation-duration) var(--animation-curve-default),
transform var(--animation-duration) var(--animation-curve-default);
diff --git a/components/select/Select.js b/components/select/Select.js
index 3cdafb5..02ea16c 100644
--- a/components/select/Select.js
+++ b/components/select/Select.js
@@ -62,7 +62,10 @@ const factory = (Trigger, SelectInput, Menu, MenuItem) => {
handleMenuItemClick = item => () => {
this.handleSelectToggle();
- this.setState({ value: item.value });
+ if (!('value' in this.props)) {
+ this.setState({ value: item.value });
+ }
+
this.props.onChange(item);
}
diff --git a/components/select/theme.css b/components/select/theme.css
index 7ba7b94..fd0c257 100644
--- a/components/select/theme.css
+++ b/components/select/theme.css
@@ -3,7 +3,6 @@
@import './config.css';
.menu {
- box-shadow: 0 1px 6px rgba(0,0,0,.2);
border-radius: 4px;
z-index: 1050;
float: left;
@@ -15,7 +14,7 @@
color: rgba(0,0,0,.65);
background: #fff;
overflow: hidden;
- position: absolute;
+ width: 100%;
}
.menuItem {
diff --git a/components/tooltip/theme.css b/components/tooltip/theme.css
index 0349f6e..a90eb4e 100644
--- a/components/tooltip/theme.css
+++ b/components/tooltip/theme.css
@@ -9,7 +9,6 @@
line-height: var(--font-size-small);
max-width: var(--tooltip-max-width);
padding: var(--tooltip-margin);
- position: absolute;
text-align: center;
z-index: var(--z-index-higher);
@@ -105,6 +104,7 @@
.popup {
opacity: 0;
+ box-shadow: none;
transform: translate(0, 0);
transition:
opacity var(--animation-duration) var(--animation-curve-default);
diff --git a/docs/index.html b/docs/index.html
index 7a69697..6b698d3 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -10,6 +10,6 @@
-
+