UNPKG

reanimated-color-picker

Version:
243 lines (233 loc) 7.44 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true, }); exports.default = void 0; var _react = _interopRequireWildcard(require('react')); var _reactNative = require('react-native'); var _reactNativeGestureHandler = require('react-native-gesture-handler'); var _reactNativeReanimated = require('react-native-reanimated'); var _index = _interopRequireDefault(require('./colorKit/index')); var _AppContext = require('./AppContext'); var _utils = require('./utils'); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } 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); } // @ts-expect-error no global if (_utils.isWeb && !global.setImmediate) { // @ts-expect-error no global global.setImmediate = setTimeout; } function ColorPickerWrapper(props, ref) { const { adaptSpectrum = false, sliderThickness = 25, thumbAnimationDuration = 200, thumbSize = 35, thumbShape = 'ring', boundedThumb = false, thumbScaleAnimationValue = 1.2, thumbScaleAnimationDuration = 100, thumbColor, renderThumb, thumbStyle, thumbInnerStyle, value = '#fff', colorAnnouncementFormat = 'rgb', enableColorAnnouncements = true, onChange, onChangeJS, onComplete, onCompleteJS, style = {}, children = /*#__PURE__*/ _react.default.createElement(_reactNative.Text, null, 'NO CHILDREN'), } = props; const initialColor = (0, _react.useRef)(_index.default.HSV(value).object(false)).current; const hueValue = (0, _reactNativeReanimated.useSharedValue)(initialColor.h); const saturationValue = (0, _reactNativeReanimated.useSharedValue)(initialColor.s); const brightnessValue = (0, _reactNativeReanimated.useSharedValue)(initialColor.v); const alphaValue = (0, _reactNativeReanimated.useSharedValue)(initialColor.a); /** * Returns lazy getters for the provided color in multiple formats. * * @worklet */ const colorResult = inputColor => { 'worklet'; const color = inputColor ?? { h: hueValue.value, s: saturationValue.value, v: brightnessValue.value, a: alphaValue.value, }; return { get hex() { return _index.default.runOnUI().HEX(color); }, get rgb() { return _index.default.runOnUI().RGB(color).string(false); }, get rgba() { return _index.default.runOnUI().RGB(color).string(true); }, get hsl() { return _index.default.runOnUI().HSL(color).string(false); }, get hsla() { return _index.default.runOnUI().HSL(color).string(true); }, get hsv() { return _index.default.runOnUI().HSV(color).string(false); }, get hsva() { return _index.default.runOnUI().HSV(color).string(true); }, get hwb() { return _index.default.runOnUI().HWB(color).string(false); }, get hwba() { return _index.default.runOnUI().HWB(color).string(true); }, }; }; const announceColor = color => { _reactNative.AccessibilityInfo.announceForAccessibility(color); }; /** @worklet */ const onGestureEnd = color => { 'worklet'; const colorObject = colorResult(color); if (enableColorAnnouncements && colorAnnouncementFormat in colorObject) { (0, _reactNativeReanimated.runOnJS)(announceColor)(colorObject[colorAnnouncementFormat]); } if (onComplete) { onComplete(colorObject); } if (onCompleteJS) { (0, _reactNativeReanimated.runOnJS)(onCompleteJS)(colorObject); } }; /** @worklet */ const onGestureChange = color => { 'worklet'; if (!onChange && !onChangeJS) { return; } const colorObject = colorResult(color); if (onChange) { onChange(colorObject); } if (onChangeJS) { (0, _reactNativeReanimated.runOnJS)(onChangeJS)(colorObject); } }; const setColor = (color, duration = thumbAnimationDuration) => { const { h, s, v, a } = _index.default.HSV(color).object(false); hueValue.value = (0, _reactNativeReanimated.withTiming)(h, { duration, }); saturationValue.value = (0, _reactNativeReanimated.withTiming)(s, { duration, }); brightnessValue.value = (0, _reactNativeReanimated.withTiming)(v, { duration, }); alphaValue.value = (0, _reactNativeReanimated.withTiming)(a, { duration, }); }; // Prevent color shift caused by precision loss during format conversion. // The color picker operates in HSV internally, so any incoming color is converted // to HSV and back to the target format on every render. This round-trip can produce // slightly different values than the original, causing sliders to drift. Before // calling setColor, we convert the current color to the incoming format and compare // channel values — if they match, the colors are perceptually identical and we skip // the update. (0, _react.useEffect)(() => { const incomingColor = _index.default.parse(value); if (!incomingColor) { return setColor(value); } const HEX_FORMATS = new Set(['hex3', 'hex4', 'hex6', 'hex8', 'named']); const incomingFormat = HEX_FORMATS.has(incomingColor.format) ? 'hex' : incomingColor.format; const currentColor = _index.default.parse(colorResult()[incomingFormat] ?? ''); if (!currentColor) { return setColor(value); } const isEqual = Object.keys(incomingColor.value).length === Object.keys(currentColor.value).length && Object.entries(incomingColor.value).every(([k, v]) => currentColor.value[k] === v); if (!isEqual) { setColor(value); } }, [value]); (0, _react.useImperativeHandle)(ref, () => ({ setColor, })); const ctxValue = { hueValue, saturationValue, brightnessValue, alphaValue, adaptSpectrum, sliderThickness, thumbSize, thumbShape, boundedThumb, thumbColor, renderThumb, thumbStyle, thumbInnerStyle, thumbScaleAnimationValue, thumbScaleAnimationDuration, value, setColor, colorResult, onGestureEnd, onGestureChange, }; return /*#__PURE__*/ _react.default.createElement( _reactNativeGestureHandler.GestureHandlerRootView, { style: [ { direction: _utils.isWeb ? 'ltr' : undefined, }, style, ], }, /*#__PURE__*/ _react.default.createElement( _AppContext.PickerContextProvider, { value: ctxValue, }, children, ), ); } /** @see [ColorPicker](https://alabsi91.github.io/reanimated-color-picker/api/color-picker-wrapper/) */ const ColorPicker = /*#__PURE__*/ (0, _react.forwardRef)(ColorPickerWrapper); var _default = (exports.default = ColorPicker);