mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-03-22 19:05:56 -04:00
Add formik checkbox component, Show password checkbox
This commit is contained in:
parent
4e0aaafa01
commit
12c41251c1
7 changed files with 146 additions and 16 deletions
src/components
84
src/components/formik-forms/formik-checkbox.jsx
Normal file
84
src/components/formik-forms/formik-checkbox.jsx
Normal file
|
@ -0,0 +1,84 @@
|
|||
const classNames = require('classnames');
|
||||
const PropTypes = require('prop-types');
|
||||
const React = require('react');
|
||||
import {Field} from 'formik';
|
||||
|
||||
require('./formik-checkbox.scss');
|
||||
require('./formik-forms.scss');
|
||||
require('../forms/row.scss');
|
||||
|
||||
const FormikCheckboxSubComponent = ({
|
||||
className,
|
||||
field,
|
||||
id,
|
||||
label,
|
||||
...props
|
||||
}) => (
|
||||
<div className="checkbox">
|
||||
<input
|
||||
checked={field.value}
|
||||
className={classNames(
|
||||
'formik-checkbox',
|
||||
className
|
||||
)}
|
||||
id={id}
|
||||
name={field.name}
|
||||
type="checkbox"
|
||||
value={field.value}
|
||||
onBlur={field.onBlur} /* eslint-disable-line react/jsx-handler-names */
|
||||
onChange={field.onChange} /* eslint-disable-line react/jsx-handler-names */
|
||||
{...props}
|
||||
/>
|
||||
{label && (
|
||||
<label
|
||||
className={classNames(
|
||||
'formik-label',
|
||||
'formik-checkbox-label'
|
||||
)}
|
||||
htmlFor={id}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
FormikCheckboxSubComponent.propTypes = {
|
||||
className: PropTypes.string,
|
||||
field: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
onBlur: PropTypes.function,
|
||||
onChange: PropTypes.function,
|
||||
value: PropTypes.bool
|
||||
}),
|
||||
id: PropTypes.string,
|
||||
label: PropTypes.string,
|
||||
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
|
||||
};
|
||||
|
||||
|
||||
const FormikCheckbox = ({
|
||||
className,
|
||||
id,
|
||||
label,
|
||||
name,
|
||||
...props
|
||||
}) => (
|
||||
<Field
|
||||
className={className}
|
||||
component={FormikCheckboxSubComponent}
|
||||
id={id}
|
||||
label={label}
|
||||
name={name}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
FormikCheckbox.propTypes = {
|
||||
className: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
label: PropTypes.string,
|
||||
name: PropTypes.string
|
||||
};
|
||||
|
||||
module.exports = FormikCheckbox;
|
39
src/components/formik-forms/formik-checkbox.scss
Normal file
39
src/components/formik-forms/formik-checkbox.scss
Normal file
|
@ -0,0 +1,39 @@
|
|||
@import "../../colors";
|
||||
|
||||
.formik-checkbox-label {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
input[type="checkbox"].formik-checkbox {
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: .625rem;
|
||||
border: 1px solid $active-dark-gray;
|
||||
border-radius: 3px;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
appearance: none;
|
||||
|
||||
&:focus:checked {
|
||||
transition: all .5s ease;
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 .25rem $ui-blue-25percent;
|
||||
}
|
||||
|
||||
&:focus:not(:checked) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:checked {
|
||||
background-color: $ui-blue;
|
||||
text-align: center;
|
||||
text-indent: .125rem;
|
||||
line-height: 1.25rem;
|
||||
font-size: .75rem;
|
||||
|
||||
&:after {
|
||||
color: $type-white;
|
||||
content: "\2714";
|
||||
}
|
||||
}
|
||||
}
|
3
src/components/formik-forms/formik-forms.scss
Normal file
3
src/components/formik-forms/formik-forms.scss
Normal file
|
@ -0,0 +1,3 @@
|
|||
.formik-label {
|
||||
font-weight: 500;
|
||||
}
|
|
@ -5,6 +5,7 @@ import {Field} from 'formik';
|
|||
|
||||
const FormikInput = require('./formik-input.jsx');
|
||||
|
||||
require('./formik-forms.scss');
|
||||
require('./formik-radio-button.scss');
|
||||
require('../forms/row.scss');
|
||||
|
||||
|
@ -34,6 +35,7 @@ const FormikRadioButtonSubComponent = ({
|
|||
{label && (
|
||||
<label
|
||||
className={classNames(
|
||||
'formik-label',
|
||||
'formik-radio-label',
|
||||
labelClassName
|
||||
)}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
@import "../../colors";
|
||||
|
||||
.formik-radio-label {
|
||||
font-weight: 300;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.join-flow-password-confirm {
|
||||
margin-bottom: .6875rem;
|
||||
}
|
||||
|
||||
.join-flow-input-tall {
|
||||
height: 3rem;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ const {injectIntl, intlShape} = require('react-intl');
|
|||
|
||||
const validate = require('../../lib/validate');
|
||||
const FormikInput = require('../../components/formik-forms/formik-input.jsx');
|
||||
const FormikCheckbox = require('../../components/formik-forms/formik-checkbox.jsx');
|
||||
const JoinFlowStep = require('./join-flow-step.jsx');
|
||||
|
||||
require('./join-flow-steps.scss');
|
||||
|
@ -26,9 +27,6 @@ class UsernameStep extends React.Component {
|
|||
'validateUsernameIfPresent',
|
||||
'validateForm'
|
||||
]);
|
||||
this.state = {
|
||||
showPassword: false
|
||||
};
|
||||
}
|
||||
handleChangeShowPassword () {
|
||||
this.setState({showPassword: !this.state.showPassword});
|
||||
|
@ -88,6 +86,7 @@ class UsernameStep extends React.Component {
|
|||
// called after all validations pass with no errors
|
||||
handleValidSubmit (formData, formikBag) {
|
||||
formikBag.setSubmitting(false); // formik makes us do this ourselves
|
||||
delete formData.showPassword;
|
||||
this.props.onNextStep(formData);
|
||||
}
|
||||
render () {
|
||||
|
@ -96,7 +95,8 @@ class UsernameStep extends React.Component {
|
|||
initialValues={{
|
||||
username: '',
|
||||
password: '',
|
||||
passwordConfirm: ''
|
||||
passwordConfirm: '',
|
||||
showPassword: false
|
||||
}}
|
||||
validate={this.validateForm}
|
||||
validateOnBlur={false}
|
||||
|
@ -154,7 +154,7 @@ class UsernameStep extends React.Component {
|
|||
error={errors.password}
|
||||
id="password"
|
||||
name="password"
|
||||
type={this.state.showPassword ? 'text' : 'password'}
|
||||
type={values.showPassword ? 'text' : 'password'}
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
validate={password => this.validatePasswordIfPresent(password, values.username)}
|
||||
validationClassName="validation-full-width-input"
|
||||
|
@ -167,12 +167,14 @@ class UsernameStep extends React.Component {
|
|||
/>
|
||||
<FormikInput
|
||||
className={classNames(
|
||||
'join-flow-input'
|
||||
'join-flow-input',
|
||||
'join-flow-password-confirm',
|
||||
{fail: errors.passwordConfirm}
|
||||
)}
|
||||
error={errors.passwordConfirm}
|
||||
id="passwordConfirm"
|
||||
name="passwordConfirm"
|
||||
type={this.state.showPassword ? 'text' : 'password'}
|
||||
type={values.showPassword ? 'text' : 'password'}
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
validate={() =>
|
||||
this.validatePasswordConfirmIfPresent(values.password,
|
||||
|
@ -189,14 +191,11 @@ class UsernameStep extends React.Component {
|
|||
/* eslint-enable react/jsx-no-bind */
|
||||
/>
|
||||
<div className="join-flow-input-title">
|
||||
<div
|
||||
onClick={this.handleChangeShowPassword}
|
||||
>
|
||||
{/* TODO: should localize 'Hide password' if we use that */}
|
||||
{this.state.showPassword ? 'Hide password' : (
|
||||
this.props.intl.formatMessage({id: 'registration.showPassword'})
|
||||
)}
|
||||
</div>
|
||||
<FormikCheckbox
|
||||
id="showPassword"
|
||||
label={this.props.intl.formatMessage({id: 'registration.showPassword'})}
|
||||
name="showPassword"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue