begins refactor of Checkbox field type
This commit is contained in:
@@ -1,20 +1,11 @@
|
||||
const validations = require('../fields/validations');
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
name: 'enableAPIKey',
|
||||
label: 'Enable API key for this user',
|
||||
type: 'checkbox',
|
||||
defaultValue: false,
|
||||
validate: validations.checkbox,
|
||||
},
|
||||
{
|
||||
name: 'apiKey',
|
||||
type: 'text',
|
||||
label: 'User API Key',
|
||||
condition: (_, siblings) => {
|
||||
return siblings.enableAPIKey && siblings.enableAPIKey.value;
|
||||
},
|
||||
validate: validations.text,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Email from '../Email';
|
||||
import Password from '../Password';
|
||||
import Checkbox from '../Checkbox';
|
||||
import Button from '../../../elements/Button';
|
||||
import ConfirmPassword from '../ConfirmPassword';
|
||||
|
||||
import './index.scss';
|
||||
@@ -9,7 +11,8 @@ import './index.scss';
|
||||
const baseClass = 'auth-fields';
|
||||
|
||||
const Auth = (props) => {
|
||||
const { initialData } = props;
|
||||
const { initialData, useAPIKey } = props;
|
||||
const [changingPassword, setChangingPassword] = useState(false);
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
@@ -19,23 +22,53 @@ const Auth = (props) => {
|
||||
label="Email"
|
||||
initialData={initialData?.email}
|
||||
/>
|
||||
<Password
|
||||
required
|
||||
name="password"
|
||||
label="New Password"
|
||||
/>
|
||||
<ConfirmPassword />
|
||||
{changingPassword && (
|
||||
<div className={`${baseClass}__changing-password`}>
|
||||
<Password
|
||||
required
|
||||
name="password"
|
||||
label="New Password"
|
||||
/>
|
||||
<ConfirmPassword />
|
||||
<Button
|
||||
size="small"
|
||||
buttonStyle="secondary"
|
||||
onClick={() => setChangingPassword(false)}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{!changingPassword && (
|
||||
<Button
|
||||
size="small"
|
||||
buttonStyle="secondary"
|
||||
onClick={() => setChangingPassword(true)}
|
||||
>
|
||||
Change Password
|
||||
</Button>
|
||||
)}
|
||||
{useAPIKey && (
|
||||
<div className={`${baseClass}__api-key`}>
|
||||
<Checkbox
|
||||
label="Enable API Key"
|
||||
name="enableAPIKey"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Auth.defaultProps = {
|
||||
initialData: undefined,
|
||||
useAPIKey: false,
|
||||
};
|
||||
|
||||
Auth.propTypes = {
|
||||
fieldTypes: PropTypes.shape({}).isRequired,
|
||||
initialData: PropTypes.shape({}),
|
||||
useAPIKey: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default Auth;
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
background: $color-background-gray;
|
||||
|
||||
.btn {
|
||||
margin: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'styled-checkbox';
|
||||
|
||||
const StyledCheckbox = ({
|
||||
onClick, isChecked, label, name, isDisabled, hasError,
|
||||
}) => {
|
||||
const classes = [
|
||||
baseClass,
|
||||
isChecked && `${baseClass}--is-checked`,
|
||||
isDisabled && `${baseClass}--is-disabled`,
|
||||
hasError && `${baseClass}--has-error`,
|
||||
].filter(Boolean).join(' ');
|
||||
|
||||
return (
|
||||
<button
|
||||
className={classes}
|
||||
onClick={() => !isDisabled && onClick(!isChecked)}
|
||||
type="button"
|
||||
title={label}
|
||||
role="checkbox"
|
||||
aria-checked={isChecked}
|
||||
aria-labelledby={name}
|
||||
tabIndex={0}
|
||||
>
|
||||
<span className="checked-symbol">x</span>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
StyledCheckbox.defaultProps = {
|
||||
isChecked: false,
|
||||
label: 'Checkbox',
|
||||
isDisabled: false,
|
||||
hasError: false,
|
||||
};
|
||||
|
||||
StyledCheckbox.propTypes = {
|
||||
onClick: PropTypes.func.isRequired,
|
||||
isChecked: PropTypes.bool,
|
||||
label: PropTypes.string,
|
||||
name: PropTypes.string.isRequired,
|
||||
isDisabled: PropTypes.bool,
|
||||
hasError: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default StyledCheckbox;
|
||||
@@ -1,27 +0,0 @@
|
||||
@import '../../shared';
|
||||
|
||||
.styled-checkbox {
|
||||
@include formInput;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
max-width: base(1.75);
|
||||
font-size: base(1);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.checked-symbol {
|
||||
opacity: 0;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&--is-checked {
|
||||
.checked-symbol {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&--has-error {
|
||||
background-color: lighten($color-red, 20%);
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,13 @@ import PropTypes from 'prop-types';
|
||||
import useFieldType from '../../useFieldType';
|
||||
import withCondition from '../../withCondition';
|
||||
import Error from '../../Error';
|
||||
import StyledCheckbox from './StyledCheckbox';
|
||||
import { checkbox } from '../../../../../fields/validations';
|
||||
import X from '../../../icons/X';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'checkbox';
|
||||
|
||||
const Checkbox = (props) => {
|
||||
const {
|
||||
name,
|
||||
@@ -20,6 +22,8 @@ const Checkbox = (props) => {
|
||||
width,
|
||||
label,
|
||||
readOnly,
|
||||
onChange,
|
||||
disableFormData,
|
||||
} = props;
|
||||
|
||||
const path = pathFromProps || name;
|
||||
@@ -29,18 +33,18 @@ const Checkbox = (props) => {
|
||||
showError,
|
||||
errorMessage,
|
||||
setValue,
|
||||
formProcessing,
|
||||
} = useFieldType({
|
||||
path,
|
||||
required,
|
||||
initialData,
|
||||
defaultValue,
|
||||
validate,
|
||||
disableFormData,
|
||||
});
|
||||
|
||||
const classes = [
|
||||
'field-type',
|
||||
'checkbox',
|
||||
baseClass,
|
||||
showError && 'error',
|
||||
readOnly && 'read-only',
|
||||
].filter(Boolean).join(' ');
|
||||
@@ -57,15 +61,24 @@ const Checkbox = (props) => {
|
||||
showError={showError}
|
||||
message={errorMessage}
|
||||
/>
|
||||
<StyledCheckbox
|
||||
onClick={setValue}
|
||||
isChecked={value || false}
|
||||
<input
|
||||
type="checkbox"
|
||||
name={path}
|
||||
label={label}
|
||||
isDisabled={formProcessing || readOnly}
|
||||
hasError={showError}
|
||||
id={path}
|
||||
checked={value ? 'on' : false}
|
||||
readOnly
|
||||
/>
|
||||
{label}
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setValue(!value)}
|
||||
>
|
||||
<span className={`${baseClass}__input`}>
|
||||
{value && <X />}
|
||||
</span>
|
||||
<span className={`${baseClass}__label`}>
|
||||
{label}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -80,6 +93,8 @@ Checkbox.defaultProps = {
|
||||
width: undefined,
|
||||
style: {},
|
||||
path: '',
|
||||
onChange: undefined,
|
||||
disableFormData: false,
|
||||
};
|
||||
|
||||
Checkbox.propTypes = {
|
||||
@@ -93,6 +108,8 @@ Checkbox.propTypes = {
|
||||
width: PropTypes.string,
|
||||
style: PropTypes.shape({}),
|
||||
label: PropTypes.string,
|
||||
onChange: PropTypes.func,
|
||||
disableFormData: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default withCondition(Checkbox);
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
@import '../shared';
|
||||
|
||||
.field-type.checkbox {
|
||||
.checkbox {
|
||||
position: relative;
|
||||
|
||||
.tooltip {
|
||||
right: auto;
|
||||
}
|
||||
|
||||
span {
|
||||
left: calc(#{base(1.25)} / 2);
|
||||
transform: none;
|
||||
}
|
||||
button {
|
||||
@extend %btn-reset;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&__input {
|
||||
position: relative;
|
||||
width: $baseline;
|
||||
height: $baseline;
|
||||
}
|
||||
|
||||
input {
|
||||
margin: 0;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user