@ramses-superapp/ramses-ui
Version:
Skinless UI primitives for Ramses Built Apps
66 lines (65 loc) • 1.89 kB
JavaScript
;
import { forwardRef, useCallback } from 'react';
import { View } from 'react-native';
import { jsx as _jsx } from "react/jsx-runtime";
/**
* Skinless slider primitive.
* Provides a track + thumb structure with pan-to-value behavior.
* No colors or visual styling — the skinning layer provides those.
*/
const RsSlider = /*#__PURE__*/forwardRef(({
value,
minimumValue = 0,
maximumValue = 1,
step = 0,
onValueChange,
disabled,
style
}, ref) => {
const trackWidth = {
current: 0
};
const handleLayout = useCallback(e => {
trackWidth.current = e.nativeEvent.layout.width;
}, [trackWidth]);
const handlePress = useCallback(e => {
if (disabled || !onValueChange || trackWidth.current === 0) return;
const x = e.nativeEvent.locationX;
const ratio = Math.min(1, Math.max(0, x / trackWidth.current));
let next = minimumValue + ratio * (maximumValue - minimumValue);
if (step > 0) {
next = Math.round(next / step) * step;
}
onValueChange(next);
}, [disabled, onValueChange, minimumValue, maximumValue, step, trackWidth]);
const range = maximumValue - minimumValue;
const pct = range > 0 ? (value - minimumValue) / range * 100 : 0;
return /*#__PURE__*/_jsx(View, {
ref: ref,
style: style,
onLayout: handleLayout,
onStartShouldSetResponder: () => !disabled,
onResponderRelease: handlePress,
accessibilityRole: "adjustable",
accessibilityValue: {
min: minimumValue,
max: maximumValue,
now: value
},
children: /*#__PURE__*/_jsx(View, {
style: {
width: '100%',
position: 'relative'
},
children: /*#__PURE__*/_jsx(View, {
style: {
width: `${pct}%`,
height: '100%'
}
})
})
});
});
RsSlider.displayName = 'RsSlider';
export default RsSlider;
//# sourceMappingURL=RsSlider.js.map