/* Copyright (c) 2018-2020 Uber Technologies, Inc. This source code is licensed under the MIT license found in the LICENSE file in the root directory of this source tree. */ // @flow import * as React from 'react'; import {getOverride, getOverrideProps} from '../helpers/overrides.js'; import type {PropsT, DefaultPropsT, StatelessStateT} from './types.js'; import { Checkmark as StyledCheckmark, Input as StyledInput, Label as StyledLabel, Root as StyledRoot, Toggle as StyledToggle, ToggleInner as StyledToggleInner, ToggleTrack as StyledToggleTrack, } from './styled-components.js'; import {STYLE_TYPE} from './constants.js'; import {isFocusVisible} from '../utils/focusVisible.js'; class StatelessCheckbox extends React.Component { static defaultProps: DefaultPropsT = { overrides: {}, checked: false, disabled: false, autoFocus: false, isIndeterminate: false, inputRef: React.createRef(), isError: false, error: false, type: 'checkbox', checkmarkType: STYLE_TYPE.default, onChange: () => {}, onMouseEnter: () => {}, onMouseLeave: () => {}, onMouseDown: () => {}, onMouseUp: () => {}, onFocus: () => {}, onBlur: () => {}, }; state = { isFocused: this.props.autoFocus || false, isFocusVisible: false, isHovered: false, isActive: false, }; componentDidMount() { const {autoFocus, inputRef} = this.props; if (autoFocus && inputRef.current) { inputRef.current.focus(); } // TODO(v11) if (__DEV__) { if (this.props.checkmarkType === STYLE_TYPE.toggle) { console.warn( "baseui:Checkbox The STYLE_TYPE.toggle value on the 'checkmarkType' prop does not conform to the current base design specification. " + 'Please update your code to STYLE_TYPE.toggle_round. This will be updated automatically in a future major version.', ); } if (this.props.isError) { console.warn( 'baseui:Checkbox Property "isError" will be removed in the next major version. Use "error" property instead.', ); } } } onMouseEnter = (e: SyntheticInputEvent) => { this.setState({isHovered: true}); this.props.onMouseEnter(e); }; onMouseLeave = (e: SyntheticInputEvent) => { this.setState({isHovered: false, isActive: false}); this.props.onMouseLeave(e); }; onMouseDown = (e: SyntheticInputEvent) => { this.setState({isActive: true}); this.props.onMouseDown(e); }; onMouseUp = (e: SyntheticInputEvent) => { this.setState({isActive: false}); this.props.onMouseUp(e); }; onFocus = (e: SyntheticInputEvent) => { this.setState({isFocused: true}); this.props.onFocus(e); if (isFocusVisible(e)) { this.setState({isFocusVisible: true}); } }; onBlur = (e: SyntheticInputEvent) => { this.setState({isFocused: false}); this.props.onBlur(e); if (this.state.isFocusVisible !== false) { this.setState({isFocusVisible: false}); } }; isToggle = () => { return ( this.props.checkmarkType === STYLE_TYPE.toggle || this.props.checkmarkType === STYLE_TYPE.toggle_round ); }; render() { const {checkmarkType} = this.props; const { overrides = {}, onChange, labelPlacement = this.isToggle() ? 'left' : 'right', inputRef, isIndeterminate, isError, error, disabled, value, name, type, checked, children, required, title, } = this.props; const { Root: RootOverride, Checkmark: CheckmarkOverride, Label: LabelOverride, Input: InputOverride, Toggle: ToggleOverride, ToggleInner: ToggleInnerOverride, ToggleTrack: ToggleTrackOverride, } = overrides; const Root = getOverride(RootOverride) || StyledRoot; const Checkmark = getOverride(CheckmarkOverride) || StyledCheckmark; const Label = getOverride(LabelOverride) || StyledLabel; const Input = getOverride(InputOverride) || StyledInput; const Toggle = getOverride(ToggleOverride) || StyledToggle; const ToggleInner = getOverride(ToggleInnerOverride) || StyledToggleInner; const ToggleTrack = getOverride(ToggleTrackOverride) || StyledToggleTrack; const inputEvents = { onChange, onFocus: this.onFocus, onBlur: this.onBlur, }; const mouseEvents = { onMouseEnter: this.onMouseEnter, onMouseLeave: this.onMouseLeave, onMouseDown: this.onMouseDown, onMouseUp: this.onMouseUp, }; const sharedProps = { $isFocused: this.state.isFocused, $isFocusVisible: this.state.isFocusVisible, $isHovered: this.state.isHovered, $isActive: this.state.isActive, $isError: isError, $error: error, $checked: checked, $isIndeterminate: isIndeterminate, $required: required, $disabled: disabled, $value: value, $checkmarkType: checkmarkType, }; // TODO(v11) - add check for children (#2172) const labelComp = ( ); return ( {(labelPlacement === 'top' || labelPlacement === 'left') && labelComp} {this.isToggle() ? ( ) : ( )} {(labelPlacement === 'bottom' || labelPlacement === 'right') && labelComp} ); } } export default StatelessCheckbox; declare var __DEV__: boolean; declare var __NODE__: boolean; declare var __BROWSER__: boolean;