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