scaffolds out the boolean input component
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const StyledCheckbox = ({ onClick, isChecked }) => {
|
||||
return (
|
||||
<button
|
||||
className="styled-checkbox"
|
||||
onClick={() => onClick(!isChecked)}
|
||||
type="button"
|
||||
>
|
||||
{isChecked ? 'X' : '-'}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
StyledCheckbox.defaultProps = {
|
||||
onClick: null,
|
||||
isChecked: false,
|
||||
};
|
||||
|
||||
StyledCheckbox.propTypes = {
|
||||
onClick: PropTypes.func,
|
||||
isChecked: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default StyledCheckbox;
|
||||
@@ -0,0 +1,10 @@
|
||||
@import '../../../../../scss/styles.scss';
|
||||
|
||||
|
||||
.styled-checkbox {
|
||||
@extend %btn-reset;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
padding: 30px;
|
||||
box-shadow: $shadow-sm;
|
||||
}
|
||||
107
src/client/components/forms/field-types/Checkbox/index.js
Normal file
107
src/client/components/forms/field-types/Checkbox/index.js
Normal file
@@ -0,0 +1,107 @@
|
||||
import React, { useRef, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import useFieldType from '../../useFieldType';
|
||||
import Label from '../../Label';
|
||||
import Error from '../../Error';
|
||||
import StyledCheckbox from './StyledCheckbox';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const defaultError = 'Checkbox is required';
|
||||
const defaultValidate = value => Boolean(value);
|
||||
|
||||
const Checkbox = (props) => {
|
||||
const {
|
||||
name,
|
||||
required,
|
||||
defaultValue,
|
||||
validate,
|
||||
style,
|
||||
width,
|
||||
errorMessage,
|
||||
label,
|
||||
} = props;
|
||||
|
||||
const {
|
||||
value,
|
||||
showError,
|
||||
onFieldChange,
|
||||
formProcessing,
|
||||
} = useFieldType({
|
||||
name,
|
||||
required,
|
||||
defaultValue,
|
||||
validate,
|
||||
});
|
||||
|
||||
const checkboxRef = useRef(null);
|
||||
|
||||
const classes = [
|
||||
'field-type',
|
||||
'checkbox',
|
||||
value && 'checkbox--is-checked',
|
||||
showError && 'error',
|
||||
].filter(Boolean).join(' ');
|
||||
|
||||
const fieldWidth = width ? `${width}%` : undefined;
|
||||
|
||||
const formatFieldChangeValue = () => onFieldChange(checkboxRef.current.checked);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classes}
|
||||
style={{
|
||||
...style,
|
||||
width: fieldWidth,
|
||||
}}
|
||||
>
|
||||
<Error
|
||||
showError={showError}
|
||||
message={errorMessage}
|
||||
/>
|
||||
<Label
|
||||
htmlFor={name}
|
||||
label={label}
|
||||
required={required}
|
||||
/>
|
||||
<input
|
||||
className="checkbox__input"
|
||||
ref={checkboxRef}
|
||||
value={value}
|
||||
onChange={formatFieldChangeValue}
|
||||
disabled={formProcessing ? 'disabled' : undefined}
|
||||
type="checkbox"
|
||||
id={name}
|
||||
name={name}
|
||||
checked={value}
|
||||
/>
|
||||
<StyledCheckbox
|
||||
onClick={onFieldChange}
|
||||
isChecked={value}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Checkbox.defaultProps = {
|
||||
label: null,
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
validate: defaultValidate,
|
||||
errorMessage: defaultError,
|
||||
width: 100,
|
||||
style: {},
|
||||
};
|
||||
|
||||
Checkbox.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
required: PropTypes.bool,
|
||||
defaultValue: PropTypes.bool,
|
||||
validate: PropTypes.func,
|
||||
errorMessage: PropTypes.string,
|
||||
width: PropTypes.number,
|
||||
style: PropTypes.shape({}),
|
||||
label: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Checkbox;
|
||||
@@ -0,0 +1,6 @@
|
||||
.checkbox {
|
||||
&__input {
|
||||
visibility: hidden;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import repeater from './Repeater';
|
||||
import textarea from './Textarea';
|
||||
import select from './Select';
|
||||
import number from './Number';
|
||||
import checkbox from './Checkbox';
|
||||
|
||||
export default {
|
||||
email,
|
||||
@@ -22,4 +23,5 @@ export default {
|
||||
repeater,
|
||||
textarea,
|
||||
select,
|
||||
checkbox,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useContext, useCallback, useEffect } from 'react';
|
||||
import FormContext from '../Form/Context';
|
||||
import useMountEffect from '../../../hooks/useMountEffect';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
@@ -26,13 +25,9 @@ const useFieldType = (options) => {
|
||||
});
|
||||
}, [name, required, setField, validate]);
|
||||
|
||||
useMountEffect(() => {
|
||||
sendField(defaultValue);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
sendField(defaultValue);
|
||||
}, [defaultValue, name, sendField]);
|
||||
}, [defaultValue, sendField]);
|
||||
|
||||
const valid = formContext.fields[name] ? formContext.fields[name].valid : true;
|
||||
const showError = valid === false && formContext.submitted;
|
||||
|
||||
Reference in New Issue
Block a user