UNPKG

@storybook/addon-ondevice-controls

Version:

Display storybook controls on your device.

218 lines (217 loc) 9.52 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.HoloColorPicker = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const slider_1 = __importDefault(require("@react-native-community/slider")); const react_1 = require("react"); const react_native_1 = require("react-native"); const tinycolor2_1 = __importDefault(require("tinycolor2")); const utils_1 = require("./utils"); class HoloColorPicker extends react_1.PureComponent { _layout; _pageX; _pageY; _isRTL; _pickerResponder; pickerContainer = (0, react_1.createRef)(); constructor(props) { super(props); const state = { color: { h: 0, s: 1, v: 1 }, pickerSize: null, }; if (props.oldColor) { state.color = (0, tinycolor2_1.default)(props.oldColor).toHsv(); } if (props.defaultColor) { state.color = (0, tinycolor2_1.default)(props.defaultColor).toHsv(); } this.state = state; this._layout = { width: 0, height: 0, x: 0, y: 0 }; this._pageX = 0; this._pageY = 0; this._isRTL = react_native_1.I18nManager.isRTL; this._pickerResponder = (0, utils_1.createPanResponder)({ onStart: this._handleColorChange, onMove: this._handleColorChange, }); } getColor() { return (0, tinycolor2_1.default)(this._getColor()).toHexString(); } _handleColorChange = ({ x, y }) => { const { s, v } = this._getColor(); const marginLeft = (this._layout.width - (this.state.pickerSize ?? 0)) / 2; const marginTop = (this._layout.height - (this.state.pickerSize ?? 0)) / 2; const relativeX = x - this._pageX - marginLeft; const relativeY = y - this._pageY - marginTop; const h = this._computeHValue(relativeX, relativeY); this._onColorChange({ h, s, v }); }; _onSValueChange = (s) => { const { h, v } = this._getColor(); this._onColorChange({ h, s, v }); }; _onVValueChange = (v) => { const { h, s } = this._getColor(); this._onColorChange({ h, s, v }); }; _onColorChange = (color) => { this.setState({ color }); if (this.props.onColorChange) { this.props.onColorChange(color); } }; _onLayout = (l) => { this._layout = l.nativeEvent.layout; const { width, height } = this._layout; const pickerSize = Math.min(width, height); if (this.state.pickerSize !== pickerSize) { this.setState({ pickerSize }); } react_native_1.InteractionManager.runAfterInteractions(() => { if (this.pickerContainer.current) { this.pickerContainer.current.measure((_x, _y, _width, _height, pageX, pageY) => { this._pageX = pageX; this._pageY = pageY; }); } }); }; _getColor() { const passedColor = typeof this.props.color === 'string' ? (0, tinycolor2_1.default)(this.props.color).toHsv() : this.props.color; return passedColor || this.state.color; } _onColorSelected = () => { const { onColorSelected } = this.props; const color = (0, tinycolor2_1.default)(this._getColor()).toHexString(); if (onColorSelected) { onColorSelected(color); } }; _onOldColorSelected = () => { const { oldColor, onOldColorSelected } = this.props; const color = (0, tinycolor2_1.default)(oldColor); this.setState({ color: color.toHsv() }); if (onOldColorSelected) { onOldColorSelected(color.toHexString()); } }; _computeHValue(x, y) { const mx = (this.state.pickerSize ?? 0) / 2; const my = (this.state.pickerSize ?? 0) / 2; const dx = x - mx; const dy = y - my; const rad = Math.atan2(dx, dy) + Math.PI + Math.PI / 2; return ((rad * 180) / Math.PI) % 360; } _hValueToRad(deg) { const rad = (deg * Math.PI) / 180; return rad - Math.PI - Math.PI / 2; } render() { const { pickerSize } = this.state; const { oldColor, style } = this.props; const color = this._getColor(); const { h, s, v } = color; const angle = this._hValueToRad(h); const selectedColor = (0, tinycolor2_1.default)(color).toHexString(); const indicatorColor = (0, tinycolor2_1.default)({ h, s: 1, v: 1 }).toHexString(); const computed = makeComputedStyles({ pickerSize: pickerSize ?? 0, selectedColor, indicatorColor, oldColor, angle, isRTL: this._isRTL, }); return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: style, children: [(0, jsx_runtime_1.jsx)(react_native_1.View, { onLayout: this._onLayout, ref: this.pickerContainer, style: styles.pickerContainer, children: !pickerSize ? null : ((0, jsx_runtime_1.jsxs)(react_native_1.View, { children: [(0, jsx_runtime_1.jsxs)(react_native_1.View, { ...this._pickerResponder.panHandlers, style: [computed.picker], collapsable: false, children: [(0, jsx_runtime_1.jsx)(react_native_1.Image, { source: require('./resources/color-circle.png'), resizeMode: "contain", style: [styles.pickerImage] }), (0, jsx_runtime_1.jsx)(react_native_1.View, { style: [styles.pickerIndicator, computed.pickerIndicator] })] }), oldColor && ((0, jsx_runtime_1.jsx)(react_native_1.TouchableOpacity, { style: [styles.selectedPreview, computed.selectedPreview], onPress: this._onColorSelected, activeOpacity: 0.7 })), oldColor && ((0, jsx_runtime_1.jsx)(react_native_1.TouchableOpacity, { style: [styles.originalPreview, computed.originalPreview], onPress: this._onOldColorSelected, activeOpacity: 0.7 })), !oldColor && ((0, jsx_runtime_1.jsx)(react_native_1.TouchableOpacity, { style: [styles.selectedFullPreview, computed.selectedFullPreview], onPress: this._onColorSelected, activeOpacity: 0.7 }))] })) }), this.props.hideSliders ? null : ((0, jsx_runtime_1.jsxs)(react_native_1.View, { children: [(0, jsx_runtime_1.jsx)(react_native_1.Text, { style: { paddingStart: 4, color: '#859499', fontSize: 12 }, children: "Saturation" }), (0, jsx_runtime_1.jsx)(slider_1.default, { value: s, onValueChange: this._onSValueChange }), (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: { paddingStart: 4, color: '#859499', fontSize: 12 }, children: "Lightness" }), (0, jsx_runtime_1.jsx)(slider_1.default, { value: v, onValueChange: this._onVValueChange })] }))] })); } } exports.HoloColorPicker = HoloColorPicker; const makeComputedStyles = ({ indicatorColor, selectedColor, oldColor, angle, pickerSize, isRTL, }) => { const summarySize = 0.5 * pickerSize; const indicatorPickerRatio = 42 / 510; const indicatorSize = indicatorPickerRatio * pickerSize; const pickerPadding = indicatorSize / 3; const indicatorRadius = pickerSize / 2 - indicatorSize / 2 - pickerPadding; const mx = pickerSize / 2; const my = pickerSize / 2; const dx = Math.cos(angle) * indicatorRadius; const dy = Math.sin(angle) * indicatorRadius; return { picker: { padding: pickerPadding, width: pickerSize, height: pickerSize, }, pickerIndicator: { top: mx + dx - indicatorSize / 2, [isRTL ? 'right' : 'left']: my + dy - indicatorSize / 2, width: indicatorSize, height: indicatorSize, borderRadius: indicatorSize / 2, backgroundColor: indicatorColor, }, selectedPreview: { width: summarySize / 2, height: summarySize, top: pickerSize / 2 - summarySize / 2, left: Math.floor(pickerSize / 2), borderTopRightRadius: summarySize / 2, borderBottomRightRadius: summarySize / 2, backgroundColor: selectedColor, }, originalPreview: { width: Math.ceil(summarySize / 2), height: summarySize, top: pickerSize / 2 - summarySize / 2, left: pickerSize / 2 - summarySize / 2, borderTopLeftRadius: summarySize / 2, borderBottomLeftRadius: summarySize / 2, backgroundColor: oldColor, }, selectedFullPreview: { width: summarySize, height: summarySize, top: pickerSize / 2 - summarySize / 2, left: pickerSize / 2 - summarySize / 2, borderRadius: summarySize / 2, backgroundColor: selectedColor, }, }; }; const styles = react_native_1.StyleSheet.create({ pickerContainer: { flex: 1, alignItems: 'center', justifyContent: 'center', }, pickerImage: { flex: 1, width: undefined, height: undefined, }, pickerIndicator: { position: 'absolute', boxShadow: '3px 3px 4px 0px rgba(0, 0, 0, 0.3)', elevation: 5, }, selectedPreview: { position: 'absolute', borderLeftWidth: 0, }, originalPreview: { position: 'absolute', borderRightWidth: 0, }, selectedFullPreview: { position: 'absolute', }, pickerAlignment: { alignItems: 'center', }, });