Socket
Socket
Sign inDemoInstall

@r365/react-calendar-timeline

Package Overview
Dependencies
30
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.25.0-drag.3 to 0.26.0-alpha.0

55

CHANGELOG.md

@@ -10,2 +10,57 @@ # Change Log

## 0.23.0
- improve unit tests coverage #426 - @ilaiwi
- stack items by group #384 - @acemac
- fix bug where `canMove` prop gets ignored #484 - @acemac + @ilaiwi
- fix sidebar re-render when groupHeights do not change #478 - @SDupZ
### Stack per group
now you can stack choose to stack items in individual groups by providing the property `stackItems` in group object. The property in group overrides the timeline prop `stackItems`.
```
const groups = [{ id: 1, title: 'group 1', stackItems: false }, { id: 2, title: 'group 2', stackItems: true }]
const items = [
{
id: 1,
group: 1,
title: 'item 1',
start_time: moment(),
end_time: moment().add(1, 'hour')
},
{
id: 2,
group: 2,
title: 'item 2',
start_time: moment().add(-0.5, 'hour'),
end_time: moment().add(0.5, 'hour')
},
{
id: 3,
group: 1,
title: 'item 3',
start_time: moment().add(2, 'hour'),
end_time: moment().add(3, 'hour')
}
]
ReactDOM.render(
<div>
Rendered by react!
<Timeline
groups={groups}
items={items}
defaultTimeStart={moment().add(-12, 'hour')}
defaultTimeEnd={moment().add(12, 'hour')}
/>
</div>,
document.getElementById('root')
)
```
## 0.22.0
### Fixed

@@ -12,0 +67,0 @@

@@ -98,2 +98,14 @@ 'use strict';

var _calendar = require('./lib/utility/calendar');
Object.keys(_calendar).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
return _calendar[key];
}
});
});
var _Timeline = require('./lib/Timeline');

@@ -100,0 +112,0 @@

60

lib/lib/columns/Columns.js

@@ -7,2 +7,4 @@ 'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

@@ -20,4 +22,8 @@

var _TimelineStateContext = require('../timeline/TimelineStateContext');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

@@ -29,2 +35,13 @@

var passThroughPropTypes = {
canvasTimeStart: _propTypes2.default.number.isRequired,
canvasTimeEnd: _propTypes2.default.number.isRequired,
canvasWidth: _propTypes2.default.number.isRequired,
lineCount: _propTypes2.default.number.isRequired,
minUnit: _propTypes2.default.string.isRequired,
timeSteps: _propTypes2.default.object.isRequired,
height: _propTypes2.default.number.isRequired,
verticalLineClassNamesForTime: _propTypes2.default.func
};
var Columns = function (_Component) {

@@ -54,3 +71,4 @@ _inherits(Columns, _Component);

height = _props.height,
verticalLineClassNamesForTime = _props.verticalLineClassNamesForTime;
verticalLineClassNamesForTime = _props.verticalLineClassNamesForTime,
getLeftOffsetFromDate = _props.getLeftOffsetFromDate;

@@ -62,8 +80,4 @@ var ratio = canvasWidth / (canvasTimeEnd - canvasTimeStart);

(0, _calendar.iterateTimes)(canvasTimeStart, canvasTimeEnd, minUnit, timeSteps, function (time, nextTime) {
var left = Math.round((time.valueOf() - canvasTimeStart) * ratio, -2);
var minUnitValue = time.get(minUnit === 'day' ? 'date' : minUnit);
var firstOfType = minUnitValue === (minUnit === 'day' ? 1 : 0);
var lineWidth = firstOfType ? 2 : 1;
var labelWidth = Math.ceil((nextTime.valueOf() - time.valueOf()) * ratio) - lineWidth;
var leftPush = firstOfType ? -1 : 0;

@@ -79,2 +93,4 @@ var classNamesForTime = [];

var left = getLeftOffsetFromDate(time.valueOf());
var right = getLeftOffsetFromDate(nextTime.valueOf());
lines.push(_react2.default.createElement('div', {

@@ -86,4 +102,4 @@ key: 'line-' + time.valueOf(),

top: '0px',
left: left + leftPush + 'px',
width: labelWidth + 'px',
left: left + 'px',
width: right - left + 'px',
height: height + 'px'

@@ -105,12 +121,22 @@ }

Columns.propTypes = {
canvasTimeStart: _propTypes2.default.number.isRequired,
canvasTimeEnd: _propTypes2.default.number.isRequired,
canvasWidth: _propTypes2.default.number.isRequired,
lineCount: _propTypes2.default.number.isRequired,
minUnit: _propTypes2.default.string.isRequired,
timeSteps: _propTypes2.default.object.isRequired,
height: _propTypes2.default.number.isRequired,
verticalLineClassNamesForTime: _propTypes2.default.func
Columns.propTypes = _extends({}, passThroughPropTypes, {
getLeftOffsetFromDate: _propTypes2.default.func.isRequired
});
var ColumnsWrapper = function ColumnsWrapper(_ref) {
var props = _objectWithoutProperties(_ref, []);
return _react2.default.createElement(
_TimelineStateContext.TimelineStateConsumer,
null,
function (_ref2) {
var getLeftOffsetFromDate = _ref2.getLeftOffsetFromDate;
return _react2.default.createElement(Columns, _extends({ getLeftOffsetFromDate: getLeftOffsetFromDate }, props));
}
);
};
exports.default = Columns;
ColumnsWrapper.defaultProps = _extends({}, passThroughPropTypes);
exports.default = ColumnsWrapper;

@@ -49,5 +49,6 @@ 'use strict';

timeSteps = props.timeSteps,
showPeriod = props.showPeriod;
showPeriod = props.showPeriod,
getLeftOffsetFromDate = props.getLeftOffsetFromDate;
var ratio = _this.calculateRatio(canvasWidth, canvasTimeEnd, canvasTimeStart);
var intervals = _this.getHeaderIntervals({

@@ -60,8 +61,7 @@ canvasTimeStart: canvasTimeStart,

showPeriod: showPeriod,
ratio: ratio
getLeftOffsetFromDate: getLeftOffsetFromDate
});
_this.state = {
intervals: intervals,
ratio: ratio
intervals: intervals
};

@@ -74,3 +74,3 @@ return _this;

value: function shouldComponentUpdate(nextProps) {
if (nextProps.canvasTimeStart !== this.props.canvasTimeStart || nextProps.canvasTimeEnd !== this.props.canvasTimeEnd || nextProps.canvasWidth !== this.props.canvasWidth || nextProps.unit !== this.props.unit || nextProps.timeSteps !== this.props.timeSteps || nextProps.showPeriod !== this.props.showPeriod || nextProps.children !== this.props.children) {
if (nextProps.canvasTimeStart !== this.props.canvasTimeStart || nextProps.canvasTimeEnd !== this.props.canvasTimeEnd || nextProps.canvasWidth !== this.props.canvasWidth || nextProps.unit !== this.props.unit || nextProps.timeSteps !== this.props.timeSteps || nextProps.showPeriod !== this.props.showPeriod || nextProps.children !== this.props.children || nextProps.headerData !== this.props.headerData) {
return true;

@@ -89,5 +89,6 @@ }

timeSteps = nextProps.timeSteps,
showPeriod = nextProps.showPeriod;
showPeriod = nextProps.showPeriod,
getLeftOffsetFromDate = nextProps.getLeftOffsetFromDate;
var ratio = this.calculateRatio(canvasWidth, canvasTimeEnd, canvasTimeStart);
var intervals = this.getHeaderIntervals({

@@ -100,18 +101,14 @@ canvasTimeStart: canvasTimeStart,

showPeriod: showPeriod,
ratio: ratio
getLeftOffsetFromDate: getLeftOffsetFromDate
});
this.setState({ intervals: intervals, ratio: ratio });
this.setState({ intervals: intervals });
}
}
}, {
key: 'calculateRatio',
value: function calculateRatio(canvasWidth, canvasTimeEnd, canvasTimeStart) {
return canvasWidth / (canvasTimeEnd - canvasTimeStart);
}
}, {
key: 'render',
value: function render() {
var props = this.getStateAndHelpers();
return this.props.children(props, this.props.props);
var Renderer = this.props.children;
return _react2.default.createElement(Renderer, props);
}

@@ -127,4 +124,4 @@ }]);

unit: _propTypes2.default.string.isRequired,
//Timeline context
timeSteps: _propTypes2.default.object.isRequired,
//Timeline context
visibleTimeStart: _propTypes2.default.number.isRequired,

@@ -136,3 +133,5 @@ visibleTimeEnd: _propTypes2.default.number.isRequired,

showPeriod: _propTypes2.default.func.isRequired,
props: _propTypes2.default.object
headerData: _propTypes2.default.object,
getLeftOffsetFromDate: _propTypes2.default.func.isRequired,
height: _propTypes2.default.number.isRequired
};

@@ -148,11 +147,14 @@

timeSteps = _ref4.timeSteps,
ratio = _ref4.ratio;
getLeftOffsetFromDate = _ref4.getLeftOffsetFromDate;
var intervals = [];
(0, _calendar.iterateTimes)(canvasTimeStart, canvasTimeEnd, unit, timeSteps, function (startTime, endTime) {
var labelWidth = Math.ceil((endTime.valueOf() - startTime.valueOf()) * ratio);
var left = getLeftOffsetFromDate(startTime.valueOf());
var right = getLeftOffsetFromDate(endTime.valueOf());
var width = right - left;
intervals.push({
startTime: startTime,
endTime: endTime,
labelWidth: labelWidth
labelWidth: width,
left: left
});

@@ -163,8 +165,2 @@ });

this.rootProps = {
style: {
position: 'relative'
}
};
this.getRootProps = function () {

@@ -175,3 +171,7 @@ var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

return {
style: Object.assign({}, style ? style : {}, _this2.rootProps.style)
style: Object.assign({}, style ? style : {}, {
position: 'relative',
width: _this2.props.canvasWidth,
height: _this2.props.height
})
};

@@ -185,5 +185,6 @@ };

if (!interval) throw new Error("you should provide interval to the prop getter");
if (!interval) throw new Error('you should provide interval to the prop getter');
var startTime = interval.startTime,
labelWidth = interval.labelWidth;
labelWidth = interval.labelWidth,
left = interval.left;

@@ -197,3 +198,3 @@ return {

unit: _this2.props.unit,
ratio: _this2.state.ratio
left: left
}),

@@ -205,15 +206,8 @@ key: 'label-' + startTime.valueOf()

this.getIntervalStyle = function (_ref5) {
var startTime = _ref5.startTime,
canvasTimeStart = _ref5.canvasTimeStart,
ratio = _ref5.ratio,
unit = _ref5.unit,
var left = _ref5.left,
labelWidth = _ref5.labelWidth,
style = _ref5.style;
var left = Math.round((startTime.valueOf() - canvasTimeStart) * ratio);
var unitValue = startTime.get(unit === 'day' ? 'date' : unit);
var firstOfType = unitValue === (unit === 'day' ? 1 : 0);
var leftCorrect = firstOfType ? 1 : 0;
return _extends({}, style, {
left: left - leftCorrect,
left: left,
width: labelWidth,

@@ -232,3 +226,4 @@ position: 'absolute'

visibleTimeStart = _props.visibleTimeStart,
visibleTimeEnd = _props.visibleTimeEnd;
visibleTimeEnd = _props.visibleTimeEnd,
headerData = _props.headerData;
//TODO: only evaluate on changing params

@@ -250,3 +245,4 @@

getIntervalProps: _this2.getIntervalProps,
showPeriod: showPeriod
showPeriod: showPeriod,
data: headerData
};

@@ -259,3 +255,4 @@ };

unit = _ref.unit,
props = _ref.props;
headerData = _ref.headerData,
height = _ref.height;
return _react2.default.createElement(

@@ -266,3 +263,4 @@ _TimelineStateContext.TimelineStateConsumer,

var getTimelineState = _ref2.getTimelineState,
showPeriod = _ref2.showPeriod;
showPeriod = _ref2.showPeriod,
getLeftOffsetFromDate = _ref2.getLeftOffsetFromDate;

@@ -281,3 +279,5 @@ var timelineState = getTimelineState();

}, timelineState, {
props: props
headerData: headerData,
getLeftOffsetFromDate: getLeftOffsetFromDate,
height: height
}));

@@ -293,5 +293,10 @@ }

unit: _propTypes2.default.string,
props: _propTypes2.default.object
headerData: _propTypes2.default.object,
height: _propTypes2.default.number
};
CustomHeaderWrapper.defaultProps = {
height: 30
};
exports.default = CustomHeaderWrapper;

@@ -9,4 +9,2 @@ 'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

@@ -61,9 +59,8 @@

return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = DateHeader.__proto__ || Object.getPrototypeOf(DateHeader)).call.apply(_ref, [this].concat(args))), _this), _this.getHeaderUnit = function () {
if (_this.props.unit) {
if (_this.props.unit === 'primaryHeader') {
return (0, _calendar.getNextUnit)(_this.props.timelineUnit);
} else if (_this.props.unit) {
return _this.props.unit;
} else if (_this.props.primaryHeader) {
return (0, _calendar.getNextUnit)(_this.props.timelineUnit);
} else {
return _this.props.timelineUnit;
}
return _this.props.timelineUnit;
}, _this.getRootStyle = function () {

@@ -77,2 +74,16 @@ return _extends({

_createClass(DateHeader, [{
key: 'getLabelFormat',
value: function getLabelFormat(interval, unit, labelWidth) {
var labelFormat = this.props.labelFormat;
if (typeof labelFormat === 'string') {
var startTime = interval[0];
return startTime.format(labelFormat);
} else if (typeof labelFormat === 'function') {
return labelFormat(interval, unit, labelWidth);
} else {
throw new Error('labelFormat should be function or string');
}
}
}, {
key: 'render',

@@ -83,12 +94,15 @@ value: function render() {

var unit = this.getHeaderUnit();
var props = this.props.props;
var _props = this.props,
headerData = _props.headerData,
height = _props.height;
return _react2.default.createElement(
_CustomHeader2.default,
{ unit: unit, props: props },
function (_ref2, props) {
{ unit: unit, height: height, headerData: headerData },
function (_ref2) {
var intervals = _ref2.headerContext.intervals,
getRootProps = _ref2.getRootProps,
getIntervalProps = _ref2.getIntervalProps,
showPeriod = _ref2.showPeriod;
showPeriod = _ref2.showPeriod,
data = _ref2.data;

@@ -110,7 +124,6 @@ var unit = _this2.getHeaderUnit();

intervalText: intervalText,
primaryHeader: !!_this2.props.primaryHeader,
secondaryHeader: !!_this2.props.secondaryHeader,
primaryHeader: _this2.props.unit === 'primaryHeader',
getIntervalProps: getIntervalProps,
intervalRenderer: _this2.props.intervalRenderer,
props: props
headerData: data
});

@@ -122,18 +135,2 @@ })

}
}, {
key: 'getLabelFormat',
value: function getLabelFormat(interval, unit, labelWidth) {
var labelFormat = this.props.labelFormat;
if (typeof labelFormat === 'string') {
var startTime = interval[0];
return startTime.format(labelFormat);
} else if ((typeof labelFormat === 'undefined' ? 'undefined' : _typeof(labelFormat)) === 'object') {
return formatLabel(interval, unit, labelWidth, labelFormat);
} else if (typeof labelFormat === 'function') {
return labelFormat(interval, unit, labelWidth);
} else {
throw new Error('labelFormat should be function, object or string');
}
}
}]);

@@ -145,4 +142,2 @@

DateHeader.propTypes = {
primaryHeader: _propTypes2.default.bool,
secondaryHeader: _propTypes2.default.bool,
unit: _propTypes2.default.string,

@@ -154,3 +149,4 @@ style: _propTypes2.default.object,

intervalRenderer: _propTypes2.default.func,
props: _propTypes2.default.object
headerData: _propTypes2.default.object,
height: _propTypes2.default.number
};

@@ -160,5 +156,3 @@

var DateHeaderWrapper = function DateHeaderWrapper(_ref3) {
var primaryHeader = _ref3.primaryHeader,
secondaryHeader = _ref3.secondaryHeader,
unit = _ref3.unit,
var unit = _ref3.unit,
labelFormat = _ref3.labelFormat,

@@ -168,3 +162,4 @@ style = _ref3.style,

intervalRenderer = _ref3.intervalRenderer,
props = _ref3.props;
headerData = _ref3.headerData,
height = _ref3.height;
return _react2.default.createElement(

@@ -179,4 +174,2 @@ _TimelineStateContext.TimelineStateConsumer,

timelineUnit: timelineState.timelineUnit,
primaryHeader: primaryHeader,
secondaryHeader: secondaryHeader,
unit: unit,

@@ -187,3 +180,4 @@ labelFormat: labelFormat,

intervalRenderer: intervalRenderer,
props: props
headerData: headerData,
height: height
});

@@ -197,12 +191,10 @@ }

className: _propTypes2.default.string,
primaryHeader: _propTypes2.default.bool,
secondaryHeader: _propTypes2.default.bool,
unit: _propTypes2.default.string,
labelFormat: _propTypes2.default.oneOfType([_propTypes2.default.func, _propTypes2.default.objectOf(_propTypes2.default.objectOf(_propTypes2.default.string)), _propTypes2.default.string]),
intervalRenderer: _propTypes2.default.func,
props: _propTypes2.default.object
headerData: _propTypes2.default.object,
height: _propTypes2.default.number
};
DateHeaderWrapper.defaultProps = {
secondaryHeader: true,
labelFormat: formatLabel

@@ -209,0 +201,0 @@ };

@@ -24,6 +24,2 @@ 'use strict';

var _constants = require('./constants');
var _calendar = require('../utility/calendar');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -30,0 +26,0 @@

@@ -45,17 +45,3 @@ 'use strict';

return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Interval.__proto__ || Object.getPrototypeOf(Interval)).call.apply(_ref, [this].concat(args))), _this), _this.getIntervalStyle = function () {
return {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: _this.props.secondaryHeader && !_this.props.primaryHeader ? 'rgb(240, 240, 240)' : 'initial',
height: '100%',
borderLeft: _this.props.primaryHeader ? '1px solid #bbb' : '2px solid #bbb',
borderRight: _this.props.primaryHeader ? '1px solid #bbb' : 'none',
borderBottom: '1px solid #bbb',
color: _this.props.primaryHeader ? '#fff' : 'initial',
cursor: 'pointer',
fontSize: '14px'
};
}, _this.onIntervalClick = function () {
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Interval.__proto__ || Object.getPrototypeOf(Interval)).call.apply(_ref, [this].concat(args))), _this), _this.onIntervalClick = function () {
var _this$props = _this.props,

@@ -93,15 +79,20 @@ primaryHeader = _this$props.primaryHeader,

intervalRenderer = _props.intervalRenderer,
props = _props.props;
headerData = _props.headerData;
if (intervalRenderer) return intervalRenderer({
getIntervalProps: this.getIntervalProps,
intervalContext: {
interval: interval,
intervalText: intervalText
}
}, props);
var Renderer = intervalRenderer;
if (Renderer) {
return _react2.default.createElement(Renderer, {
getIntervalProps: this.getIntervalProps,
intervalContext: {
interval: interval,
intervalText: intervalText
},
data: headerData
});
}
return _react2.default.createElement(
'div',
this.getIntervalProps({
style: this.getIntervalStyle()
_extends({}, this.getIntervalProps({}), {
className: 'rct-dateHeader ' + (this.props.primaryHeader ? 'rct-dateHeader-primary' : '')
}),

@@ -127,6 +118,5 @@ _react2.default.createElement(

primaryHeader: _propTypes2.default.bool.isRequired,
secondaryHeader: _propTypes2.default.bool.isRequired,
getIntervalProps: _propTypes2.default.func.isRequired,
props: _propTypes2.default.object
headerData: _propTypes2.default.object
};
exports.default = Interval;

@@ -51,9 +51,10 @@ 'use strict';

return {
style: _extends({
style: _extends({}, style, {
width: width
}, style)
})
};
}, _this.getStateAndHelpers = function () {
return {
getRootProps: _this.getRootProps
getRootProps: _this.getRootProps,
data: _this.props.headerData
};

@@ -67,3 +68,4 @@ }, _temp), _possibleConstructorReturn(_this, _ret);

var props = this.getStateAndHelpers();
return this.props.children(props, this.props.props);
var Renderer = this.props.children;
return _react2.default.createElement(Renderer, props);
}

@@ -80,3 +82,3 @@ }]);

variant: _propTypes2.default.string,
props: _propTypes2.default.object
headerData: _propTypes2.default.object
};

@@ -88,3 +90,3 @@

variant = _ref2.variant,
props = _ref2.props;
headerData = _ref2.headerData;
return _react2.default.createElement(

@@ -102,3 +104,3 @@ _HeadersContext.TimelineHeadersConsumer,

variant: variant,
props: props
headerData: headerData
});

@@ -112,3 +114,3 @@ }

variant: _propTypes2.default.string,
props: _propTypes2.default.object
headerData: _propTypes2.default.object
};

@@ -115,0 +117,0 @@

@@ -46,8 +46,5 @@ 'use strict';

_this.getRootStyle = function () {
return _extends({
background: '#c52020',
borderBottom: '1px solid #bbb'
}, _this.props.style, {
display: 'flex',
width: 'max-content'
return _extends({}, _this.props.style, {
display: 'flex'
// width: 'max-content'
});

@@ -62,5 +59,3 @@ };

return _extends({
border: '1px solid #bbb'
}, calendarHeaderStyle, {
return _extends({}, calendarHeaderStyle, {
overflow: 'hidden',

@@ -71,2 +66,8 @@ width: _this.props.width

_this.handleRootRef = function (element) {
if (_this.props.headerRef) {
_this.props.headerRef(element);
}
};
return _this;

@@ -85,6 +86,8 @@ }

_react2.default.Children.map(children, function (child) {
if (child.type === _SidebarHeader2.default && child.props.variant === _constants.RIGHT_VARIANT) {
rightSidebarHeader = child;
} else if (child.type === _SidebarHeader2.default && child.props.variant === _constants.LEFT_VARIANT) {
leftSidebarHeader = child;
if (child.type === _SidebarHeader2.default) {
if (child.props.variant === _constants.RIGHT_VARIANT) {
rightSidebarHeader = child;
} else {
leftSidebarHeader = child;
}
} else {

@@ -96,3 +99,8 @@ calendarHeaders.push(child);

'div',
{ style: this.getRootStyle(), className: this.props.className },
{
ref: this.handleRootRef,
style: this.getRootStyle(),
className: 'rct-header-root ' + this.props.className
},
leftSidebarHeader,

@@ -104,3 +112,3 @@ _react2.default.createElement(

style: this.getCalendarHeaderStyle(),
className: this.props.calendarHeaderClassName
className: 'rct-calendar-header ' + this.props.calendarHeaderClassName
},

@@ -125,3 +133,4 @@ calendarHeaders

calendarHeaderClassName: _propTypes2.default.string,
width: _propTypes2.default.number.isRequired
width: _propTypes2.default.number.isRequired,
headerRef: _propTypes2.default.func
};

@@ -173,5 +182,6 @@

calendarHeaderStyle: _propTypes2.default.object,
calendarHeaderClassName: _propTypes2.default.string
calendarHeaderClassName: _propTypes2.default.string,
headerRef: _propTypes2.default.func
};
exports.default = TimelineHeadersWrapper;

@@ -234,3 +234,3 @@ 'use strict';

}).draggable({
enabled: this.props.selected
enabled: this.props.selected && this.canMove()
}).styleCursor(false).on('dragstart', function (e) {

@@ -257,3 +257,3 @@ if (_this2.props.selected) {

if (_this2.props.moveResizeValidator) {
dragTime = _this2.props.moveResizeValidator('move', _this2.props.item, dragTime, undefined, (0, _generic._get)(_this2.props.dimensions.order.group, _this2.props.keys.groupIdKey));
dragTime = _this2.props.moveResizeValidator('move', _this2.props.item, dragTime);
}

@@ -276,3 +276,3 @@

if (_this2.props.moveResizeValidator) {
dragTime = _this2.props.moveResizeValidator('move', _this2.props.item, dragTime, undefined, (0, _generic._get)(_this2.props.dimensions.order.group, _this2.props.keys.groupIdKey));
dragTime = _this2.props.moveResizeValidator('move', _this2.props.item, dragTime);
}

@@ -313,4 +313,3 @@

if (_this2.props.moveResizeValidator) {
console.log(_this2.props.dimensions);
resizeTime = _this2.props.moveResizeValidator('resize', _this2.props.item, resizeTime, resizeEdge, (0, _generic._get)(_this2.props.dimensions.order.group, _this2.props.keys.groupIdKey));
resizeTime = _this2.props.moveResizeValidator('resize', _this2.props.item, resizeTime, resizeEdge);
}

@@ -333,3 +332,3 @@

if (_this2.props.moveResizeValidator) {
resizeTime = _this2.props.moveResizeValidator('resize', _this2.props.item, resizeTime, resizeEdge, (0, _generic._get)(_this2.props.dimensions.order.group, _this2.props.keys.groupIdKey));
resizeTime = _this2.props.moveResizeValidator('resize', _this2.props.item, resizeTime, resizeEdge);
}

@@ -348,3 +347,5 @@

}).on('tap', function (e) {
_this2.actualClick(e, e.pointerType === 'mouse' ? 'click' : 'touch');
if (e.pointerType !== 'mouse') {
_this2.actualClick(e, 'touch');
}
});

@@ -389,8 +390,7 @@

this.cacheDataFromProps(this.props);
var interactMounted = this.state.interactMounted;
var couldDrag = this.props.selected && this.canMove(this.props);
var couldResizeLeft = this.props.selected && this.canResizeLeft(this.props);
var couldResizeRight = this.props.selected && this.canResizeRight(this.props);
var couldDrag = prevProps.selected && this.canMove(prevProps);
var couldResizeLeft = prevProps.selected && this.canResizeLeft(prevProps);
var couldResizeRight = prevProps.selected && this.canResizeRight(prevProps);
var willBeAbleToDrag = this.props.selected && this.canMove(this.props);

@@ -400,24 +400,30 @@ var willBeAbleToResizeLeft = this.props.selected && this.canResizeLeft(this.props);

if (this.props.selected && !interactMounted) {
this.mountInteract();
interactMounted = true;
}
if (!!this.item) {
if (this.props.selected && !interactMounted) {
this.mountInteract();
interactMounted = true;
}
if (interactMounted && (couldResizeLeft !== willBeAbleToResizeLeft || couldResizeRight !== willBeAbleToResizeRight)) {
var leftResize = this.props.useResizeHandle ? this.dragLeft : true;
var rightResize = this.props.useResizeHandle ? this.dragRight : true;
if (interactMounted && (couldResizeLeft !== willBeAbleToResizeLeft || couldResizeRight !== willBeAbleToResizeRight)) {
var leftResize = this.props.useResizeHandle ? this.dragLeft : true;
var rightResize = this.props.useResizeHandle ? this.dragRight : true;
(0, _interactjs2.default)(this.item).resizable({
enabled: willBeAbleToResizeLeft || willBeAbleToResizeRight,
edges: {
top: false,
bottom: false,
left: willBeAbleToResizeLeft && leftResize,
right: willBeAbleToResizeRight && rightResize
}
});
(0, _interactjs2.default)(this.item).resizable({
enabled: willBeAbleToResizeLeft || willBeAbleToResizeRight,
edges: {
top: false,
bottom: false,
left: willBeAbleToResizeLeft && leftResize,
right: willBeAbleToResizeRight && rightResize
}
});
}
if (interactMounted && couldDrag !== willBeAbleToDrag) {
(0, _interactjs2.default)(this.item).draggable({ enabled: willBeAbleToDrag });
}
} else {
interactMounted = false;
}
if (interactMounted && couldDrag !== willBeAbleToDrag) {
(0, _interactjs2.default)(this.item).draggable({ enabled: willBeAbleToDrag });
}
this.setState({
interactMounted: interactMounted
});
}

@@ -536,16 +542,2 @@ }, {

this.onMouseDown = function (e) {
if (!_this3.state.interactMounted) {
e.preventDefault();
_this3.startedClicking = true;
}
};
this.onMouseUp = function (e) {
if (!_this3.state.interactMounted && _this3.startedClicking) {
_this3.startedClicking = false;
_this3.actualClick(e, 'click');
}
};
this.onTouchStart = function (e) {

@@ -603,4 +595,2 @@ if (!_this3.state.interactMounted) {

className: classNames + (' ' + (props.className ? props.className : '')),
onMouseDown: (0, _events.composeEvents)(_this3.onMouseDown, props.onMouseDown),
onMouseUp: (0, _events.composeEvents)(_this3.onMouseUp, props.onMouseUp),
onTouchStart: (0, _events.composeEvents)(_this3.onTouchStart, props.onTouchStart),

@@ -610,3 +600,6 @@ onTouchEnd: (0, _events.composeEvents)(_this3.onTouchEnd, props.onTouchEnd),

onContextMenu: (0, _events.composeEvents)(_this3.handleContextMenu, props.onContextMenu),
style: Object.assign({}, _this3.getItemStyle(props))
style: Object.assign({}, _this3.getItemStyle(props)),
onClick: function onClick(e) {
_this3.actualClick(e, 'click');
}
};

@@ -613,0 +606,0 @@ };

@@ -39,3 +39,3 @@ 'use strict';

value: function shouldComponentUpdate(nextProps) {
return !((0, _generic.arraysEqual)(nextProps.groups, this.props.groups) && nextProps.keys === this.props.keys && nextProps.width === this.props.width && (0, _generic.arraysEqual)(nextProps.groupHeights, this.props.groupHeights) && nextProps.height === this.props.height);
return !(nextProps.keys === this.props.keys && nextProps.width === this.props.width && nextProps.height === this.props.height && (0, _generic.arraysEqual)(nextProps.groups, this.props.groups) && (0, _generic.arraysEqual)(nextProps.groupHeights, this.props.groupHeights));
}

@@ -42,0 +42,0 @@ }, {

@@ -0,0 +0,0 @@ 'use strict';

@@ -0,0 +0,0 @@ 'use strict';

@@ -88,3 +88,3 @@ 'use strict';

markers: state.markers.filter(function (marker) {
return marker !== newMarker;
return marker.id !== newMarker.id;
})

@@ -91,0 +91,0 @@ };

@@ -110,2 +110,6 @@ 'use strict';

_this.getSelected = _this.getSelected.bind(_this);
_this.hasSelectedItem = _this.hasSelectedItem.bind(_this);
_this.isItemSelected = _this.isItemSelected.bind(_this);
var visibleTimeStart = null;

@@ -333,3 +337,3 @@ var visibleTimeEnd = null;

key: 'childrenWithProps',
value: function childrenWithProps(canvasTimeStart, canvasTimeEnd, canvasWidth, dimensionItems, groupHeights, groupTops, height, headerHeight, visibleTimeStart, visibleTimeEnd, minUnit, timeSteps) {
value: function childrenWithProps(canvasTimeStart, canvasTimeEnd, canvasWidth, dimensionItems, groupHeights, groupTops, height, visibleTimeStart, visibleTimeEnd, minUnit, timeSteps) {
if (!this.props.children) {

@@ -356,5 +360,4 @@ return null;

groupTops: groupTops,
selected: this.state.selectedItem && !this.props.selected ? [this.state.selectedItem] : this.props.selected || [],
selected: this.getSelected(),
height: height,
headerHeight: headerHeight,
minUnit: minUnit,

@@ -373,2 +376,21 @@ timeSteps: timeSteps

}, {
key: 'getSelected',
value: function getSelected() {
return this.state.selectedItem && !this.props.selected ? [this.state.selectedItem] : this.props.selected || [];
}
}, {
key: 'hasSelectedItem',
value: function hasSelectedItem() {
if (!Array.isArray(this.props.selected)) return !!this.state.selectedItem;
return this.props.selected.length > 0;
}
}, {
key: 'isItemSelected',
value: function isItemSelected(itemId) {
var selectedItems = this.getSelected();
return selectedItems.some(function (i) {
return i === itemId;
});
}
}, {
key: 'render',

@@ -381,4 +403,2 @@ value: function render() {

groups = _props.groups,
headerLabelGroupHeight = _props.headerLabelGroupHeight,
headerLabelHeight = _props.headerLabelHeight,
sidebarWidth = _props.sidebarWidth,

@@ -406,3 +426,2 @@ rightSidebarWidth = _props.rightSidebarWidth,

var minUnit = (0, _calendar.getMinUnit)(zoom, width, timeSteps);
var headerHeight = headerLabelGroupHeight + headerLabelHeight;

@@ -478,6 +497,6 @@ var isInteractingWithItem = !!draggingItem || !!resizingItem;

this.items(canvasTimeStart, zoom, canvasTimeEnd, canvasWidth, minUnit, dimensionItems, groupHeights, groupTops),
this.columns(canvasTimeStart, canvasTimeEnd, canvasWidth, minUnit, timeSteps, height, headerHeight),
this.columns(canvasTimeStart, canvasTimeEnd, canvasWidth, minUnit, timeSteps, height),
this.rows(canvasWidth, groupHeights, groups),
this.infoLabel(),
this.childrenWithProps(canvasTimeStart, canvasTimeEnd, canvasWidth, dimensionItems, groupHeights, groupTops, height, headerHeight, visibleTimeStart, visibleTimeEnd, minUnit, timeSteps)
this.childrenWithProps(canvasTimeStart, canvasTimeEnd, canvasWidth, dimensionItems, groupHeights, groupTops, height, visibleTimeStart, visibleTimeEnd, minUnit, timeSteps)
)

@@ -535,7 +554,4 @@ ),

minResizeWidth: _propTypes2.default.number,
stickyOffset: _propTypes2.default.number,
stickyHeader: _propTypes2.default.bool,
lineHeight: _propTypes2.default.number,
headerLabelGroupHeight: _propTypes2.default.number,
headerLabelHeight: _propTypes2.default.number,
itemHeightRatio: _propTypes2.default.number,

@@ -554,3 +570,3 @@

stackItems: _propTypes2.default.bool,
stackItems: _propTypes2.default.oneOf([false, 'space', 'lines']),

@@ -655,3 +671,4 @@ traditionalZoom: _propTypes2.default.bool,

children: _propTypes2.default.node,
width: _propTypes2.default.number
width: _propTypes2.default.number,
onUpdateMove: _propTypes2.default.func
};

@@ -663,7 +680,4 @@ ReactCalendarTimeline.defaultProps = {

minResizeWidth: 20,
stickyOffset: 0,
stickyHeader: true,
lineHeight: 30,
headerLabelGroupHeight: 30,
headerLabelHeight: 30,
itemHeightRatio: 0.65,

@@ -729,3 +743,4 @@

selected: null
selected: null,
onUpdateMove: null
};

@@ -851,3 +866,3 @@ ReactCalendarTimeline.childContextTypes = {

this.selectItem = function (item, clickType, e) {
if (_this4.state.selectedItem === item || _this4.props.itemTouchSendsClick && clickType === 'touch') {
if (_this4.isItemSelected(item) || _this4.props.itemTouchSendsClick && clickType === 'touch') {
if (item && _this4.props.onItemClick) {

@@ -928,3 +943,5 @@ var time = _this4.timeFromItemEvent(e);

var keys = _this4.props.keys;
if (_this4.props.onUpdateMove) {
_this4.props.onUpdateMove(item, dragTime, newGroupOrder, 'move');
}
_this4.setState({

@@ -946,2 +963,5 @@ draggingItem: item,

this.resizingItem = function (item, resizeTime, edge) {
if (_this4.props.onUpdateMove) {
_this4.props.onUpdateMove(item, resizeTime, undefined, 'resize', edge);
}
_this4.setState({

@@ -963,3 +983,3 @@ resizingItem: item,

// shouldnt this be handled by the user, as far as when to deselect an item?
if (_this4.state.selectedItem) {
if (_this4.hasSelectedItem()) {
_this4.selectItem(null);

@@ -1017,3 +1037,3 @@ }

_react2.default.createElement(_SidebarHeader2.default, null),
_react2.default.createElement(_DateHeader2.default, { primaryHeader: true }),
_react2.default.createElement(_DateHeader2.default, { unit: 'primaryHeader' }),
_react2.default.createElement(_DateHeader2.default, null),

@@ -1030,2 +1050,2 @@ _this4.props.rightSidebarWidth ? _react2.default.createElement(_SidebarHeader2.default, { variant: 'right' }) : null

exports.default = ReactCalendarTimeline;
exports.default = ReactCalendarTimeline;

@@ -0,0 +0,0 @@ 'use strict';

@@ -24,2 +24,3 @@ 'use strict';

exports.collision = collision;
exports.groupStackInLines = groupStackInLines;
exports.groupStack = groupStack;

@@ -100,3 +101,4 @@ exports.groupNoStack = groupNoStack;

var nextTime = (0, _moment2.default)(time).add(timeSteps[unit] || 1, unit + 's');
callback(time, nextTime);
var endTime = (0, _moment2.default)(time).endOf(unit + 's');
callback(time, endTime);
time = nextTime;

@@ -178,6 +180,9 @@ }

day: 'month',
month: 'year'
month: 'year',
year: 'year'
};
return nextUnits[unit] || '';
if (!nextUnits[unit]) {
throw new Error('unit ' + unit + ' in not acceptable');
}
return nextUnits[unit];
}

@@ -310,2 +315,19 @@

/**
* Calculate the position of a given item for a group that each in a line
* is being stacked
*/
function groupStackInLines(lineHeight, item, items, groupHeight, groupTop, itemIndex) {
// calculate non-overlapping positions
var verticalMargin = lineHeight - item.dimensions.height;
if (item.dimensions.stack && item.dimensions.top === null) {
item.dimensions.top = groupTop + verticalMargin + itemIndex * lineHeight;
}
return {
groupHeight: lineHeight * items.length,
verticalMargin: verticalMargin,
itemTop: item.dimensions.top
};
}
/**
* Calculate the position of a given item for a group that

@@ -317,3 +339,3 @@ * is being stacked

var curHeight = groupHeight;
var verticalMargin = lineHeight - item.dimensions.height;
var verticalMargin = (lineHeight - item.dimensions.height) / 2;
if (item.dimensions.stack && item.dimensions.top === null) {

@@ -338,3 +360,3 @@ item.dimensions.top = groupTop + verticalMargin;

item.dimensions.top = collidingItem.dimensions.top + lineHeight;
curHeight = Math.max(curHeight, item.dimensions.top + item.dimensions.height - groupTop);
curHeight = Math.max(curHeight, item.dimensions.top + item.dimensions.height + verticalMargin - groupTop);
}

@@ -402,3 +424,3 @@ } while (collidingItem);

} else {
groupHeights.push(Math.max(groupHeight + verticalMargin, lineHeight));
groupHeights.push(Math.max(groupHeight, lineHeight));
}

@@ -414,7 +436,7 @@ }

/**
*
* @param {*} itemsDimensions
* @param {*} isGroupStacked
* @param {*} lineHeight
* @param {*} groupTop
*
* @param {*} itemsDimensions
* @param {*} isGroupStacked
* @param {*} lineHeight
* @param {*} groupTop
*/

@@ -427,4 +449,6 @@ function stackGroup(itemsDimensions, isGroupStacked, lineHeight, groupTop) {

var r = {};
if (isGroupStacked) {
if (isGroupStacked === 'space') {
r = groupStack(lineHeight, itemsDimensions[itemIndex], itemsDimensions, groupHeight, groupTop, itemIndex);
} else if (isGroupStacked === 'lines') {
r = groupStackInLines(lineHeight, itemsDimensions[itemIndex], itemsDimensions, groupHeight, groupTop, itemIndex);
} else {

@@ -431,0 +455,0 @@ r = groupNoStack(lineHeight, itemsDimensions[itemIndex], groupHeight, groupTop);

{
"name": "@r365/react-calendar-timeline",
"version": "0.25.0-drag.3",
"version": "0.26.0-alpha.0",
"description": "react calendar timeline",

@@ -130,3 +130,3 @@ "main": "lib/index.js",

"interactjs": "^1.3.4",
"jest": "^23.1.0",
"jest": "^23.6.0",
"jest-dom": "^1.12.1",

@@ -144,3 +144,3 @@ "jest-watch-typeahead": "^0.1.0",

"react-router-dom": "^4.1.1",
"react-testing-library": "^5.1.0",
"react-testing-library": "^6.0.3",
"rimraf": "^2.6.2",

@@ -147,0 +147,0 @@ "sass-loader": "^7.0.3",

# React Calendar Timeline
A modern and responsive react timeline component.
A modern and responsive React timeline component.

@@ -19,3 +19,3 @@ ![calendar demo](https://raw.githubusercontent.com/namespace-ee/react-calendar-timeline/master/demo.gif)

`react-calendar-timeline` has `react`, `react-dom`, [`moment`](http://momentjs.com/) and [`interactjs`](http://interactjs.io/docs/) as peer dependencies.
`react-calendar-timeline` has [react](https://reactjs.org/), [react-dom](https://reactjs.org/docs/react-dom.html), [`moment`](http://momentjs.com/) and [`interactjs`](http://interactjs.io/docs/) as peer dependencies.

@@ -87,3 +87,3 @@ # Usage

rightTitle: 'title in the right sidebar',
stackItems?: true,
stackItems?: false or 'space' or 'line',
height?: 30

@@ -93,3 +93,3 @@ }

If you use right sidebar, you can pass optional `rightTitle` property here.
If you use the right sidebar, you can pass optional `rightTitle` property here.
If you want to overwrite the calculated height with a custom height, you can pass a `height` property as an int in pixels here. This can be very useful for categorized groups.

@@ -124,3 +124,3 @@

The preferred (fastest) option is to give unix timestamps in milliseconds for `start_time` and `end_time`. Objects that convert to them (JavaScript Date or moment()) will also work, but will be a lot slower.
The preferred (fastest) option is to give Unix timestamps in milliseconds for `start_time` and `end_time`. Objects that convert to them (JavaScript `Date` or `moment()`) will also work, but will be a lot slower.

@@ -133,3 +133,3 @@ ## defaultTimeStart and defaultTimeEnd

The exact viewport of the calendar. When these are specified, scrolling in the calendar must be orchestrated by the `onTimeChange` function. This parameter expects a unix timestamp in milliseconds.
The exact viewport of the calendar. When these are specified, scrolling in the calendar must be orchestrated by the `onTimeChange` function. This parameter expects a Unix timestamp in milliseconds.

@@ -185,15 +185,2 @@ **Note that you need to provide either `defaultTimeStart/End` or `visibleTimeStart/End` for the timeline to function**

## stickyOffset
At what height from the top of the screen should we start "sticking" the header (i.e. position: sticky)? This is useful if for example you already have
a sticky navbar and want to push the timeline header down further. Defaults `0`.
## stickyHeader
Specify whether you want the timeline header to be "sticky". Pass `false` if you want the header to fix at top of element and not fix when you scroll down the page. Defaults to `true`
## headerRef
Ref callback that gets a DOM reference to the header element. See [FAQ below](#the-timeline-header-doesnt-fix-to-the-top-of-the-container-when-i-scroll-down).
## lineHeight

@@ -203,10 +190,2 @@

## headerLabelGroupHeight
Height of the top header line. Default `30`
## headerLabelHeight
Height of the bottom header line. Default `30`
## itemHeightRatio

@@ -226,3 +205,3 @@

How many pixels we can drag the background for it to be counted as a click on the background. Defualt: `3`
How many pixels we can drag the background for it to be counted as a click on the background. Default `3`

@@ -249,2 +228,7 @@ ## canMove

can be assigned to
- false
- space (saves space in stacking)
- line (stack each item in a line)
## traditionalZoom

@@ -319,3 +303,3 @@

## moveResizeValidator(action, itemId, time, resizeEdge, groupId)
## moveResizeValidator(action, itemId, time, resizeEdge)

@@ -330,4 +314,2 @@ This function is called when an item is being moved or resized. It's up to this function to return a new version of `change`, when the proposed move would violate business logic.

The argument `groupId` is the new group id to be moved to.
The function must return a new unix timestamp in milliseconds... or just `time` if the proposed new time doesn't interfere with business logic.

@@ -347,76 +329,7 @@

```
## onUpdateMove(itemId, time, newGroup, action,resizeEdge)
## headerLabelFormats and subHeaderLabelFormats
this function is called after moveResizeValidator on every drag update
The formats passed to moment to render times in the header and subheader. Defaults to these:
```js
import {
defaultHeaderLabelFormats,
defaultSubHeaderLabelFormats
} from 'react-calendar-timeline'
defaultHeaderLabelFormats ==
{
yearShort: 'YY',
yearLong: 'YYYY',
monthShort: 'MM/YY',
monthMedium: 'MM/YYYY',
monthMediumLong: 'MMM YYYY',
monthLong: 'MMMM YYYY',
dayShort: 'L',
dayLong: 'dddd, LL',
hourShort: 'HH',
hourMedium: 'HH:00',
hourMediumLong: 'L, HH:00',
hourLong: 'dddd, LL, HH:00',
time: 'LLL'
}
defaultSubHeaderLabelFormats ==
{
yearShort: 'YY',
yearLong: 'YYYY',
monthShort: 'MM',
monthMedium: 'MMM',
monthLong: 'MMMM',
dayShort: 'D',
dayMedium: 'dd D',
dayMediumLong: 'ddd, Do',
dayLong: 'dddd, Do',
hourShort: 'HH',
hourLong: 'HH:00',
minuteShort: 'mm',
minuteLong: 'HH:mm'
}
```
For US time formats (AM/PM), use these:
```js
import {
defaultHeaderLabelFormats,
defaultSubHeaderLabelFormats
} from 'react-calendar-timeline'
const usHeaderLabelFormats = Object.assign({}, defaultSubHeaderLabelFormats, {
hourShort: 'h A',
hourMedium: 'h A',
hourMediumLong: 'L, h A',
hourLong: 'dddd, LL, h A'
})
const usSubHeaderLabelFormats = Object.assign(
{},
defaultSubHeaderLabelFormats,
{
hourShort: 'h A',
hourLong: 'h A',
minuteLong: 'h:mm A'
}
)
```
... and then pass these as `headerLabelFormats` and `subHeaderLabelFormats`
## onTimeChange(visibleTimeStart, visibleTimeEnd, updateScrollCanvas)

@@ -452,5 +365,5 @@

Render prop function used to render a customized item. The function provides multiple paramerters that can be used to render each item.
Render prop function used to render a customized item. The function provides multiple parameters that can be used to render each item.
Paramters provided to the function has two types: context params which have the state of the item and timeline, and prop getters functions
Parameters provided to the function has two types: context params which have the state of the item and timeline, and prop getters functions

@@ -486,2 +399,3 @@ #### Render props params

| `dragStart` | `object` | returns `x` and `y` of the start dragging point of the item. |
| `dragTime` | `number` | current drag time. |
| `dragGroupDelta` | `number` | returns number of groups the item moved. if negative, moving was to top. If positive, moving was to down |

@@ -491,2 +405,3 @@ | `resizing` | `boolean` | returns if the item is being resized. |

| `resizeStart` | `number` | returns the x value from where the component start moving |
| `resizeTime` | `number` | current resize time |
| `width` | `boolean` | returns the width of the item (same as in dimensions) |

@@ -508,3 +423,3 @@

* key: item id
* ref: function to get item referance
* ref: function to get item reference
* className: classnames to be applied to the item

@@ -519,5 +434,5 @@ * onMouseDown: event handler

\*\* _the given styles will only override the styles that are not a requirement for postioning the item. Other styles like `color`, `radius` and others_
\*\* _the given styles will only override the styles that are not a requirement for positioning the item. Other styles like `color`, `radius` and others_
These properties can be override using the prop argument with proprties:
These properties can be override using the prop argument with properties:

@@ -731,6 +646,6 @@ * className: class names to be added

{({ styles, date }) =>
// date is value of current date. Use this to render special styles for the marker
// or any other custom logic based on date:
// e.g. styles = {...styles, backgroundColor: isDateInAfternoon(date) ? 'red' : 'limegreen'}
return <div style={styles} />
// date is value of current date. Use this to render special styles for the marker
// or any other custom logic based on date:
// e.g. styles = {...styles, backgroundColor: isDateInAfternoon(date) ? 'red' : 'limegreen'}
<div style={styles} />
}

@@ -758,5 +673,3 @@ </TodayMarker>

<CustomMarker date={today}>
{({ styles, date }) =>
return <div style={styles} />
}
{({ styles, date }) => <div style={styles} />}
</CustomMarker>

@@ -791,6 +704,6 @@

{({ styles, date }) =>
// date is value of current date. Use this to render special styles for the marker
// or any other custom logic based on date:
// e.g. styles = {...styles, backgroundColor: isDateInAfternoon(date) ? 'red' : 'limegreen'}
return <div style={styles} />
// date is value of current date. Use this to render special styles for the marker
// or any other custom logic based on date:
// e.g. styles = {...styles, backgroundColor: isDateInAfternoon(date) ? 'red' : 'limegreen'}
<div style={styles} />
}

@@ -828,3 +741,3 @@ </CursorMarker>

</SidebarHeader>
<DateHeader primaryHeader />
<DateHeader unit="primaryHeader" />
<DateHeader />

@@ -850,4 +763,4 @@ </TimelineHeaders>

| `calendarHeaderClassName`| `string`| applied to the root component of the calendar headers -scrolable div- `DateHeader` and `CustomHeader`)|
| `headerRef` | `function` | used to get the ref of the header element
### `SidebarHeader`

@@ -863,2 +776,3 @@

| `children` | `Function`| function as a child component to render the header|
| `headerData` | `any`| Contextual data to be passed to the item renderer as a data prop |

@@ -876,2 +790,3 @@ #### Child function renderer

| `getRootProps` | `function(props={})` | returns the props you should apply to the root div element.|
| `data` | `any` | Contextual data passed by `headerData` prop|

@@ -902,8 +817,8 @@ * `getRootProps` The returned props are:

</SidebarHeader>
<SidebarHeader variant="right">
{({ getRootProps }) => {
return <div {...getRootProps()}>Right</div>
<SidebarHeader variant="right" headerData={{someData: 'extra'}}>
{({ getRootProps, data }) => {
return <div {...getRootProps()}>Right {data.someData}</div>
}}
</SidebarHeader>
<DateHeader primaryHeader />
<DateHeader unit="primaryHeader" />
<DateHeader />

@@ -914,2 +829,4 @@ </TimelineHeaders>

_Note_ : the Child function renderer can be a component or a function for convenience
### `DateHeader`

@@ -926,35 +843,43 @@

| `className` | `string`| applied to the root of the header|
| `unit`| `second`, `minute`, `hour`, `day`, `week`, `month`, `year` | intervals between columns |
| `primaryHeader`| `boolean` | main header with interval unit larger than timeline unit by 1 |
| `secondaryHeader` | `boolean` (`true` by default) | sub header with interval equal to timeline unit |
| `labelFormat` | `Function` or `object` or `string`| controls the how to format the interval label |
| `intervalRenderer`| `Function`| render prop to render each interval in the header |
| `unit`| `second`, `minute`, `hour`, `day`, `week`, `month`, `year` or `primaryHeader` | intervals between columns |
| `labelFormat` | `Function` or `string`| controls the how to format the interval label |
| `intervalRenderer`| `Function`| render prop to render each interval in the header
| `headerData` | `any`| Contextual data to be passed to the item renderer as a data prop |
| `height` | `number` default (30)| height of the header in pixels |
_Note_: passing `primaryHeader` to unit the header will act as the main header with interval unit larger than timeline unit by 1
#### Interval unit
intervals are decided through three props: `unit`, `primaryHeader` and `secondaryHeader` (default true). `secondaryHeader` is the default if no prop are set. The unit of the intervals will be the same the timeline and a special style is matches the default style of the secondary header from when no custom headers are applied.
intervals are decided through the prop: `unit`. By default, the unit of the intervals will be the same the timeline.
If `primaryHeader` is set to true, it will override `secondaryHeader` and the unit if the timeline will be larger by 1 of the timeline unit. The default style will match the primary header from when no custom headers are applied.
If `primaryHeader` is passed to unit, it will override the unit with a unit a unit larger by 1 of the timeline unit.
If `unit` is set, it will override both `primaryHeader` and `secondaryHeader`. The unit of the header will be the unit passed though the prop and can be any `unit of time` from `momentjs`. The default style will match the primary header from when no custom headers are applied.
If `unit` is set, the unit of the header will be the unit passed though the prop and can be any `unit of time` from `momentjs`.
#### Label format
To format each interval label you can use 3 types of props to format which are:
To format each interval label you can use 2 types of props to format which are:
- `string`: if a string was passed it will be passed to `startTime` method `format` which is a `momentjs` object .
- `object`: this will give you more flexibility to format the label with respect to `labelWidth`. Internally the `startTime` will be formated with the string corresponding to `formatObject[unit][range]`
The object will be in the following type:
- `Function`: This is the more powerful method and offers the most control over what is rendered. The returned `string` will be rendered inside the interval
```typescript
type unit = `second` | `minute` | `hour` | `day` | `week` | `month` | `year`
interface LabelFormat {
[unit]: {
long: string,
mediumLong: string,
medium: string,
short: string
}
}
type Unit = `second` | `minute` | `hour` | `day` | `month` | `year`
([startTime, endTime] : [Moment, Moment], unit: Unit, labelWidth: number, formatOptions: LabelFormat = defaultFormat ) => string
```
##### Default format
by default we provide a responsive format for the dates based on the label width. it follows the following rules:
The `long`, `mediumLong`, `medium` and `short` will be be decided through the `labelWidth` value according to where it lays upon the following scale:
```
|-----`short`-----50px-----`medium`-----100px-----`mediumLong`-----150px--------`long`-----
```
```typescript
// default format object

@@ -995,15 +920,5 @@ const format : LabelFormat = {

The `long`, `mediumLong`, `medium` and `short` will be be decided through the `labelWidth` value according to where it lays upon the following scale:
_Note_: this is only an implementation of the function param. You can do this on your own easily
```
|-----`short`-----50px-----`medium`-----100px-----`mediumLong`-----150px--------`long`-----
```
- `Function`: This is the more powerful method and offers the most control over what is rendered. The returned `string` will be rendered inside the interval
```typescript
type Unit = `second` | `minute` | `hour` | `day` | `month` | `year`
([startTime, endTime] : [Moment, Moment], unit: Unit, labelWidth: number, formatOptions: LabelFormat = defaultFormat ) => string
```
#### intervalRenderer

@@ -1015,2 +930,4 @@

_Note_ : the renderProp can be a component or a function for convenience
##### interval context

@@ -1022,3 +939,3 @@

| ------------------ | -------- | ---------------------------------------------------- |
| `interval` | `array : [Moment, Moment]` | an tuple array conating two moment object the first `startTime` and the second `endTime`|
| `interval` | `object : {startTime, endTime, labelWidth, left}` | an object containing data related to the interval|
| `intervalText` | `string` | the string returned from `labelFormat` prop |

@@ -1046,2 +963,6 @@

##### data
data passed through headerData
#### example

@@ -1063,3 +984,3 @@

</SidebarHeader>
<DateHeader primaryHeader />
<DateHeader unit="primaryHeader" />
<DateHeader />

@@ -1070,5 +991,7 @@ <DateHeader

style={{ height: 50 }}
intervalRenderer={({ getIntervalProps, intervalContext }) => {
data={{someData: 'example'}}
intervalRenderer={({ getIntervalProps, intervalContext, data }) => {
return <div {...getIntervalProps()}>
{intervalContext.intervalText}
{data.example}
</div>

@@ -1205,2 +1128,4 @@ }}

| `children` | `Function`| function as a child component to render the header|
| `headerData` | `any`| Contextual data to be passed to the item renderer as a data prop |
| `height` | `number` default (30)| height of the header in pixels |

@@ -1217,2 +1142,4 @@ #### unit

_Note_ : the Child function renderer can be a component or a function for convenience
```

@@ -1233,3 +1160,5 @@ ({

getIntervalProps: this.getIntervalProps,
showPeriod
showPeriod,
//contextual data passed through headerData
data,
})=> React.Node

@@ -1247,7 +1176,7 @@ ```

| ------------------ | -------- | ---------------------------------------------------- |
| `timelineWidth` | `array : [Moment, Moment]` | an tuple array conating two moment object the first `startTime` and the second `endTime`|
| `visibleTimeStart` | `string` | the string returned from `labelFormat` prop |
| `visibleTimeEnd` | `array : [Moment, Moment]` | an tuple array conating two moment object the first `startTime` and the second `endTime`|
| `canvasTimeStart` | `string` | the string returned from `labelFormat` prop |
| `canvasTimeEnd` | `array : [Moment, Moment]` | an tuple array conating two moment object the first `startTime` and the second `endTime`|
| `timelineWidth` | `number` | width of timeline|
| `visibleTimeStart` | `number` | unix milliseconds of start visible time |
| `visibleTimeEnd` | `number` | unix milliseconds of end visible time|
| `canvasTimeStart` | `number` | unix milliseconds of start buffer time |
| `canvasTimeEnd` | `number` |unix milliseconds of end buffer time|

@@ -1289,3 +1218,5 @@ ###### Header context

##### data:
pass through the `headerData` prop content

@@ -1308,5 +1239,5 @@ #### example

</SidebarHeader>
<DateHeader primaryHeader />
<DateHeader unit="primaryHeader" />
<DateHeader />
<CustomHeader unit="year">
<CustomHeader headerData={{someData: 'data'}} unit="year">
{({

@@ -1316,3 +1247,4 @@ headerContext: { intervals },

getIntervalProps,
showPeriod
showPeriod,
data,
}) => {

@@ -1363,3 +1295,3 @@ return (

Now you can use item renderer for rendering items with different colors [itemRenderer](https://github.com/namespace-ee/react-calendar-timeline#itemrenderer).
Now you can use item renderer for rendering items with different colors [itemRenderer](https://github.com/namespace-ee/react-calendar-timeline#itemrenderer).
Please refer to [examples](https://github.com/namespace-ee/react-calendar-timeline/tree/master/examples#custom-item-rendering) for a sandbox example

@@ -1372,7 +1304,6 @@

To use it, you need to add two props to the `<Timeline />` component:
To use it, you need to add a props to the `<Timeline />` component:
```jsx
rightSidebarWidth={150}
rightSidebarContent={<p>Second filter</p>}
```

@@ -1390,29 +1321,8 @@

If you are using Custom Headers then you need to add `SidebarHeader` component under `TimelineHeader` with variant `right`
## The timeline header doesn't fix to the top of the container when I scroll down.
There are two causes of this:
you need to add sticky to the header like [this example](https://github.com/FoothillSolutions/react-calendar-timeline/tree/dest-build/examples#sticky-header).
* you are passing `stickyHeader={false}` to the timeline component. The header by default has sticky behavior unless you tell it not to using this prop.
* the browser you are viewing the timeline in doesn't support `position: sticky`. In this scenario, you will need to polyfill this behavior using the `headerRef`.
In this example, we use [stickyfill](https://github.com/wilddeer/stickyfill) as our sticky polyfill
```jsx
// add a handler in your parent component that accepts a DOM element
// with this element, pass the element into a polyfill library
handleHeaderRef = (el) => {
// polyfill dom element with stickyfill
Stickyfill.addOne(el)
}
// in render, pass this handler to the `headerRef` prop:
render() {
<Timeline
//other props
headerRef={this.handleHeaderRef}
/>
}
```

@@ -1498,1 +1408,4 @@

-->
## License
[MIT licensed](/LICENSE.md).

@@ -15,2 +15,3 @@ import Timeline from './lib/Timeline'

export {default as ItemHeader} from './lib/headers/ItemHeader'
export * from './lib/utility/calendar'
export default Timeline

@@ -5,13 +5,19 @@ import PropTypes from 'prop-types'

import { iterateTimes } from '../utility/calendar'
import { TimelineStateConsumer } from '../timeline/TimelineStateContext'
export default class Columns extends Component {
const passThroughPropTypes = {
canvasTimeStart: PropTypes.number.isRequired,
canvasTimeEnd: PropTypes.number.isRequired,
canvasWidth: PropTypes.number.isRequired,
lineCount: PropTypes.number.isRequired,
minUnit: PropTypes.string.isRequired,
timeSteps: PropTypes.object.isRequired,
height: PropTypes.number.isRequired,
verticalLineClassNamesForTime: PropTypes.func
}
class Columns extends Component {
static propTypes = {
canvasTimeStart: PropTypes.number.isRequired,
canvasTimeEnd: PropTypes.number.isRequired,
canvasWidth: PropTypes.number.isRequired,
lineCount: PropTypes.number.isRequired,
minUnit: PropTypes.string.isRequired,
timeSteps: PropTypes.object.isRequired,
height: PropTypes.number.isRequired,
verticalLineClassNamesForTime: PropTypes.func
...passThroughPropTypes,
getLeftOffsetFromDate: PropTypes.func.isRequired
}

@@ -41,3 +47,4 @@

height,
verticalLineClassNamesForTime
verticalLineClassNamesForTime,
getLeftOffsetFromDate
} = this.props

@@ -54,9 +61,4 @@ const ratio = canvasWidth / (canvasTimeEnd - canvasTimeStart)

(time, nextTime) => {
const left = Math.round((time.valueOf() - canvasTimeStart) * ratio, -2)
const minUnitValue = time.get(minUnit === 'day' ? 'date' : minUnit)
const firstOfType = minUnitValue === (minUnit === 'day' ? 1 : 0)
const lineWidth = firstOfType ? 2 : 1
const labelWidth =
Math.ceil((nextTime.valueOf() - time.valueOf()) * ratio) - lineWidth
const leftPush = firstOfType ? -1 : 0

@@ -80,2 +82,4 @@ let classNamesForTime = []

const left = getLeftOffsetFromDate(time.valueOf())
const right = getLeftOffsetFromDate(nextTime.valueOf())
lines.push(

@@ -88,4 +92,4 @@ <div

top: '0px',
left: `${left + leftPush}px`,
width: `${labelWidth}px`,
left: `${left}px`,
width: `${right - left}px`,
height: `${height}px`

@@ -100,2 +104,18 @@ }}

}
}
}
const ColumnsWrapper = ({ ...props }) => {
return (
<TimelineStateConsumer>
{({ getLeftOffsetFromDate }) => (
<Columns getLeftOffsetFromDate={getLeftOffsetFromDate} {...props} />
)}
</TimelineStateConsumer>
)
}
ColumnsWrapper.defaultProps = {
...passThroughPropTypes
}
export default ColumnsWrapper

@@ -0,0 +0,0 @@ export const defaultKeys = {

export const LEFT_VARIANT= 'left'
export const RIGHT_VARIANT= 'right'

@@ -5,3 +5,3 @@ import React from 'react'

import { TimelineStateConsumer } from '../timeline/TimelineStateContext'
import { iterateTimes } from '../utility/calendar'
import { iterateTimes, calculateXPositionForTime } from '../utility/calendar'

@@ -13,4 +13,4 @@ export class CustomHeader extends React.Component {

unit: PropTypes.string.isRequired,
//Timeline context
timeSteps: PropTypes.object.isRequired,
//Timeline context
visibleTimeStart: PropTypes.number.isRequired,

@@ -22,3 +22,5 @@ visibleTimeEnd: PropTypes.number.isRequired,

showPeriod: PropTypes.func.isRequired,
props: PropTypes.object
headerData: PropTypes.object,
getLeftOffsetFromDate: PropTypes.func.isRequired,
height: PropTypes.number.isRequired,
}

@@ -33,9 +35,6 @@ constructor(props) {

timeSteps,
showPeriod
showPeriod,
getLeftOffsetFromDate
} = props
const ratio = this.calculateRatio(
canvasWidth,
canvasTimeEnd,
canvasTimeStart
)
const intervals = this.getHeaderIntervals({

@@ -48,8 +47,7 @@ canvasTimeStart,

showPeriod,
ratio,
getLeftOffsetFromDate
})
this.state = {
intervals,
ratio
intervals
}

@@ -66,3 +64,4 @@ }

nextProps.showPeriod !== this.props.showPeriod ||
nextProps.children !== this.props.children
nextProps.children !== this.props.children ||
nextProps.headerData !== this.props.headerData
) {

@@ -89,9 +88,6 @@ return true

timeSteps,
showPeriod
showPeriod,
getLeftOffsetFromDate
} = nextProps
const ratio = this.calculateRatio(
canvasWidth,
canvasTimeEnd,
canvasTimeStart
)
const intervals = this.getHeaderIntervals({

@@ -104,6 +100,6 @@ canvasTimeStart,

showPeriod,
ratio,
getLeftOffsetFromDate
})
this.setState({ intervals, ratio })
this.setState({ intervals })
}

@@ -117,3 +113,3 @@ }

timeSteps,
ratio,
getLeftOffsetFromDate
}) => {

@@ -127,9 +123,10 @@ const intervals = []

(startTime, endTime) => {
const labelWidth = Math.ceil(
(endTime.valueOf() - startTime.valueOf()) * ratio
)
const left = getLeftOffsetFromDate(startTime.valueOf())
const right = getLeftOffsetFromDate(endTime.valueOf())
const width = right - left
intervals.push({
startTime,
endTime,
labelWidth
labelWidth: width,
left
})

@@ -141,12 +138,10 @@ }

rootProps = {
style: {
position: 'relative'
}
}
getRootProps = (props = {}) => {
const { style } = props
return {
style: Object.assign({}, style ? style : {}, this.rootProps.style)
style: Object.assign({}, style ? style : {}, {
position: 'relative',
width: this.props.canvasWidth,
height: this.props.height,
})
}

@@ -157,4 +152,5 @@ }

const { interval, style } = props
if (!interval) throw new Error("you should provide interval to the prop getter")
const { startTime, labelWidth } = interval
if (!interval)
throw new Error('you should provide interval to the prop getter')
const { startTime, labelWidth, left } = interval
return {

@@ -167,3 +163,3 @@ style: this.getIntervalStyle({

unit: this.props.unit,
ratio: this.state.ratio
left
}),

@@ -174,14 +170,6 @@ key: `label-${startTime.valueOf()}`

calculateRatio(canvasWidth, canvasTimeEnd, canvasTimeStart) {
return canvasWidth / (canvasTimeEnd - canvasTimeStart)
}
getIntervalStyle = ({ startTime, canvasTimeStart, ratio, unit, labelWidth, style, }) => {
const left = Math.round((startTime.valueOf() - canvasTimeStart) * ratio)
const unitValue = startTime.get(unit === 'day' ? 'date' : unit)
const firstOfType = unitValue === (unit === 'day' ? 1 : 0)
const leftCorrect = firstOfType ? 1 : 0
getIntervalStyle = ({ left, labelWidth, style }) => {
return {
...style,
left: left - leftCorrect,
left,
width: labelWidth,

@@ -200,3 +188,4 @@ position: 'absolute'

visibleTimeStart,
visibleTimeEnd
visibleTimeEnd,
headerData,
} = this.props

@@ -218,3 +207,4 @@ //TODO: only evaluate on changing params

getIntervalProps: this.getIntervalProps,
showPeriod
showPeriod,
data: headerData,
}

@@ -225,9 +215,10 @@ }

const props = this.getStateAndHelpers()
return this.props.children(props, this.props.props)
const Renderer = this.props.children
return <Renderer {...props}/>
}
}
const CustomHeaderWrapper = ({ children, unit, props }) => (
const CustomHeaderWrapper = ({ children, unit, headerData, height }) => (
<TimelineStateConsumer>
{({ getTimelineState, showPeriod }) => {
{({ getTimelineState, showPeriod, getLeftOffsetFromDate }) => {
const timelineState = getTimelineState()

@@ -243,3 +234,5 @@ return (

{...timelineState}
props={props}
headerData={headerData}
getLeftOffsetFromDate={getLeftOffsetFromDate}
height={height}
/>

@@ -256,5 +249,10 @@ )}

unit: PropTypes.string,
props: PropTypes.object,
headerData: PropTypes.object,
height: PropTypes.number,
}
CustomHeaderWrapper.defaultProps = {
height: 30,
}
export default CustomHeaderWrapper

@@ -11,4 +11,2 @@ import React from 'react'

static propTypes = {
primaryHeader: PropTypes.bool,
secondaryHeader: PropTypes.bool,
unit: PropTypes.string,

@@ -24,12 +22,31 @@ style: PropTypes.object,

intervalRenderer: PropTypes.func,
props: PropTypes.object,
headerData: PropTypes.object,
height: PropTypes.number,
}
getHeaderUnit = () => {
if (this.props.unit) {
if (this.props.unit === 'primaryHeader') {
return getNextUnit(this.props.timelineUnit)
} else if (this.props.unit) {
return this.props.unit
} else if (this.props.primaryHeader) {
return getNextUnit(this.props.timelineUnit)
}
return this.props.timelineUnit
}
getRootStyle = () => {
return {
height: 30,
...this.props.style
}
}
getLabelFormat(interval, unit, labelWidth) {
const { labelFormat } = this.props
if (typeof labelFormat === 'string') {
const startTime = interval[0]
return startTime.format(labelFormat)
} else if (typeof labelFormat === 'function') {
return labelFormat(interval, unit, labelWidth)
} else {
return this.props.timelineUnit
throw new Error('labelFormat should be function or string')
}

@@ -40,5 +57,5 @@ }

const unit = this.getHeaderUnit()
const {props} = this.props;
const { headerData, height } = this.props
return (
<CustomHeader unit={unit} props={props}>
<CustomHeader unit={unit} height={height} headerData={headerData}>
{({

@@ -48,4 +65,5 @@ headerContext: { intervals },

getIntervalProps,
showPeriod
}, props) => {
showPeriod,
data
}) => {
const unit = this.getHeaderUnit()

@@ -55,2 +73,3 @@

<div
data-testid={`dateHeader`}
className={this.props.className}

@@ -72,7 +91,6 @@ {...getRootProps({ style: this.getRootStyle() })}

intervalText={intervalText}
primaryHeader={!!this.props.primaryHeader}
secondaryHeader={!!this.props.secondaryHeader}
primaryHeader={this.props.unit === 'primaryHeader'}
getIntervalProps={getIntervalProps}
intervalRenderer={this.props.intervalRenderer}
props={props}
headerData={data}
/>

@@ -87,28 +105,5 @@ )

}
getRootStyle = () => {
return {
height: 30,
...this.props.style
}
}
getLabelFormat(interval, unit, labelWidth) {
const { labelFormat } = this.props
if (typeof labelFormat === 'string') {
const startTime = interval[0]
return startTime.format(labelFormat)
} else if (typeof labelFormat === 'object') {
return formatLabel(interval, unit, labelWidth, labelFormat)
} else if (typeof labelFormat === 'function') {
return labelFormat(interval, unit, labelWidth)
} else {
throw new Error('labelFormat should be function, object or string')
}
}
}
const DateHeaderWrapper = ({
primaryHeader,
secondaryHeader,
unit,

@@ -119,3 +114,4 @@ labelFormat,

intervalRenderer,
props,
headerData,
height,
}) => (

@@ -128,4 +124,2 @@ <TimelineStateConsumer>

timelineUnit={timelineState.timelineUnit}
primaryHeader={primaryHeader}
secondaryHeader={secondaryHeader}
unit={unit}

@@ -136,3 +130,4 @@ labelFormat={labelFormat}

intervalRenderer={intervalRenderer}
props={props}
headerData={headerData}
height={height}
/>

@@ -147,4 +142,2 @@ )

className: PropTypes.string,
primaryHeader: PropTypes.bool,
secondaryHeader: PropTypes.bool,
unit: PropTypes.string,

@@ -157,7 +150,7 @@ labelFormat: PropTypes.oneOfType([

intervalRenderer: PropTypes.func,
props: PropTypes.object,
headerData: PropTypes.object,
height: PropTypes.number,
}
DateHeaderWrapper.defaultProps = {
secondaryHeader: true,
labelFormat: formatLabel

@@ -164,0 +157,0 @@ }

@@ -5,4 +5,2 @@ import React from 'react'

import { noop } from '../utility/generic'
import { LEFT_SIDEBAR_ID, RIGHT_SIDEBAR_ID } from './constants'
import { getNextUnit } from '../utility/calendar'

@@ -9,0 +7,0 @@ const defaultContextState = {

@@ -14,28 +14,6 @@ import React from 'react'

primaryHeader: PropTypes.bool.isRequired,
secondaryHeader: PropTypes.bool.isRequired,
getIntervalProps: PropTypes.func.isRequired,
props: PropTypes.object
headerData: PropTypes.object
}
getIntervalStyle = () => {
return {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundColor:
this.props.secondaryHeader && !this.props.primaryHeader
? 'rgb(240, 240, 240)'
: 'initial',
height: '100%',
borderLeft: this.props.primaryHeader
? '1px solid #bbb'
: '2px solid #bbb',
borderRight: this.props.primaryHeader ? '1px solid #bbb' : 'none',
borderBottom: '1px solid #bbb',
color: this.props.primaryHeader ? '#fff' : 'initial',
cursor: 'pointer',
fontSize: '14px'
}
}
onIntervalClick = () => {

@@ -53,3 +31,3 @@ const { primaryHeader, interval, unit, showPeriod } = this.props

getIntervalProps = (props={}) => {
getIntervalProps = (props = {}) => {
return {

@@ -65,16 +43,23 @@ ...this.props.getIntervalProps({

render() {
const { intervalText, interval, intervalRenderer, props } = this.props
if (intervalRenderer)
return intervalRenderer({
getIntervalProps: this.getIntervalProps,
intervalContext: {
interval,
intervalText
}
}, props)
const { intervalText, interval, intervalRenderer, headerData } = this.props
const Renderer = intervalRenderer
if (Renderer) {
return (
<Renderer
getIntervalProps={this.getIntervalProps}
intervalContext={{
interval,
intervalText
}}
data={headerData}
/>
)
}
return (
<div
data-testid="dateHeaderInterval"
{...this.getIntervalProps({
style: this.getIntervalStyle()
})}
className={`rct-dateHeader ${this.props.primaryHeader? 'rct-dateHeader-primary' : ''}`}
>

@@ -81,0 +66,0 @@ <span>{intervalText}</span>

@@ -0,0 +0,0 @@ import React from 'react'

@@ -12,3 +12,3 @@ import React from 'react'

variant: PropTypes.string,
props: PropTypes.object
headerData: PropTypes.object
}

@@ -24,4 +24,4 @@

style: {
...style,
width,
...style
}

@@ -33,3 +33,4 @@ }

return {
getRootProps: this.getRootProps
getRootProps: this.getRootProps,
data: this.props.headerData,
}

@@ -40,7 +41,8 @@ }

const props = this.getStateAndHelpers()
return this.props.children(props, this.props.props)
const Renderer = this.props.children
return <Renderer {...props}/>
}
}
const SidebarWrapper = ({ children, variant, props }) => (
const SidebarWrapper = ({ children, variant, headerData }) => (
<TimelineHeadersConsumer>

@@ -54,3 +56,3 @@ {({ leftSidebarWidth, rightSidebarWidth }) => {

variant={variant}
props={props}
headerData={headerData}
/>

@@ -65,3 +67,3 @@ )

variant: PropTypes.string,
props: PropTypes.object
headerData: PropTypes.object
}

@@ -71,5 +73,5 @@

variant: LEFT_VARIANT,
children: ({ getRootProps }) => <div {...getRootProps()} />
children: ({ getRootProps }) => <div data-testid="sidebarHeader" {...getRootProps()} />
}
export default SidebarWrapper

@@ -16,3 +16,4 @@ import React from 'react'

calendarHeaderClassName: PropTypes.string,
width: PropTypes.number.isRequired
width: PropTypes.number.isRequired,
headerRef: PropTypes.func,
}

@@ -26,7 +27,5 @@

return {
background: '#c52020',
borderBottom: '1px solid #bbb',
...this.props.style,
display: 'flex',
width: 'max-content'
// width: 'max-content'
}

@@ -42,3 +41,2 @@ }

return {
border: '1px solid #bbb',
...calendarHeaderStyle,

@@ -50,2 +48,8 @@ overflow: 'hidden',

handleRootRef = (element) => {
if(this.props.headerRef){
this.props.headerRef(element)
}
}
render() {

@@ -59,12 +63,8 @@ let rightSidebarHeader

React.Children.map(children, child => {
if (
child.type === SidebarHeader &&
child.props.variant === RIGHT_VARIANT
) {
rightSidebarHeader = child
} else if (
child.type === SidebarHeader &&
child.props.variant === LEFT_VARIANT
) {
leftSidebarHeader = child
if (child.type === SidebarHeader) {
if (child.props.variant === RIGHT_VARIANT) {
rightSidebarHeader = child
} else {
leftSidebarHeader = child
}
} else {

@@ -75,3 +75,8 @@ calendarHeaders.push(child)

return (
<div style={this.getRootStyle()} className={this.props.className}>
<div
ref={this.handleRootRef}
data-testid="headerRootDiv"
style={this.getRootStyle()}
className={`rct-header-root ${this.props.className}`}
>
{leftSidebarHeader}

@@ -81,3 +86,4 @@ <div

style={this.getCalendarHeaderStyle()}
className={this.props.calendarHeaderClassName}
className={`rct-calendar-header ${this.props.calendarHeaderClassName}`}
data-testid="headerContainer"
>

@@ -129,5 +135,6 @@ {calendarHeaders}

calendarHeaderStyle: PropTypes.object,
calendarHeaderClassName: PropTypes.string
calendarHeaderClassName: PropTypes.string,
headerRef: PropTypes.func,
}
export default TimelineHeadersWrapper

@@ -0,0 +0,0 @@ import React from 'react'

@@ -240,3 +240,3 @@ import { Component } from 'react'

.draggable({
enabled: this.props.selected
enabled: this.props.selected && this.canMove()
})

@@ -269,5 +269,3 @@ .styleCursor(false)

this.props.item,
dragTime,
undefined,
_get(this.props.dimensions.order.group, this.props.keys.groupIdKey)
dragTime
)

@@ -299,5 +297,3 @@ }

this.props.item,
dragTime,
undefined,
_get(this.props.dimensions.order.group, this.props.keys.groupIdKey)
dragTime
)

@@ -345,3 +341,2 @@ }

if (this.props.moveResizeValidator) {
console.log(this.props.dimensions)
resizeTime = this.props.moveResizeValidator(

@@ -351,4 +346,3 @@ 'resize',

resizeTime,
resizeEdge,
_get(this.props.dimensions.order.group, this.props.keys.groupIdKey)
resizeEdge
)

@@ -376,4 +370,3 @@ }

resizeTime,
resizeEdge,
_get(this.props.dimensions.order.group, this.props.keys.groupIdKey)
resizeEdge
)

@@ -399,3 +392,5 @@ }

.on('tap', e => {
this.actualClick(e, e.pointerType === 'mouse' ? 'click' : 'touch')
if(e.pointerType !== 'mouse'){
this.actualClick(e, 'touch')
}
})

@@ -430,9 +425,8 @@

this.cacheDataFromProps(this.props)
let { interactMounted } = this.state
const couldDrag = this.props.selected && this.canMove(this.props)
const couldDrag = prevProps.selected && this.canMove(prevProps)
const couldResizeLeft =
this.props.selected && this.canResizeLeft(this.props)
prevProps.selected && this.canResizeLeft(prevProps)
const couldResizeRight =
this.props.selected && this.canResizeRight(this.props)
prevProps.selected && this.canResizeRight(prevProps)
const willBeAbleToDrag = this.props.selected && this.canMove(this.props)

@@ -444,44 +438,38 @@ const willBeAbleToResizeLeft =

if (this.props.selected && !interactMounted) {
this.mountInteract()
interactMounted = true
if(!!this.item){
if (this.props.selected && !interactMounted) {
this.mountInteract()
interactMounted = true
}
if (
interactMounted &&
(couldResizeLeft !== willBeAbleToResizeLeft ||
couldResizeRight !== willBeAbleToResizeRight)
) {
const leftResize = this.props.useResizeHandle ? this.dragLeft : true
const rightResize = this.props.useResizeHandle ? this.dragRight : true
interact(this.item).resizable({
enabled: willBeAbleToResizeLeft || willBeAbleToResizeRight,
edges: {
top: false,
bottom: false,
left: willBeAbleToResizeLeft && leftResize,
right: willBeAbleToResizeRight && rightResize
}
})
}
if (interactMounted && couldDrag !== willBeAbleToDrag) {
interact(this.item).draggable({ enabled: willBeAbleToDrag })
}
}
if (
interactMounted &&
(couldResizeLeft !== willBeAbleToResizeLeft ||
couldResizeRight !== willBeAbleToResizeRight)
) {
const leftResize = this.props.useResizeHandle ? this.dragLeft : true
const rightResize = this.props.useResizeHandle ? this.dragRight : true
interact(this.item).resizable({
enabled: willBeAbleToResizeLeft || willBeAbleToResizeRight,
edges: {
top: false,
bottom: false,
left: willBeAbleToResizeLeft && leftResize,
right: willBeAbleToResizeRight && rightResize
}
})
else{
interactMounted= false;
}
if (interactMounted && couldDrag !== willBeAbleToDrag) {
interact(this.item).draggable({ enabled: willBeAbleToDrag })
}
}
this.setState({
interactMounted,
})
onMouseDown = e => {
if (!this.state.interactMounted) {
e.preventDefault()
this.startedClicking = true
}
}
onMouseUp = e => {
if (!this.state.interactMounted && this.startedClicking) {
this.startedClicking = false
this.actualClick(e, 'click')
}
}
onTouchStart = e => {

@@ -537,4 +525,2 @@ if (!this.state.interactMounted) {

className: classNames + ` ${props.className ? props.className : ''}`,
onMouseDown: composeEvents(this.onMouseDown, props.onMouseDown),
onMouseUp: composeEvents(this.onMouseUp, props.onMouseUp),
onTouchStart: composeEvents(this.onTouchStart, props.onTouchStart),

@@ -544,3 +530,4 @@ onTouchEnd: composeEvents(this.onTouchEnd, props.onTouchEnd),

onContextMenu: composeEvents(this.handleContextMenu, props.onContextMenu),
style: Object.assign({}, this.getItemStyle(props))
style: Object.assign({}, this.getItemStyle(props)),
onClick : (e) => {this.actualClick(e, 'click')}
}

@@ -547,0 +534,0 @@ }

@@ -0,0 +0,0 @@ import PropTypes from 'prop-types'

@@ -0,0 +0,0 @@ export const overridableStyles = {

@@ -19,7 +19,7 @@ import PropTypes from 'prop-types'

return !(
arraysEqual(nextProps.groups, this.props.groups) &&
nextProps.keys === this.props.keys &&
nextProps.width === this.props.width &&
arraysEqual(nextProps.groupHeights, this.props.groupHeights) &&
nextProps.height === this.props.height
nextProps.height === this.props.height &&
arraysEqual(nextProps.groups, this.props.groups) &&
arraysEqual(nextProps.groupHeights, this.props.groupHeights)
)

@@ -26,0 +26,0 @@ }

@@ -0,0 +0,0 @@ import React from 'react'

@@ -0,0 +0,0 @@ import React from 'react'

@@ -0,0 +0,0 @@ import React from 'react'

@@ -0,0 +0,0 @@ import React from 'react'

@@ -0,0 +0,0 @@ import React from 'react'

@@ -0,0 +0,0 @@ import React from 'react'

@@ -45,3 +45,3 @@ import React from 'react'

return {
markers: state.markers.filter(marker => marker !== newMarker)
markers: state.markers.filter(marker => marker.id !== newMarker.id)
}

@@ -48,0 +48,0 @@ })

@@ -0,0 +0,0 @@ import React, { PureComponent } from 'react'

@@ -0,0 +0,0 @@ import PropTypes from 'prop-types'

@@ -0,0 +0,0 @@ import React, { PureComponent } from 'react'

@@ -46,7 +46,4 @@ import PropTypes from 'prop-types'

minResizeWidth: PropTypes.number,
stickyOffset: PropTypes.number,
stickyHeader: PropTypes.bool,
lineHeight: PropTypes.number,
headerLabelGroupHeight: PropTypes.number,
headerLabelHeight: PropTypes.number,
itemHeightRatio: PropTypes.number,

@@ -65,3 +62,3 @@

stackItems: PropTypes.bool,
stackItems: PropTypes.oneOf([false,'space', 'lines']),

@@ -167,2 +164,3 @@ traditionalZoom: PropTypes.bool,

width: PropTypes.number,
onUpdateMove: PropTypes.func,
}

@@ -175,7 +173,4 @@

minResizeWidth: 20,
stickyOffset: 0,
stickyHeader: true,
lineHeight: 30,
headerLabelGroupHeight: 30,
headerLabelHeight: 30,
itemHeightRatio: 0.65,

@@ -245,3 +240,4 @@

selected: null
selected: null,
onUpdateMove: null,
}

@@ -282,2 +278,6 @@

this.getSelected = this.getSelected.bind(this)
this.hasSelectedItem = this.hasSelectedItem.bind(this)
this.isItemSelected= this.isItemSelected.bind(this)
let visibleTimeStart = null

@@ -599,3 +599,3 @@ let visibleTimeEnd = null

if (
this.state.selectedItem === item ||
this.isItemSelected(item) ||
(this.props.itemTouchSendsClick && clickType === 'touch')

@@ -648,2 +648,3 @@ ) {

canvasTimeStart,
canvasTimeEnd,

@@ -680,3 +681,5 @@ getCanvasWidth(width),

const keys = this.props.keys
if(this.props.onUpdateMove){
this.props.onUpdateMove(item, dragTime, newGroupOrder, 'move')
}
this.setState({

@@ -698,2 +701,5 @@ draggingItem: item,

resizingItem = (item, resizeTime, edge) => {
if(this.props.onUpdateMove){
this.props.onUpdateMove(item, resizeTime, undefined, 'resize', edge)
}
this.setState({

@@ -737,3 +743,3 @@ resizingItem: item,

// shouldnt this be handled by the user, as far as when to deselect an item?
if (this.state.selectedItem) {
if (this.hasSelectedItem()) {
this.selectItem(null)

@@ -900,3 +906,2 @@ }

height,
headerHeight,
visibleTimeStart,

@@ -928,8 +933,4 @@ visibleTimeEnd,

groupTops: groupTops,
selected:
this.state.selectedItem && !this.props.selected
? [this.state.selectedItem]
: this.props.selected || [],
selected: this.getSelected(),
height: height,
headerHeight: headerHeight,
minUnit: minUnit,

@@ -963,3 +964,3 @@ timeSteps: timeSteps

<SidebarHeader />
<DateHeader primaryHeader />
<DateHeader unit="primaryHeader" />
<DateHeader />

@@ -975,3 +976,18 @@ {this.props.rightSidebarWidth ? <SidebarHeader variant="right"/> : null}

}
getSelected() {
return this.state.selectedItem && !this.props.selected
? [this.state.selectedItem]
: this.props.selected || [];
}
hasSelectedItem(){
if(!Array.isArray(this.props.selected)) return !!this.state.selectedItem
return this.props.selected.length > 0
}
isItemSelected(itemId){
const selectedItems = this.getSelected()
return selectedItems.some(i => i === itemId)
}
render() {

@@ -981,4 +997,2 @@ const {

groups,
headerLabelGroupHeight,
headerLabelHeight,
sidebarWidth,

@@ -1003,3 +1017,2 @@ rightSidebarWidth,

const minUnit = getMinUnit(zoom, width, timeSteps)
const headerHeight = headerLabelGroupHeight + headerLabelHeight

@@ -1092,3 +1105,2 @@ const isInteractingWithItem = !!draggingItem || !!resizingItem

height,
headerHeight
)}

@@ -1105,3 +1117,2 @@ {this.rows(canvasWidth, groupHeights, groups)}

height,
headerHeight,
visibleTimeStart,

@@ -1108,0 +1119,0 @@ visibleTimeEnd,

@@ -0,0 +0,0 @@ import React from 'react'

@@ -72,3 +72,4 @@ import moment from 'moment'

let nextTime = moment(time).add(timeSteps[unit] || 1, `${unit}s`)
callback(time, nextTime)
let endTime = moment(time).endOf(`${unit}s`)
callback(time, endTime)
time = nextTime

@@ -152,6 +153,9 @@ }

day: 'month',
month: 'year'
month: 'year',
year: 'year'
}
return nextUnits[unit] || ''
if (!nextUnits[unit]) {
throw new Error(`unit ${unit} in not acceptable`)
}
return nextUnits[unit]
}

@@ -302,2 +306,26 @@

/**
* Calculate the position of a given item for a group that each in a line
* is being stacked
*/
export function groupStackInLines(
lineHeight,
item,
items,
groupHeight,
groupTop,
itemIndex
) {
// calculate non-overlapping positions
let verticalMargin = lineHeight - item.dimensions.height
if (item.dimensions.stack && item.dimensions.top === null) {
item.dimensions.top = groupTop + verticalMargin + itemIndex * lineHeight
}
return {
groupHeight: lineHeight * items.length,
verticalMargin,
itemTop: item.dimensions.top
}
}
/**
* Calculate the position of a given item for a group that

@@ -316,3 +344,3 @@ * is being stacked

let curHeight = groupHeight
let verticalMargin = lineHeight - item.dimensions.height
let verticalMargin = (lineHeight - item.dimensions.height) / 2
if (item.dimensions.stack && item.dimensions.top === null) {

@@ -343,3 +371,3 @@ item.dimensions.top = groupTop + verticalMargin

curHeight,
item.dimensions.top + item.dimensions.height - groupTop
item.dimensions.top + item.dimensions.height + verticalMargin - groupTop
)

@@ -354,3 +382,2 @@ }

}
}

@@ -405,3 +432,3 @@

} else {
groupHeights.push(Math.max(groupHeight + verticalMargin, lineHeight))
groupHeights.push(Math.max(groupHeight, lineHeight))
}

@@ -417,9 +444,14 @@ }

/**
*
* @param {*} itemsDimensions
* @param {*} isGroupStacked
* @param {*} lineHeight
* @param {*} groupTop
*
* @param {*} itemsDimensions
* @param {*} isGroupStacked
* @param {*} lineHeight
* @param {*} groupTop
*/
export function stackGroup(itemsDimensions, isGroupStacked, lineHeight, groupTop) {
export function stackGroup(
itemsDimensions,
isGroupStacked,
lineHeight,
groupTop
) {
var groupHeight = 0

@@ -430,3 +462,3 @@ var verticalMargin = 0

let r = {}
if (isGroupStacked) {
if (isGroupStacked === 'space') {
r = groupStack(

@@ -440,4 +472,18 @@ lineHeight,

)
} else if (isGroupStacked === 'lines') {
r = groupStackInLines(
lineHeight,
itemsDimensions[itemIndex],
itemsDimensions,
groupHeight,
groupTop,
itemIndex
)
} else {
r = groupNoStack(lineHeight, itemsDimensions[itemIndex], groupHeight, groupTop)
r = groupNoStack(
lineHeight,
itemsDimensions[itemIndex],
groupHeight,
groupTop
)
}

@@ -444,0 +490,0 @@ groupHeight = r.groupHeight

@@ -0,0 +0,0 @@ // TODO: can we use getBoundingClientRect instead??

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc