UNPKG

@chayns-components/devalue-slider

Version:
215 lines (212 loc) 8.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _core = require("@chayns-components/core"); var _size = _interopRequireDefault(require("@react-hook/size")); var _chaynsApi = require("chayns-api"); var _react = require("motion/react"); var _react2 = _interopRequireWildcard(require("react")); var _design = require("../../hooks/design"); var _common = require("../../utils/common"); var _Slider = require("./Slider.styles"); var _textstring = require("@chayns-components/textstring"); var _textStrings = _interopRequireDefault(require("../../constants/textStrings")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const Slider = /*#__PURE__*/(0, _react2.forwardRef)(({ color, devalueColor, trackHeight = 50, thumbSize = 40, borderSize = 2, trackText, onChange = () => {}, onDevalue = () => Promise.resolve({ success: true }), onComplete }, ref) => { const [trackRef, setTrackRef] = (0, _react2.useState)(null); const [trackWidth] = (0, _size.default)(trackRef, { initialWidth: 300, initialHeight: 50 }); const [iconColor, setIconColor] = (0, _react2.useState)('black'); const [isCompleted, setIsCompleted] = (0, _react2.useState)(false); const [isDisabled, setIsDisabled] = (0, _react2.useState)(false); const isCompletedRef = (0, _react2.useRef)(isCompleted); const [showWaitCursor, setShowWaitCursor] = (0, _react2.useState)(false); const scaleFactor = (0, _react2.useMemo)(() => trackHeight / thumbSize, [thumbSize, trackHeight]); const x = (0, _react.useMotionValue)(0); const { icon, styles: iconStyles } = (0, _design.useThumbIcon)(x, iconColor); const dragControls = (0, _react.useDragControls)(); const vibrationTrigger = (0, _react.useTransform)(x, // round to 10 to avoid unnecessary vibrate calls value => Math.round(value / 10) * 10); const lastVibrationValue = (0, _react2.useRef)(0); (0, _react2.useEffect)(() => { vibrationTrigger.on('change', value => { if (!isCompletedRef.current && value !== lastVibrationValue.current) { lastVibrationValue.current = value; void (0, _chaynsApi.vibrate)({ pattern: [10] }); } }); }, [vibrationTrigger]); const containerAnimation = (0, _react.useAnimation)(); const thumbVariants = (0, _react2.useMemo)(() => (0, _Slider.createThumbVariants)({ thumbSize, trackWidth, scaleFactor }), [scaleFactor, thumbSize, trackWidth]); const textOpacity = (0, _react.useTransform)(x, [0, 120], [1, 0]); // this is the relative value of the right edge of the thumb const relativeValue = (0, _react.useTransform)(x, value => { if (!value) return 0; const thumbRadius = thumbSize * scaleFactor; return parseFloat(((value + thumbRadius) / trackWidth * 100).toPrecision(2)); }); // this is the relative value of the center of the thumb, it is used for the background gradient const relativeBackgroundValue = (0, _react.useTransform)(x, value => { if (!value) return 0; const thumbRadius = thumbSize * scaleFactor / 2; return parseFloat(((value + thumbRadius) / trackWidth * 100).toPrecision(2)); }); const trackBackground = (0, _react.useTransform)(relativeBackgroundValue, value => { if (isCompleted) return devalueColor; if (!value) return 'transparent'; return `linear-gradient(to right, ${devalueColor} ${value}%, transparent ${value}%)`; }); const handlePointerDownCapture = (0, _react2.useCallback)(event => { const currentValue = relativeValue.get(); if (currentValue > 5) { event.preventDefault(); event.stopPropagation(); } void (0, _chaynsApi.invokeCall)({ action: 19, value: { pattern: [50], iOSFeedbackVibration: 7 } }); }, [relativeValue]); const handleRedeem = (0, _react2.useCallback)(async () => { setShowWaitCursor(true); setIsCompleted(true); isCompletedRef.current = true; const devaluePromise = onDevalue(); const sleepPromise = (0, _common.sleep)(1000); const [devalued] = await Promise.all([devaluePromise, sleepPromise]); if (!devalued.success) { setShowWaitCursor(false); setIsCompleted(false); isCompletedRef.current = false; await containerAnimation.start('base'); return; } setShowWaitCursor(false); setIconColor('white'); void (0, _chaynsApi.invokeCall)({ action: 19, value: { iOSFeedbackVibration: 3, pattern: [100, 200, 100] } }); await containerAnimation.start('completed'); await containerAnimation.start('leaving'); onComplete === null || onComplete === void 0 || onComplete(); }, [containerAnimation, onComplete, onDevalue]); const handleTrackRef = (0, _react2.useCallback)(node => { setTrackRef(node); }, []); const handleDragStart = (0, _react2.useCallback)(() => { void containerAnimation.start('dragging'); }, [containerAnimation]); const handleDragEnd = (0, _react2.useCallback)(() => { if (relativeValue.get() > 98) { void handleRedeem(); return; } void containerAnimation.start('base'); }, [relativeValue, containerAnimation, handleRedeem]); (0, _react2.useEffect)(() => { void containerAnimation.start('base'); }, [containerAnimation]); (0, _react2.useEffect)(() => { if (isCompleted) return () => {}; return relativeValue.on('change', onChange); }, [isCompleted, onChange, relativeValue]); (0, _react2.useImperativeHandle)(ref, () => ({ disable: () => { setIsDisabled(true); setShowWaitCursor(false); setIsCompleted(false); isCompletedRef.current = false; void containerAnimation.start('base'); }, enable: () => { setIsDisabled(false); } }), [containerAnimation]); const baseFontSize = (0, _react2.useMemo)(() => 22, []); return /*#__PURE__*/_react2.default.createElement(_Slider.Container, { animate: containerAnimation }, /*#__PURE__*/_react2.default.createElement(_Slider.Track, { $height: trackHeight, $borderSize: borderSize, $backgroundColor: color, ref: handleTrackRef }, /*#__PURE__*/_react2.default.createElement(_Slider.TrackBackground, { $height: trackHeight, style: { background: trackBackground } }), /*#__PURE__*/_react2.default.createElement(_Slider.Thumb, { variants: thumbVariants, $size: thumbSize, $trackHeight: trackHeight, style: { x }, drag: isCompleted || isDisabled ? false : 'x', dragElastic: 0, onPointerDownCapture: handlePointerDownCapture, whileTap: { scale: 1.4, cursor: 'grabbing' }, onDragStart: handleDragStart, onDragEnd: handleDragEnd, dragControls: dragControls, dragConstraints: { right: trackWidth - thumbSize * scaleFactor, left: 0 } }, /*#__PURE__*/_react2.default.createElement(_Slider.ThumbIconContainer, null, !showWaitCursor && /*#__PURE__*/_react2.default.createElement(_Slider.ThumbIcon, { key: "thumb-icon", icon: icon, variants: _Slider.THUMB_ICON_VARIANTS, style: iconStyles }), showWaitCursor && /*#__PURE__*/_react2.default.createElement(_core.SmallWaitCursor, { shouldHideBackground: true, color: "black" }))), /*#__PURE__*/_react2.default.createElement(_Slider.TrackText, { style: { opacity: textOpacity }, $color: "white", $baseFontSize: baseFontSize }, trackText ?? /*#__PURE__*/_react2.default.createElement(_textstring.Textstring, { textstring: (0, _textstring.ttsToITextString)(_textStrings.default.components.slider.tracktext) })))); }); var _default = exports.default = Slider; //# sourceMappingURL=Slider.js.map