@react-native-assets/slider
Version:
Lightweight slider for React-Native and React-Native-Web. A Range slider is included
130 lines (129 loc) • 6.72 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importDefault(require("react"));
const RN = __importStar(require("react-native"));
const useEvent_1 = require("../hooks/useEvent");
const useRounding_1 = __importDefault(require("../hooks/useRounding"));
const SliderView_1 = __importDefault(require("./SliderView"));
// We add a default padding to ensure that the responder view has enough space to recognize the touches
const styleSheet = RN.StyleSheet.create({
vertical: {
paddingHorizontal: 10
},
horizontal: {
paddingVertical: 10
}
});
const ResponderView = react_1.default.forwardRef((props, ref) => {
const { width: windowWidth, height: windowHeight } = RN.useWindowDimensions();
const { vertical, inverted, enabled, style, minimumValue, maximumValue, step, onLayout: onLayoutProp, onMove: onMoveProp, onPress: onPressProp, onRelease: onReleaseProp, ...others } = props;
const containerSize = react_1.default.useRef({ width: 0, height: 0 });
const fallbackRef = react_1.default.useRef();
const forwardRef = react_1.default.useCallback((view) => {
fallbackRef.current = view;
if (ref) {
if (typeof ref === 'function')
ref(view);
else
ref.current = view;
}
}, [ref]);
const round = (0, useRounding_1.default)({ step, minimumValue, maximumValue });
const isVertical = react_1.default.useMemo(() => vertical || (style && (RN.StyleSheet.flatten(style).flexDirection || '').startsWith('column')), [vertical, style]);
// See below for more details
const originPageLocation = react_1.default.useRef({ pageX: 0, pageY: 0 });
react_1.default.useEffect(() => {
var _a;
// We update the component's origin when the window size changes
(_a = fallbackRef.current) === null || _a === void 0 ? void 0 : _a.measure((_x, _y, _width, _height, pageX = 0, pageY = 0) => (originPageLocation.current = { pageX, pageY }));
}, [windowWidth, windowHeight]);
/** Convert a touch event into it's position on the slider */
const eventToValue = (0, useEvent_1.useEvent)((event) => {
var _a;
// We could simplify this code if this bug was solved:
// https://github.com/Sharcoux/slider/issues/18#issuecomment-877411645
const { pageX, pageY, locationX, locationY } = event.nativeEvent;
const x = RN.Platform.OS === 'web' ? locationX : (pageX - originPageLocation.current.pageX);
const y = RN.Platform.OS === 'web' ? locationY : (pageY - originPageLocation.current.pageY);
let offset = isVertical ? y : x;
const size = ((_a = containerSize.current) === null || _a === void 0 ? void 0 : _a[isVertical ? 'height' : 'width']) || 1;
// In RTL mode, coordinates are flipped for horizontal sliders
if (RN.I18nManager.isRTL && !isVertical)
offset = size - offset;
const newValue = inverted
? maximumValue - ((maximumValue - minimumValue) * offset) / size
: minimumValue + ((maximumValue - minimumValue) * offset) / size;
return round(newValue);
});
const onMove = (0, useEvent_1.useEvent)((event) => {
onMoveProp(eventToValue(event));
event.preventDefault();
event.stopPropagation();
});
const onPress = (0, useEvent_1.useEvent)((event) => {
onPressProp(eventToValue(event));
event.preventDefault();
event.stopPropagation();
});
const onRelease = (0, useEvent_1.useEvent)((event) => {
onReleaseProp(eventToValue(event));
event.preventDefault();
event.stopPropagation();
});
const isEnabled = (0, useEvent_1.useEvent)((event) => {
event.stopPropagation();
return enabled;
});
const keepResponder = (0, useEvent_1.useEvent)((event) => {
event.stopPropagation();
return false;
});
const onLayout = (0, useEvent_1.useEvent)((event) => {
var _a;
// For some reason, pageX and pageY might be 'undefined' in some cases
(_a = fallbackRef.current) === null || _a === void 0 ? void 0 : _a.measure((_x, _y, _width, _height, pageX = 0, pageY = 0) => (originPageLocation.current = { pageX, pageY }));
onLayoutProp === null || onLayoutProp === void 0 ? void 0 : onLayoutProp(event);
containerSize.current = event.nativeEvent.layout;
});
const containerStyle = react_1.default.useMemo(() => [styleSheet[vertical ? 'vertical' : 'horizontal'], style], [vertical, style]);
return (react_1.default.createElement(RN.View, { ...others, focusable: false, pointerEvents: 'box-only', ref: forwardRef, onLayout: onLayout, style: containerStyle, onStartShouldSetResponder: isEnabled, onMoveShouldSetResponder: isEnabled, onResponderGrant: onPress, onResponderRelease: onRelease, onResponderMove: onMove, onResponderTerminationRequest: keepResponder, onResponderTerminate: onRelease },
react_1.default.createElement(SliderView_1.default, { vertical: vertical, inverted: inverted }, props.children)));
});
ResponderView.displayName = 'ResponderView';
exports.default = react_1.default.memo(ResponderView);