react-native-paper-dates
Version:
Performant Date Picker for React Native Paper
184 lines (179 loc) • 6.94 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _color = _interopRequireDefault(require("color"));
var _reactNative = require("react-native");
var _reactNativePaper = require("react-native-paper");
var _timeUtils = require("./timeUtils");
var _utils = require("../shared/utils");
var _AnalogClockHours = _interopRequireDefault(require("./AnalogClockHours"));
var _AnimatedClockSwitcher = _interopRequireDefault(require("./AnimatedClockSwitcher"));
var _AnalogClockMinutes = _interopRequireDefault(require("./AnalogClockMinutes"));
var _DisplayModeContext = require("../contexts/DisplayModeContext");
var _react = require("react");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function returnTrue() {
return true;
}
function AnalogClock({
hours,
minutes,
focused,
is24Hour,
onChange
}) {
const shortPointer = hours >= 12 && is24Hour;
const theme = (0, _reactNativePaper.useTheme)();
const {
mode
} = (0, _react.useContext)(_DisplayModeContext.DisplayModeContext);
// used to make pointer shorter if hours are selected and above 12
const clockRef = (0, _react.useRef)(null);
// Hooks are nice, sometimes... :-)..
// We need the latest values, since the onPointerMove uses a closure to the function
const hoursRef = (0, _utils.useLatest)(hours);
const onChangeRef = (0, _utils.useLatest)(onChange);
const minutesRef = (0, _utils.useLatest)(minutes);
const focusedRef = (0, _utils.useLatest)(focused);
const is24HourRef = (0, _utils.useLatest)(is24Hour);
const modeRef = (0, _utils.useLatest)(mode);
const onPointerMove = (0, _react.useCallback)((e, final) => {
let x = e.nativeEvent.locationX;
let y = e.nativeEvent.locationY;
let angle = (0, _timeUtils.getAngle)(x, y, _timeUtils.circleSize);
if (focusedRef.current === _timeUtils.clockTypes.hours) {
let hours24 = is24HourRef.current;
let previousHourType = (0, _timeUtils.getHourType)(hoursRef.current);
let pickedHours = (0, _timeUtils.getHours)(angle, previousHourType);
let hours12AndPm = !hours24 && modeRef.current === 'PM';
let hourTypeFromOffset = (0, _timeUtils.getHourTypeFromOffset)(x, y, _timeUtils.circleSize);
let hours24AndPM = hours24 && hourTypeFromOffset === _timeUtils.hourTypes.pm;
// Avoiding the "24h"
// Should be 12h for 12 hours and PM mode
if (hours12AndPm || hours24AndPM) {
pickedHours += 12;
}
if ((modeRef.current === 'AM' || hours24) && pickedHours === 12) {
pickedHours = 0;
}
if (!hours24 && modeRef.current === 'AM' && pickedHours === 12) {
pickedHours = 0;
}
if (pickedHours === 24) {
pickedHours = 12;
}
if (hoursRef.current !== pickedHours || final) {
onChangeRef.current({
hours: pickedHours,
minutes: minutesRef.current,
focused: final ? _timeUtils.clockTypes.minutes : undefined
});
}
} else if (focusedRef.current === _timeUtils.clockTypes.minutes) {
let pickedMinutes = (0, _timeUtils.getMinutes)(angle);
if (minutesRef.current !== pickedMinutes) {
onChangeRef.current({
hours: hoursRef.current,
minutes: pickedMinutes
});
}
}
}, [focusedRef, is24HourRef, hoursRef, onChangeRef, minutesRef, modeRef]);
const panResponder = (0, _react.useRef)(_reactNative.PanResponder.create({
onPanResponderGrant: e => onPointerMove(e, false),
onPanResponderMove: e => onPointerMove(e, false),
onPanResponderRelease: e => onPointerMove(e, true),
onStartShouldSetPanResponder: returnTrue,
onStartShouldSetPanResponderCapture: () => false,
onMoveShouldSetPanResponder: returnTrue,
onMoveShouldSetPanResponderCapture: returnTrue,
onPanResponderTerminationRequest: returnTrue,
onShouldBlockNativeResponder: returnTrue
})).current;
const dynamicSize = focused === _timeUtils.clockTypes.hours && shortPointer ? 33 : 0;
const pointerNumber = focused === _timeUtils.clockTypes.hours ? hours : minutes;
const degreesPerNumber = focused === _timeUtils.clockTypes.hours ? 30 : 6;
const v3Color = theme.colors.surfaceVariant;
const v2Color = theme.dark ? (0, _color.default)(theme.colors.surface).lighten(1.4).hex() : (0, _color.default)(theme.colors.surface).darken(0.1).hex();
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
ref: clockRef,
...panResponder.panHandlers,
style: [styles.clock, {
backgroundColor: theme.isV3 ? v3Color : v2Color
}]
// @ts-ignore -> https://github.com/necolas/react-native-web/issues/506
,
cursor: 'pointer',
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [styles.line, {
backgroundColor: theme.colors.primary,
transform: [{
rotate: -90 + pointerNumber * degreesPerNumber + 'deg'
}, {
translateX: _timeUtils.circleSize / 4 - (focused === _timeUtils.clockTypes.hours && pointerNumber >= 0 && pointerNumber < 13 ? 0 : 4) + (focused === _timeUtils.clockTypes.minutes ? 4 : 0) - dynamicSize / 2
}],
width: _timeUtils.circleSize / 2 - 4 - dynamicSize
}],
pointerEvents: "none",
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [styles.endPoint, {
backgroundColor: theme.colors.primary
}]
})
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [_reactNative.StyleSheet.absoluteFill, styles.center],
pointerEvents: "none",
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [styles.middlePoint, {
backgroundColor: theme.colors.primary
}]
})
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_AnimatedClockSwitcher.default, {
focused: focused,
hours: /*#__PURE__*/(0, _jsxRuntime.jsx)(_AnalogClockHours.default, {
is24Hour: is24Hour,
hours: hours
}),
minutes: /*#__PURE__*/(0, _jsxRuntime.jsx)(_AnalogClockMinutes.default, {
minutes: minutes
})
})]
});
}
const styles = _reactNative.StyleSheet.create({
center: {
alignItems: 'center',
justifyContent: 'center'
},
clock: {
alignItems: 'center',
borderRadius: _timeUtils.circleSize / 2,
height: _timeUtils.circleSize,
justifyContent: 'center',
position: 'relative',
width: _timeUtils.circleSize
},
endPoint: {
borderRadius: 24,
bottom: -23,
height: 48,
position: 'absolute',
right: 0,
width: 48
},
line: {
borderRadius: 4,
height: 2,
position: 'absolute'
},
middlePoint: {
borderRadius: 4,
height: 8,
width: 8
}
});
var _default = exports.default = /*#__PURE__*/(0, _react.memo)(AnalogClock);
//# sourceMappingURL=AnalogClock.js.map