ph-material-pickers
Version:
React components, that implements material design pickers for material-ui v4
475 lines (416 loc) • 15.9 kB
JavaScript
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
import { createContext, createElement, Component, useContext, useRef, useMemo, Fragment } from 'react';
import { bool, number } from 'prop-types';
import { V as VIEW_HEIGHT, b as useDefaultProps, u as useUtils } from './dimensions-f39eca69.js';
import _extends from '@babel/runtime/helpers/esm/extends';
import clsx from 'clsx';
import Typography from '@material-ui/core/Typography';
import { withStyles, createStyles, makeStyles } from '@material-ui/core/styles';
import IconButton from '@material-ui/core/IconButton';
import { u as useGlobalKeyDown, k as keycode } from './useKeyDown-5aaf69f9.js';
import _classCallCheck from '@babel/runtime/helpers/esm/classCallCheck';
import _createClass from '@babel/runtime/helpers/esm/createClass';
import _inherits from '@babel/runtime/helpers/esm/inherits';
import _possibleConstructorReturn from '@babel/runtime/helpers/esm/possibleConstructorReturn';
import _getPrototypeOf from '@babel/runtime/helpers/esm/getPrototypeOf';
// consider getting rid from wrapper variant
var WrapperVariantContext = createContext(null);
var IsStaticVariantContext = createContext(false);
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function () { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
var styles = function styles(theme) {
return createStyles({
pointer: {
width: 2,
backgroundColor: theme.palette.primary.main,
position: 'absolute',
left: 'calc(50% - 1px)',
bottom: '50%',
transformOrigin: 'center bottom 0px'
},
animateTransform: {
transition: theme.transitions.create(['transform', 'height'])
},
thumb: {
width: 4,
height: 4,
backgroundColor: theme.palette.primary.contrastText,
borderRadius: '100%',
position: 'absolute',
top: -21,
left: -15,
border: "14px solid ".concat(theme.palette.primary.main),
boxSizing: 'content-box'
},
noPoint: {
backgroundColor: theme.palette.primary.main
}
});
};
var ClockPointer = /*#__PURE__*/function (_React$Component) {
_inherits(ClockPointer, _React$Component);
var _super = _createSuper(ClockPointer);
function ClockPointer() {
var _this;
_classCallCheck(this, ClockPointer);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _super.call.apply(_super, [this].concat(args));
_this.state = {
toAnimateTransform: false,
// eslint-disable-next-line react/no-unused-state
previousType: undefined
};
_this.getAngleStyle = function () {
var _this$props = _this.props,
value = _this$props.value,
isInner = _this$props.isInner,
type = _this$props.type;
var max = type === 'hours' ? 12 : 60;
var angle = 360 / max * value;
if (type === 'hours' && value > 12) {
angle -= 360; // round up angle to max 360 degrees
}
return {
height: isInner ? '26%' : '40%',
transform: "rotateZ(".concat(angle, "deg)")
};
};
return _this;
}
_createClass(ClockPointer, [{
key: "render",
value: function render() {
var _this$props2 = this.props,
classes = _this$props2.classes,
hasSelected = _this$props2.hasSelected,
isInner = _this$props2.isInner,
type = _this$props2.type,
value = _this$props2.value,
other = _objectWithoutProperties(_this$props2, ["classes", "hasSelected", "isInner", "type", "value"]);
return /*#__PURE__*/createElement("div", _extends({}, other, {
style: this.getAngleStyle(),
className: clsx(classes.pointer, this.state.toAnimateTransform && classes.animateTransform)
}), /*#__PURE__*/createElement("div", {
className: clsx(classes.thumb, hasSelected && classes.noPoint)
}));
}
}]);
return ClockPointer;
}(Component);
ClockPointer.getDerivedStateFromProps = function (nextProps, state) {
if (nextProps.type !== state.previousType) {
return {
toAnimateTransform: true,
previousType: nextProps.type
};
}
return {
toAnimateTransform: false,
previousType: nextProps.type
};
};
var ClockPointer$1 = withStyles(styles, {
name: 'MuiPickersClockPointer'
})(ClockPointer);
var getMeridiem = function getMeridiem(date, utils) {
if (!date) {
return null;
}
return utils.getHours(date) >= 12 ? 'pm' : 'am';
};
var convertValueToMeridiem = function convertValueToMeridiem(value, meridiem, ampm) {
if (ampm) {
var currentMeridiem = value >= 12 ? 'pm' : 'am';
if (currentMeridiem !== meridiem) {
return meridiem === 'am' ? value - 12 : value + 12;
}
}
return value;
};
var convertToMeridiem = function convertToMeridiem(time, meridiem, ampm, utils) {
var newHoursAmount = convertValueToMeridiem(utils.getHours(time), meridiem, ampm);
return utils.setHours(time, newHoursAmount);
};
var clockCenter = {
x: 260 / 2,
y: 260 / 2
};
var baseClockPoint = {
x: clockCenter.x,
y: 0
};
var cx = baseClockPoint.x - clockCenter.x;
var cy = baseClockPoint.y - clockCenter.y;
var rad2deg = function rad2deg(rad) {
return rad * 57.29577951308232;
};
var getAngleValue = function getAngleValue(step, offsetX, offsetY) {
var x = offsetX - clockCenter.x;
var y = offsetY - clockCenter.y;
var atan = Math.atan2(cx, cy) - Math.atan2(x, y);
var deg = rad2deg(atan);
deg = Math.round(deg / step) * step;
deg %= 360;
var value = Math.floor(deg / step) || 0;
var delta = Math.pow(x, 2) + Math.pow(y, 2);
var distance = Math.sqrt(delta);
return {
value: value,
distance: distance
};
};
var getMinutes = function getMinutes(offsetX, offsetY) {
var step = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
var angleStep = step * 6;
var _getAngleValue = getAngleValue(angleStep, offsetX, offsetY),
value = _getAngleValue.value;
value = value * step % 60;
return value;
};
var getHours = function getHours(offsetX, offsetY, ampm) {
var _getAngleValue2 = getAngleValue(30, offsetX, offsetY),
value = _getAngleValue2.value,
distance = _getAngleValue2.distance;
var hour = value || 12;
if (!ampm) {
if (distance < 90) {
hour += 12;
hour %= 24;
}
} else {
hour %= 12;
}
return hour;
};
function getSecondsInDay(date, utils) {
return utils.getHours(date) * 3600 + utils.getMinutes(date) * 60 + utils.getSeconds(date);
}
var createIsAfterIgnoreDatePart = function createIsAfterIgnoreDatePart(disableIgnoringDatePartForTimeValidation, utils) {
return function (dateLeft, dateRight) {
if (disableIgnoringDatePartForTimeValidation) {
return utils.isAfter(dateLeft, dateRight);
}
return getSecondsInDay(dateLeft, utils) > getSecondsInDay(dateRight, utils);
};
};
var validateTime = function validateTime(utils, value, _ref) {
var minTime = _ref.minTime,
maxTime = _ref.maxTime,
shouldDisableTime = _ref.shouldDisableTime,
disableIgnoringDatePartForTimeValidation = _ref.disableIgnoringDatePartForTimeValidation;
var date = utils.date(value);
var isAfterComparingFn = createIsAfterIgnoreDatePart(Boolean(disableIgnoringDatePartForTimeValidation), utils);
if (value === null) {
return null;
}
switch (true) {
case !utils.isValid(value):
return 'invalidDate';
case Boolean(minTime && isAfterComparingFn(minTime, date)):
return 'minTime';
case Boolean(maxTime && isAfterComparingFn(date, maxTime)):
return 'maxTime';
case Boolean(shouldDisableTime && shouldDisableTime(utils.getHours(date), 'hours')):
return 'shouldDisableTime-hours';
case Boolean(shouldDisableTime && shouldDisableTime(utils.getMinutes(date), 'minutes')):
return 'shouldDisableTime-minutes';
case Boolean(shouldDisableTime && shouldDisableTime(utils.getSeconds(date), 'seconds')):
return 'shouldDisableTime-seconds';
default:
return null;
}
};
var muiComponentConfig = {
name: 'MuiPickersClock'
};
var useStyles = makeStyles(function (theme) {
return {
root: {
display: 'flex',
justifyContent: 'center',
position: 'relative',
minHeight: VIEW_HEIGHT,
alignItems: 'center'
},
clock: {
backgroundColor: 'rgba(0,0,0,.07)',
borderRadius: '50%',
height: 260,
width: 260,
position: 'relative',
pointerEvents: 'none'
},
squareMask: {
width: '100%',
height: '100%',
position: 'absolute',
pointerEvents: 'auto',
outline: 'none',
touchActions: 'none',
userSelect: 'none',
'&:active': {
cursor: 'move'
}
},
pin: {
width: 6,
height: 6,
borderRadius: '50%',
backgroundColor: theme.palette.primary.main,
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)'
},
amButton: {
zIndex: 1,
left: 8,
position: 'absolute',
bottom: 8
},
pmButton: {
zIndex: 1,
position: 'absolute',
bottom: 8,
right: 8
},
meridiemButtonSelected: {
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastText,
'&:hover': {
backgroundColor: theme.palette.primary.light
}
}
};
}, muiComponentConfig);
function Clock(props) {
var _useGlobalKeyDown;
var _useDefaultProps = useDefaultProps(props, muiComponentConfig),
allowKeyboardControl = _useDefaultProps.allowKeyboardControl,
ampm = _useDefaultProps.ampm,
_useDefaultProps$ampm = _useDefaultProps.ampmInClock,
ampmInClock = _useDefaultProps$ampm === void 0 ? false : _useDefaultProps$ampm,
numbersElementsArray = _useDefaultProps.children,
date = _useDefaultProps.date,
handleMeridiemChange = _useDefaultProps.handleMeridiemChange,
isTimeDisabled = _useDefaultProps.isTimeDisabled,
meridiemMode = _useDefaultProps.meridiemMode,
_useDefaultProps$minu = _useDefaultProps.minutesStep,
minutesStep = _useDefaultProps$minu === void 0 ? 1 : _useDefaultProps$minu,
onChange = _useDefaultProps.onChange,
type = _useDefaultProps.type,
value = _useDefaultProps.value;
var utils = useUtils();
var classes = useStyles();
var wrapperVariant = useContext(WrapperVariantContext);
var isMoving = useRef(false);
var isSelectedTimeDisabled = isTimeDisabled(value, type);
var isPointerInner = !ampm && type === 'hours' && (value < 1 || value > 12);
var handleValueChange = function handleValueChange(newValue, isFinish) {
if (isTimeDisabled(newValue, type)) {
return;
}
onChange(newValue, isFinish);
};
var setTime = function setTime(e, isFinish) {
var offsetX = e.offsetX,
offsetY = e.offsetY;
if (typeof offsetX === 'undefined') {
var rect = e.target.getBoundingClientRect();
offsetX = e.changedTouches[0].clientX - rect.left;
offsetY = e.changedTouches[0].clientY - rect.top;
}
var value = type === 'seconds' || type === 'minutes' ? getMinutes(offsetX, offsetY, minutesStep) : getHours(offsetX, offsetY, Boolean(ampm));
handleValueChange(value, isFinish);
};
var handleTouchMove = function handleTouchMove(e) {
isMoving.current = true;
setTime(e, 'shallow');
};
var handleTouchEnd = function handleTouchEnd(e) {
if (isMoving.current) {
setTime(e, 'finish');
isMoving.current = false;
}
};
var handleMouseMove = function handleMouseMove(e) {
e.preventDefault();
e.stopPropagation(); // MouseEvent.which is deprecated, but MouseEvent.buttons is not supported in Safari
var isButtonPressed = typeof e.buttons === 'undefined' ? e.nativeEvent.which === 1 : e.buttons === 1;
if (isButtonPressed) {
setTime(e.nativeEvent, 'shallow');
}
};
var handleMouseUp = function handleMouseUp(e) {
if (isMoving.current) {
isMoving.current = false;
}
setTime(e.nativeEvent, 'finish');
};
var hasSelected = useMemo(function () {
if (type === 'hours') {
return true;
}
return value % 5 === 0;
}, [type, value]);
var keyboardControlStep = type === 'minutes' ? minutesStep : 1;
useGlobalKeyDown(Boolean(allowKeyboardControl !== null && allowKeyboardControl !== void 0 ? allowKeyboardControl : wrapperVariant !== 'static') && !isMoving.current, (_useGlobalKeyDown = {}, _defineProperty(_useGlobalKeyDown, keycode.Home, function () {
return handleValueChange(0, 'partial');
}), _defineProperty(_useGlobalKeyDown, keycode.End, function () {
return handleValueChange(type === 'minutes' ? 59 : 23, 'partial');
}), _defineProperty(_useGlobalKeyDown, keycode.ArrowUp, function () {
return handleValueChange(value + keyboardControlStep, 'partial');
}), _defineProperty(_useGlobalKeyDown, keycode.ArrowDown, function () {
return handleValueChange(value - keyboardControlStep, 'partial');
}), _useGlobalKeyDown));
return /*#__PURE__*/createElement("div", {
className: classes.root
}, /*#__PURE__*/createElement("div", {
className: classes.clock
}, /*#__PURE__*/createElement("div", {
role: "menu",
tabIndex: -1,
className: classes.squareMask,
onTouchMove: handleTouchMove,
onTouchEnd: handleTouchEnd,
onMouseUp: handleMouseUp,
onMouseMove: handleMouseMove
}), !isSelectedTimeDisabled && /*#__PURE__*/createElement(Fragment, null, /*#__PURE__*/createElement("div", {
className: classes.pin
}), date && /*#__PURE__*/createElement(ClockPointer$1, {
type: type,
value: value,
isInner: isPointerInner,
hasSelected: hasSelected,
"aria-live": "polite",
"aria-label": "Selected time ".concat(utils.format(date, 'fullTime'))
})), numbersElementsArray), ampm && (wrapperVariant === 'desktop' || ampmInClock) && /*#__PURE__*/createElement(Fragment, null, /*#__PURE__*/createElement(IconButton, {
"data-mui-test": "in-clock-am-btn",
onClick: function onClick() {
return handleMeridiemChange('am');
},
disabled: meridiemMode === null,
className: clsx(classes.amButton, meridiemMode === 'am' && classes.meridiemButtonSelected)
}, /*#__PURE__*/createElement(Typography, {
variant: "caption"
}, "AM")), /*#__PURE__*/createElement(IconButton, {
disabled: meridiemMode === null,
"data-mui-test": "in-clock-pm-btn",
onClick: function onClick() {
return handleMeridiemChange('pm');
},
className: clsx(classes.pmButton, meridiemMode === 'pm' && classes.meridiemButtonSelected)
}, /*#__PURE__*/createElement(Typography, {
variant: "caption"
}, "PM"))));
}
process.env.NODE_ENV !== "production" ? Clock.propTypes = {
ampm: bool,
minutesStep: number
} : void 0;
Clock.displayName = 'Clock';
export { Clock as C, IsStaticVariantContext as I, WrapperVariantContext as W, createIsAfterIgnoreDatePart as a, convertValueToMeridiem as b, convertToMeridiem as c, getMeridiem as g, useStyles as u, validateTime as v };
//# sourceMappingURL=Clock-c2c3c22b.js.map