react-native-resegmented-control
Version:
A fully customizable, declarative component that mimics the design of UISegmentedControl from iOS 13. Supported on iOS and Android
141 lines • 7.33 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var react_1 = __importStar(require("react"));
var react_native_1 = require("react-native");
var react_native_gesture_handler_1 = require("react-native-gesture-handler");
var react_native_reanimated_1 = __importStar(require("react-native-reanimated"));
var react_native_redash_1 = require("react-native-redash");
var Divider_1 = require("../Divider");
var Segment_1 = require("../Segment");
var SegmentedContext_1 = require("../SegmentedContext");
var utils_1 = require("../utils");
var SegmentedControlStyles_1 = __importDefault(require("./SegmentedControlStyles"));
exports.SegmentedControl = function (_a) {
var _b = _a.activeTintColor, activeTintColor = _b === void 0 ? '#000000' : _b, children = _a.children, _c = _a.disabled, disabled = _c === void 0 ? false : _c, disabledStyle = _a.disabledStyle, _d = _a.inactiveTintColor, inactiveTintColor = _d === void 0 ? '#000000' : _d, initialSelectedName = _a.initialSelectedName, onChangeValue = _a.onChangeValue, sliderStyle = _a.sliderStyle, style = _a.style;
var _e;
var _f = react_1.useState(false), _initialized = _f[0], _setInitialized = _f[1];
var _g = react_1.useState(0), _width = _g[0], _setWidth = _g[1];
var _initialSelectedName = react_1.useState(initialSelectedName)[0];
var _h = react_1.useState(_initialSelectedName), _activeName = _h[0], _setActiveName = _h[1];
var _j = react_1.useState(new react_native_reanimated_1.default.Value(0)), _sliderPosition = _j[0], _setSliderPosition = _j[1];
var _k = react_1.useState(0), _sliderWidth = _k[0], _setSliderWidth = _k[1];
var _l = react_1.useState(undefined), _map = _l[0], _setMap = _l[1];
var values = Array.isArray(children) ? children : [children];
// Map segment names to index
react_1.useEffect(function () {
var tempMap = {};
values.forEach(function (child, index) {
if (child.type !== Segment_1.Segment) {
throw new Error('SegmentedControl only accepts Segment as children.');
}
if (!child.props.name) {
throw new Error('Segment requires `name` to be defined.');
}
tempMap[child.props.name] = index;
});
_setMap(tempMap);
}, []);
// Set slider width
react_1.useEffect(function () {
_setSliderWidth(_width * (1 / values.length - 0.015));
}, [values, _width]);
// Set initial slider position
react_1.useEffect(function () {
if (typeof _initialSelectedName !== 'undefined' &&
typeof _map !== 'undefined' &&
_width > 0 &&
!_initialized) {
var index = _map[_initialSelectedName];
var position = _width * (index / values.length);
_setSliderPosition(new react_native_reanimated_1.default.Value(position));
_setInitialized(true);
}
}, [values, _width, _map, _initialSelectedName]);
// This hook is used to animate the slider position
react_native_reanimated_1.default.useCode(function () {
var index = _activeName && _map ? _map[_activeName] : 0;
var sliderPosition = _width * (index / values.length);
return react_native_reanimated_1.default.set(_sliderPosition, react_native_redash_1.timing({
from: _sliderPosition,
to: sliderPosition,
easing: react_native_reanimated_1.Easing.linear,
duration: 200,
}));
}, [_activeName]);
var handleLayout = function (event) {
return _setWidth(event.nativeEvent.layout.width);
};
var handleChangeValue = function (name) {
if (typeof _activeName === 'undefined' && typeof _map !== 'undefined') {
var index = _map[name];
_setSliderPosition(new react_native_reanimated_1.default.Value(_width * (index / values.length)));
}
_setActiveName(name);
if (typeof onChangeValue === 'function') {
onChangeValue(name);
}
};
var handleGestureEvent = function (event) {
if (disabled)
return;
var x = event.nativeEvent.x;
var calculatedIndex = Math.floor((x / _width) * values.length);
var index = utils_1.clamp(calculatedIndex, 0, values.length - 1);
var name = values[index].props.name;
handleChangeValue(name);
};
var currentIndex = (_e = _map === null || _map === void 0 ? void 0 : _map[_activeName || '']) !== null && _e !== void 0 ? _e : -1;
return (react_1.default.createElement(SegmentedContext_1.SegmentedContext.Provider, { value: {
selectedName: _activeName,
onChange: handleChangeValue,
} },
react_1.default.createElement(react_native_gesture_handler_1.PanGestureHandler, { onGestureEvent: handleGestureEvent },
react_1.default.createElement(react_native_1.View, { onLayout: handleLayout, style: [
SegmentedControlStyles_1.default.container,
style,
disabled && SegmentedControlStyles_1.default.disabledContainer,
disabled && disabledStyle,
] },
typeof _activeName !== 'undefined' && (react_1.default.createElement(react_native_reanimated_1.default.View, { testID: "SegmentedControl_Slider", style: [
SegmentedControlStyles_1.default.sliderDefault,
{
width: _sliderWidth,
transform: [
{
translateX: _sliderPosition,
},
],
},
sliderStyle,
SegmentedControlStyles_1.default.slider,
] })),
values.map(function (child, index) {
return (react_1.default.createElement(react_1.default.Fragment, { key: child.props.name },
index > 0 && (react_1.default.createElement(Divider_1.Divider, { hide: currentIndex !== index && currentIndex !== index - 1 })), __assign(__assign({}, child), { props: __assign({ disabled: disabled,
inactiveTintColor: inactiveTintColor,
activeTintColor: activeTintColor }, child.props) })));
})))));
};
exports.default = exports.SegmentedControl;
//# sourceMappingURL=SegmentedControl.js.map