UNPKG

@fto-consult/expo-ui

Version:

Bibliothèque de composants UI Expo,react-native

176 lines (171 loc) 6.24 kB
import { Switch,TouchableRipple } from 'react-native-paper'; import {Pressable} from "react-native"; import View from "$ecomponents/View"; import React from "$react"; import {isUndefined,defaultObj,defaultVal,defaultStr,defaultBool} from "$cutils"; import theme,{Colors,DISABLED_OPACITY} from "$theme"; import {StyleSheet} from "react-native"; import PropTypes from "prop-types"; import Tooltip from "$ecomponents/Tooltip"; import HelperText from "$ecomponents/HelperText"; import Label from "$ecomponents/Label"; export const leftPosition = 'left'; export const rightPosition = "right"; const SwitchComponent = React.forwardRef((props,ref)=>{ let { checkedValue, uncheckedValue, defaultValue, value, label, text, checkedLabel, error, style, on, onPress, onValue, offValue, checkedTooltip, onChange, uncheckedTooltip, uncheckedLabel, helperText, labelProps, position, labelStyle, tooltip, checked, testID, title, disabled, readOnly, right, left, width, height, ...p } = props; p = defaultObj(p); disabled = defaultBool(disabled,false); const isEditable = !disabled && readOnly !== true ? true : false; const pointerEvents = isEditable ? "auto" : "none"; checkedValue = defaultVal(onValue,checkedValue,1); uncheckedValue = defaultVal(offValue,uncheckedValue,0); on = defaultVal(on,checked); if(!isUndefined(on)){ defaultValue = on ?checkedValue : uncheckedValue; } defaultValue = defaultVal(defaultValue,value,0); const [isSwitchOn,setIsSwitchOn] = React.useState(defaultValue == checkedValue ? true : false) const toggleIsSwitchOn = (a)=> { if(typeof onPress ==='function' && onPress(a) === false){ return; } setIsSwitchOn(!isSwitchOn); }; const previousIsSwitchOn = React.usePrevious(isSwitchOn); if(isSwitchOn){ label = defaultVal(checkedLabel,label,text) tooltip = defaultStr(checkedTooltip,tooltip,title); } else { label = defaultVal(uncheckedLabel,label,text) tooltip = defaultStr(uncheckedTooltip,tooltip,title); } React.useEffect(()=>{ if(previousIsSwitchOn !== isSwitchOn){ if(typeof onChange =='function'){ onChange({checked:isSwitchOn,isSwitchOn,isOn:isSwitchOn,isOff:!isSwitchOn,value:isSwitchOn?checkedValue:uncheckedValue,label:isSwitchOn?checkedLabel:uncheckedLabel}); } } },[isSwitchOn]) const setValue = (defaultValue)=>{ const isOn = defaultValue == checkedValue ? true : false; if(isOn === isSwitchOn) return; setIsSwitchOn(isOn); } React.useEffect(()=>{ setValue(defaultValue); },[defaultValue]) const context = {setValue}; React.useEffect(()=>{ React.setRef(ref,context); return ()=>{ React.setRef(ref,null); } },[]) position = defaultStr(position).toLowerCase(); if(position !== leftPosition && position !== rightPosition){ position = leftPosition; } labelProps = defaultObj(labelProps) const isLeftPosition = position === leftPosition; const disabledStyle = undefined;//disabled ? {opacity : DISABLED_OPACITY} : undefined; const sw = <Switch disabled = {disabled} readOnly = {readOnly || !isEditable} pointerEvents={pointerEvents} style = {[{['margin'+(isLeftPosition?'Right':'Left')]:10},style,styles.switch,disabledStyle]} value = {isSwitchOn} onValueChange = {setIsSwitchOn} color = {Colors.isValid(p.color)? p.color : theme.colors.primaryOnSurface} testID={testID+"_MainSwitchComponent"} /> return <Tooltip {...p} tooltip={tooltip} aria-label={label} role="switch" disabled = {!isEditable} pointerEvents = {pointerEvents} accessibilityState={{checked:isSwitchOn}} testID={testID} style={[p.style,disabledStyle]} ref={ref} > <TouchableRipple onPress={toggleIsSwitchOn} style={[disabledStyle]}> <View importantForAccessibility="no-hide-descendants" pointerEvents={pointerEvents} style={[styles.wrap,p.style,styles.container,]}> { isLeftPosition ? sw: null} {<Label {...labelProps} pointerEvents={pointerEvents} disabled = {disabled} style={[styles.label,labelStyle,labelProps.style,error?{color:theme.colors.error}:undefined]} >{label}</Label>} {!isLeftPosition ? sw : null} </View> </TouchableRipple> <HelperText error={error} disabled={!isEditable}>{helperText}</HelperText> </Tooltip> }); SwitchComponent.propTypes = { ...defaultObj(Switch.propTypes), rippleProps : PropTypes.object, // les props du tooltip à exploiter pour le rendu du switch labelProps : PropTypes.object,//les props du label checkedValue : PropTypes.any, onValue : PropTypes.any, offValue : PropTypes.any, uncheckedValue : PropTypes.any, checkedLabel : PropTypes.string, uncheckedLabel : PropTypes.string, checkedTooltip : PropTypes.string, uncheckedTooltip : PropTypes.string, } const styles = StyleSheet.create({ wrap : { justifyContent: 'space-between', paddingHorizontal : 0, paddingVertical : 5, }, container : { flexDirection: 'row', alignItems: 'center', paddingVertical : 7, }, label: { fontSize: 16, flexShrink: 1, flexGrow: 1, }, switch : { backgroundColor : "transparent", paddingHorizontal:0, } }); export default SwitchComponent; SwitchComponent.displayName = "SwitchComponent";