@metamask/design-system-react-native
Version:
120 lines • 5.61 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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Checkbox = void 0;
const design_system_twrnc_preset_1 = require("@metamask/design-system-twrnc-preset");
const react_1 = __importStar(require("react"));
const react_native_1 = require("react-native/index.js");
const Icon_1 = require("../Icon/index.cjs");
const TextOrChildren_1 = require("../temp-components/TextOrChildren/index.cjs");
const AnimatedView = react_native_1.Animated.View;
exports.Checkbox = (0, react_1.forwardRef)(({ isSelected, isDisabled = false, isInvalid = false, label = '', labelProps, onChange, checkboxContainerProps, checkedIconProps, twClassName = '', style, ...props }, ref) => {
// Animation values
const scaleAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current;
const iconAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(isSelected ? 1 : 0)).current;
// Sync icon opacity whenever selection changes
(0, react_1.useEffect)(() => {
react_native_1.Animated.timing(iconAnim, {
toValue: isSelected ? 1 : 0,
duration: 300,
easing: react_native_1.Easing.ease,
useNativeDriver: true,
}).start();
}, [isSelected, iconAnim]);
// Bounce effect when toggling
const animateScale = (0, react_1.useCallback)(() => {
react_native_1.Animated.sequence([
react_native_1.Animated.timing(scaleAnim, {
toValue: 1.15,
duration: 100,
easing: react_native_1.Easing.ease,
useNativeDriver: true,
}),
react_native_1.Animated.timing(scaleAnim, {
toValue: 1,
duration: 100,
easing: react_native_1.Easing.ease,
useNativeDriver: true,
}),
]).start();
}, [scaleAnim]);
// Press handler: notify parent, then bounce
const handlePress = () => {
if (isDisabled) {
return;
}
onChange?.(!isSelected);
animateScale();
};
(0, react_1.useImperativeHandle)(ref, () => ({ toggle: handlePress }), [handlePress]);
const tw = (0, design_system_twrnc_preset_1.useTailwind)();
const twContainerClassNames = tw `flex-row items-center ${isDisabled ? 'opacity-50' : 'opacity-100'} ${twClassName}`;
const getCheckboxContainerStyle = (0, react_1.useCallback)((pressed) => {
const baseBg = isSelected ? 'bg-primary-default' : 'bg-default';
let baseBorder = 'border-default';
if (isSelected) {
baseBorder = 'border-primary-default';
}
else if (isInvalid) {
baseBorder = 'border-error-default';
}
const pressedBg = isSelected
? 'bg-primary-default-pressed'
: 'bg-default-pressed';
let pressedBorder = 'border-default';
if (isSelected) {
pressedBorder = 'border-primary-default-pressed';
}
else if (isInvalid) {
pressedBorder = 'border-error-default';
}
return pressed
? `${pressedBg} ${pressedBorder}`
: `${baseBg} ${baseBorder}`;
}, [isSelected, isInvalid]);
return (<react_native_1.Pressable onPress={handlePress} accessible accessibilityRole="checkbox" accessibilityState={{
checked: isSelected,
disabled: isDisabled,
}} accessibilityLabel={typeof label === 'string' ? label : undefined} style={(state) => [
twContainerClassNames,
typeof style === 'function' ? style(state) : style,
]} disabled={isDisabled} {...props}>
{({ pressed }) => (<>
<AnimatedView {...checkboxContainerProps} style={[
tw `${getCheckboxContainerStyle(pressed)} flex size-[22px] items-center justify-center rounded border-2`,
{ transform: [{ scale: scaleAnim }] },
]}>
{/* Always render icon, opacity driven by iconAnim */}
<react_native_1.Animated.View style={{ opacity: iconAnim }}>
<Icon_1.Icon name={Icon_1.IconName.Check} color={Icon_1.IconColor.PrimaryInverse} size={Icon_1.IconSize.Sm} {...checkedIconProps}/>
</react_native_1.Animated.View>
</AnimatedView>
{label ? (<TextOrChildren_1.TextOrChildren textProps={{ ...labelProps, twClassName: 'ml-3' }}>
{label}
</TextOrChildren_1.TextOrChildren>) : null}
</>)}
</react_native_1.Pressable>);
});
//# sourceMappingURL=Checkbox.cjs.map