1/** 2 * Copyright (c) Nicolas Gallagher. 3 * Copyright (c) Facebook, Inc. and its affiliates. 4 * 5 * This source code is licensed under the MIT license found in the 6 * LICENSE file in the root directory of this source tree. 7 * 8 * see: https://github.com/necolas/react-native-web 9 */ 10 11import React from 'react'; 12// @ts-ignore 13import { StyleSheet, View, unstable_createElement as createElement } from 'react-native'; 14 15import { CheckboxProps, CheckboxEvent } from './Checkbox.types'; 16 17export default class ExpoCheckbox extends React.PureComponent<CheckboxProps> { 18 private handleChange = (event: React.SyntheticEvent<HTMLInputElement, CheckboxEvent>) => { 19 const value = event.nativeEvent.target.checked; 20 event.nativeEvent.value = value; 21 this.props.onChange?.(event); 22 this.props.onValueChange?.(value); 23 }; 24 25 render() { 26 const { color, disabled, onChange, onValueChange, style, value, ...other } = this.props; 27 28 const fakeControl = ( 29 <View 30 pointerEvents="none" 31 style={[ 32 styles.fakeControl, 33 value && styles.fakeControlChecked, 34 // custom color 35 !!color && { backgroundColor: value ? color : undefined, borderColor: color }, 36 disabled && styles.fakeControlDisabled, 37 value && disabled && styles.fakeControlCheckedAndDisabled, 38 ]} 39 /> 40 ); 41 42 const nativeControl = createElement('input', { 43 accessibilityChecked: value, 44 accessibilityDisabled: disabled, 45 checked: value, 46 disabled, 47 onChange: this.handleChange, 48 style: [styles.nativeControl, styles.cursorInherit], 49 type: 'checkbox', 50 }); 51 52 return ( 53 <View {...other} style={[styles.root, style, disabled && styles.cursorDefault]}> 54 {nativeControl} 55 {fakeControl} 56 </View> 57 ); 58 } 59} 60 61const styles = StyleSheet.create({ 62 root: { 63 // @ts-ignore 64 cursor: 'pointer', 65 height: 16, 66 userSelect: 'none', 67 width: 16, 68 }, 69 cursorDefault: { 70 // @ts-ignore 71 cursor: 'default', 72 }, 73 74 cursorInherit: { 75 // @ts-ignore 76 cursor: 'inherit', 77 }, 78 fakeControl: { 79 ...StyleSheet.absoluteFillObject, 80 alignItems: 'center', 81 backgroundColor: '#fff', 82 borderColor: '#657786', 83 borderRadius: 2, 84 borderStyle: 'solid', 85 borderWidth: 2, 86 height: '100%', 87 justifyContent: 'center', 88 width: '100%', 89 }, 90 fakeControlChecked: { 91 backgroundColor: '#009688', 92 // @ts-ignore 93 backgroundImage: 94 'url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K")', 95 backgroundRepeat: 'no-repeat', 96 borderColor: '#009688', 97 }, 98 fakeControlDisabled: { 99 borderColor: '#CCD6DD', 100 }, 101 fakeControlCheckedAndDisabled: { 102 backgroundColor: '#AAB8C2', 103 borderColor: '#AAB8C2', 104 }, 105 nativeControl: { 106 ...StyleSheet.absoluteFillObject, 107 height: '100%', 108 margin: 0, 109 padding: 0, 110 width: '100%', 111 // @ts-ignore 112 WebkitAppearance: 'none', 113 }, 114}); 115 116export const name = 'ExpoCheckbox'; 117