Skip to content

Commit

Permalink
Unify API of form components (#28, #113)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamkudrna committed Nov 10, 2020
1 parent 30cd892 commit fb044b7
Show file tree
Hide file tree
Showing 47 changed files with 775 additions and 903 deletions.
8 changes: 1 addition & 7 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,7 @@
"rules": {
"func-names": "off",
"react/jsx-props-no-spreading": "off",
"react/jsx-one-expression-per-line": "off",
// Bedřich Schindler <bedrich@visionapps.cz>, 14. 9. 2019
// Because of bug in eslint-config-react https://github.com/yannickcr/eslint-plugin-react/issues/1846
"react/button-has-type": "off",
// Bedřich Schindler <bedrich@visionapps.cz>, 14. 9. 2019
// These rules will be fixed later due to huge amouut of errors after update
"react/destructuring-assignment": "off"
"react/jsx-one-expression-per-line": "off"
},
"overrides": [
{
Expand Down
4 changes: 2 additions & 2 deletions src/lib/components/layout/Center/Center.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import PropTypes from 'prop-types';
import React from 'react';
import styles from './Center.scss';

export const Center = (props) => (
export const Center = ({ children }) => (
<div className={styles.root}>
<div>
{props.children}
{children}
</div>
</div>
);
Expand Down
8 changes: 4 additions & 4 deletions src/lib/components/layout/FormLayout/README.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ the job: the
for your FormLayout. This prevents FormLayout from unexpectedly growing in
browsers that don't support
[CSS subgrid](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Subgrid)
in cases when there are longer error messages or helper texts.
in cases when there are longer validation messages or help texts.

## Vertical Layout

Expand Down Expand Up @@ -268,9 +268,9 @@ This is a demo of all components supported by FormLayout.
<TextField
id="form-layout-horizontal-email"
changeHandler={() => {}}
helpText="Optional"
label="Email address"
type="email"
helperText="Optional"
/>
<>
<TextField
Expand All @@ -289,10 +289,10 @@ This is a demo of all components supported by FormLayout.
<TextField
id="form-layout-horizontal-zip"
changeHandler={() => {}}
helperText="ZIP should be 5 to 6 digits long code."
label="ZIP"
inputSize={6}
validationState="invalid"
validationText="ZIP should be 5 to 6 digits long code."
/>
<FormLayoutCustomField
id="form-layout-horizontal-country"
Expand Down Expand Up @@ -336,9 +336,9 @@ This is a demo of all components supported by FormLayout.
id="form-layout-horizontal-newsletter"
changeHandler={() => {}}
checked
helpText="Only once per week!"
label="Receive weekly newsletter"
required
description="Only once per week!"
/>
<Radio
id="form-layout-horizontal-fruit-2"
Expand Down
14 changes: 6 additions & 8 deletions src/lib/components/layout/List/List.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ import PropTypes from 'prop-types';
import React from 'react';
import styles from './List.scss';

export const List = (props) => {
const {
align,
autoWidth,
children,
} = props;

if (!props.children) {
export const List = ({
align,
autoWidth,
children,
}) => {
if (!children) {
return null;
}

Expand Down
3 changes: 3 additions & 0 deletions src/lib/components/ui/Button/Button.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ export const Button = (props) => {
'label', 'labelVisibility', 'loadingIcon', 'priority', 'size', 'startCorner', 'type', 'variant'],
);

/* No worries, `type` is always assigned correctly through props. */
/* eslint-disable react/button-has-type */
return (
<button
{...propsToTransfer}
Expand Down Expand Up @@ -144,6 +146,7 @@ export const Button = (props) => {
</button>
);
};
/* eslint-enable react/button-has-type */

Button.defaultProps = {
afterLabel: null,
Expand Down
141 changes: 64 additions & 77 deletions src/lib/components/ui/CheckboxField/CheckboxField.jsx
Original file line number Diff line number Diff line change
@@ -1,103 +1,90 @@
import PropTypes from 'prop-types';
import React from 'react';
import getRootValidationStateClassName from '../../../helpers/getRootValidationStateClassName';
import transferProps from '../../../utils/transferProps';
import withForwardedRef from '../withForwardedRef';
import styles from './CheckboxField.scss';

export const CheckboxField = (props) => {
let labelVisibilityClass = '';
let labelPositionClass = '';
let rootInFormLayoutClass = '';
let rootLayoutClass = '';
let rootValidationStateClass = '';

if (!props.isLabelVisible) {
labelVisibilityClass = styles.isLabelHidden;
}

if (props.labelPosition === 'before') {
labelPositionClass = styles.labelPositionBefore;
} else if (props.labelPosition === 'after') {
labelPositionClass = styles.labelPositionAfter;
}

if (props.inFormLayout) {
rootInFormLayoutClass = styles.isRootInFormLayout;
}

if (props.layout === 'horizontal') {
rootLayoutClass = styles.isRootLayoutHorizontal;
}

if (props.validationState === 'invalid') {
rootValidationStateClass = styles.isRootStateInvalid;
} else if (props.validationState === 'valid') {
rootValidationStateClass = styles.isRootStateValid;
} else if (props.validationState === 'warning') {
rootValidationStateClass = styles.isRootStateWarning;
}
const {
changeHandler,
checked,
disabled,
forwardedRef,
helpText,
id,
inFormLayout,
isLabelVisible,
label,
labelPosition,
layout,
required,
validationState,
validationText,
value,
} = props;

const propsToTransfer = transferProps(
props,
['changeHandler', 'checked', 'description', 'disabled', 'error', 'id', 'inFormLayout', 'isLabelVisible',
'label', 'labelPosition', 'layout', 'required', 'validationState', 'value'],
['changeHandler', 'checked', 'disabled', 'helpText', 'id', 'inFormLayout', 'isLabelVisible',
'label', 'labelPosition', 'layout', 'required', 'validationState', 'validationText', 'value'],
);

return (
<div
className={`
${styles.root}
${rootInFormLayoutClass}
${rootLayoutClass}
${rootValidationStateClass}
`.trim()}
className={[
styles.root,
inFormLayout ? styles.isRootInFormLayout : '',
layout === 'horizontal' ? styles.isRootLayoutHorizontal : '',
getRootValidationStateClassName(validationState, styles),
].join(' ')}
>
<label
className={(`
${styles.inputWrap}
${labelPositionClass}
`).trim()}
htmlFor={props.id}
id={`${props.id}__label`}
className={[
styles.inputWrap,
labelPosition === 'before' ? styles.labelPositionBefore : styles.labelPositionAfter,
].join(' ')}
htmlFor={id}
id={`${id}__label`}
>
<input
{...propsToTransfer}
id={props.id}
value={props.value}
onChange={props.changeHandler}
disabled={props.disabled}
checked={props.checked}
ref={props.forwardedRef}
required={props.required}
id={id}
value={value}
onChange={changeHandler}
disabled={disabled}
checked={checked}
ref={forwardedRef}
required={required}
type="checkbox"
className={styles.input}
/>
<span className={styles.label}>
<span
className={(`
${styles.labelInner}
${labelVisibilityClass}
`).trim()}
id={`${props.id}__labelText`}
className={[
styles.labelInner,
isLabelVisible ? '' : styles.isLabelHidden,
].join(' ')}
id={`${id}__labelText`}
>
{props.label}
{label}
</span>
</span>
</label>
{props.description && (
{helpText && (
<div
className={styles.description}
id={`${props.id}__descriptionText`}
className={styles.helpText}
id={`${id}__helpText`}
>
{props.description}
{helpText}
</div>
)}
{props.error && (
{validationText && (
<div
className={styles.error}
id={`${props.id}__errorText`}
className={styles.validationText}
id={`${id}__validationText`}
>
{props.error}
{validationText}
</div>
)}
</div>
Expand All @@ -107,16 +94,16 @@ export const CheckboxField = (props) => {
CheckboxField.defaultProps = {
changeHandler: null,
checked: false,
description: null,
disabled: false,
error: null,
forwardedRef: undefined,
helpText: null,
inFormLayout: false,
isLabelVisible: true,
labelPosition: 'after',
layout: 'vertical',
required: false,
validationState: null,
validationText: null,
value: undefined,
};

Expand All @@ -129,28 +116,24 @@ CheckboxField.propTypes = {
* If `true`, the input will be checked.
*/
checked: PropTypes.bool,
/**
* Optional description.
*/
description: PropTypes.string,
/**
* If `true`, the input will be disabled.
*/
disabled: PropTypes.bool,
/**
* Error message to be displayed.
*/
error: PropTypes.string,
/**
* Reference forwarded to the `input` element.
*/
forwardedRef: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({ current: PropTypes.any }),
]),
/**
* Optional help text.
*/
helpText: PropTypes.node,
/**
* ID of the input HTML element. It also serves as a prefix for important inner elements:
* `<ID>__label`, `<ID>__labelText`, `<ID>__descriptionText`, and `<ID>__errorText`.
* `<ID>__label`, `<ID>__labelText`, `<ID>__helpText`, and `<ID>__validationText`.
*/
id: PropTypes.string.isRequired,
/**
Expand Down Expand Up @@ -182,6 +165,10 @@ CheckboxField.propTypes = {
* Alter the field to provide feedback based on validation result.
*/
validationState: PropTypes.oneOf(['invalid', 'valid', 'warning']),
/**
* Validation message to be displayed.
*/
validationText: PropTypes.node,
/**
* Value of the input.
*/
Expand Down
17 changes: 7 additions & 10 deletions src/lib/components/ui/CheckboxField/CheckboxField.scss
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,12 @@
border-left: $disabled-border-style;
}

.description,
.error {
@include form-field-helper-text();
.helpText,
.validationText {
@include form-field-help-text();
}

.error {
.validationText {
min-height: 1rem;
}

Expand All @@ -149,8 +149,7 @@
// States
// stylelint-disable no-descending-specificity
.isRootStateInvalid .label,
.isRootStateInvalid .description,
.isRootStateInvalid .error {
.isRootStateInvalid .validationText {
color: $form-invalid-color;
}

Expand All @@ -164,8 +163,7 @@
}

.isRootStateValid .label,
.isRootStateValid .description,
.isRootStateValid .error {
.isRootStateValid .validationText {
color: $form-valid-color;
}

Expand All @@ -179,8 +177,7 @@
}

.isRootStateWarning .label,
.isRootStateWarning .description,
.isRootStateWarning .error {
.isRootStateWarning .validationText {
color: $form-warning-color;
}

Expand Down
Loading

0 comments on commit fb044b7

Please sign in to comment.