Skip to content
This repository has been archived by the owner on Sep 14, 2021. It is now read-only.

Commit

Permalink
feat(Checkbox): Support multiline label and improved VoiceOver focus (#…
Browse files Browse the repository at this point in the history
…614)

BREAKING CHANGE: Requires consumers to have React v16.3+. Also introduces horizontal padding to the Checkbox in button mode to prevent label text colliding with button border.
  • Loading branch information
michaeltaranto authored Apr 4, 2019
1 parent 3e30c70 commit 961a19f
Show file tree
Hide file tree
Showing 6 changed files with 276 additions and 181 deletions.
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@
"shallow-equal": "^1.0.0"
},
"peerDependencies": {
"react": "^15.0.0 || ^16.0.0",
"react-dom": "^15.0.0 || ^16.0.0",
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-helmet": "^3.0.0 || ^4.0.0 || ^5.0.0"
},
"devDependencies": {
Expand Down Expand Up @@ -134,16 +134,16 @@
"query-string": "^6.1.0",
"raf": "^3.4.0",
"raw-loader": "^0.5.1",
"react": "^16.0.0",
"react": "^16.8.6",
"react-copy-to-clipboard": "^5.0.1",
"react-dom": "^16.0.0",
"react-dom": "^16.8.6",
"react-element-to-jsx-string": "^13.0.0",
"react-helmet": "^5.2.0",
"react-hot-loader": "^3.0.0-beta.7",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"react-shallow-testutils": "^3.0.0",
"react-test-renderer": "^16.0.0",
"react-test-renderer": "^16.8.6",
"renovate-config-seek": "^0.4.0",
"seek-style-guide-webpack": "^3.0.1",
"semantic-release": "^8.1.2",
Expand Down
41 changes: 31 additions & 10 deletions react/Checkbox/Checkbox.demo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Checkbox from './Checkbox';
import classnames from 'classnames';
import Checkbox, { STANDARD, BUTTON } from './Checkbox';
import * as sketch from './Checkbox.sketch';
import demoStyles from './Checkbox.demo.less';
import fieldMessageOptions from '../FieldMessage/FieldMessage.demoFragment';
Expand All @@ -15,26 +16,47 @@ class CheckboxContainer extends Component {
super();

this.state = {
checked: false
checked1: false,
checked2: false
};
}

handleChange = event => {
handleChange1 = event => {
this.setState({
checked: event.target.checked
checked1: event.target.checked
});
};

handleChange2 = event => {
this.setState({
checked2: event.target.checked
});
};

render() {
const { component: DemoComponent, componentProps } = this.props;
const { checked } = this.state;
const { checked1, checked2 } = this.state;

return (
<div className={demoStyles.root}>
<div
className={classnames({
[demoStyles.root_isStandard]: componentProps.type === STANDARD,
[demoStyles.root_isButton]: componentProps.type === BUTTON
})}
>
<DemoComponent
{...componentProps}
id="fullTime"
label="Full time"
checked={checked1}
onChange={this.handleChange1}
/>
<DemoComponent
{...componentProps}
checked={checked}
onChange={this.handleChange}
id="partTime"
label="Part time / casual / vacation"
checked={checked2}
onChange={this.handleChange2}
/>
</div>
);
Expand All @@ -49,10 +71,9 @@ export default {
container: CheckboxContainer,
sketch,
initialProps: {
id: 'stillInRole',
label: 'Still in role',
type: 'standard',
// Documentation only:
label: 'Full Time',
checked: false,
onChange: () => {}
},
Expand Down
12 changes: 10 additions & 2 deletions react/Checkbox/Checkbox.demo.less
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
.root > :global(*) {
min-width: 150px; // :(
@import "~seek-style-guide/theme";

.root_isStandard {
display: flex;
flex-direction: column;
width: 220px;
}

.root_isButton > :not(*:last-child) {
margin-right: @gutter-width / 2;
}
40 changes: 31 additions & 9 deletions react/Checkbox/Checkbox.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React, { Component } from 'react';
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import styles from './Checkbox.less';
import CheckMarkIcon from '../CheckMarkIcon/CheckMarkIcon';
import classnames from 'classnames';
import FieldMessage from '../FieldMessage/FieldMessage';
import Text from '../Text/Text';
import { TONE } from '../private/tone';

const STANDARD = 'standard';
const BUTTON = 'button';
export const STANDARD = 'standard';
export const BUTTON = 'button';

function combineClassNames(props = {}, ...classNames) {
const { className, ...restProps } = props;
Expand Down Expand Up @@ -51,12 +52,21 @@ export default class Checkbox extends Component {
};

renderButton(label) {
return <span className={styles.button}>{label}</span>;
return (
<Text
component="span"
baseline={false}
raw={true}
className={styles.button}
>
{label}
</Text>
);
}

renderStandard(label) {
return (
<div className={styles.standard}>
<Fragment>
<div className={styles.checkbox}>
<CheckMarkIcon
className={styles.checkMark}
Expand All @@ -73,8 +83,15 @@ export default class Checkbox extends Component {
className={styles.checkMark}
/>
</div>
<span>{label}</span>
</div>
<Text
component="span"
baseline={false}
raw={true}
className={styles.labelText}
>
{label}
</Text>
</Fragment>
);
}

Expand Down Expand Up @@ -112,7 +129,8 @@ export default class Checkbox extends Component {
onChange,
onFocus,
onBlur,
inputProps
inputProps,
type
} = this.props;

const allInputProps = {
Expand All @@ -122,7 +140,11 @@ export default class Checkbox extends Component {
onChange,
onFocus,
onBlur,
...combineClassNames(inputProps, styles.input),
...combineClassNames(inputProps, {
[styles.input]: true,
[styles.input_isCheckbox]: type === STANDARD,
[styles.input_isButton]: type === BUTTON
}),
type: 'checkbox'
};

Expand Down
65 changes: 49 additions & 16 deletions react/Checkbox/Checkbox.less
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@import (reference) "~seek-style-guide/theme";
@checkbox-size: @row-height * 5;
@touchable-margin: (@touchableTextHeight - @checkbox-size) / 2;

.activeFocusReset() {
.input:not([readonly]):not([disabled]):focus + .label &,
Expand All @@ -11,38 +13,69 @@

.root {
display: inline-block;
position: relative;
}

.input {
opacity: 0;
position: absolute;
pointer-events: none;
}

.input_isCheckbox {
width: @checkbox-size;
height: @checkbox-size;
margin: @touchable-margin 0 0 0;
}

.input_isButton {
width: 100%;
height: @touchableTextHeight;
margin: 0;
}

.label {
display: block;
display: flex;
cursor: pointer;
min-height: @touchableTextHeight;

:checked + & {
:global(*) {
pointer-events: none;
}

.input:checked + &,
.input:checked + & .labelText {
font-weight: @sk-bold;
}
}

.standard {
.touchableText(@standard-type-scale);
height: 100%;
cursor: pointer;
display: flex;
align-items: center;
.labelText {
@media @desktop {
padding: (
((@interaction-type-row-span - @standard-type-row-span) / 2) *
@row-height
)
0;
}
@media @mobile {
padding: (
((@interaction-type-row-span - @standard-type-row-span-mobile) / 2) *
@row-height
)
0;
}
}

.checkbox {
.activeFocusReset();

background-color: @sk-white;
width: @row-height * 5;
height: @row-height * 5;
flex: 0 0 (@row-height * 5);
width: @checkbox-size;
height: @checkbox-size;
flex: 0 0 @checkbox-size;
border: @field-border-width solid @sk-mid-gray-light;
border-radius: @field-border-radius;
margin-top: @touchable-margin;
margin-right: @field-gutter-width;
position: relative;

Expand Down Expand Up @@ -94,18 +127,18 @@

.button {
.activeFocusReset();
.touchableText(@standard-type-scale-mobile);
width: 100%;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
padding: 0 @field-gutter-width;
white-space: nowrap;
overflow: hidden;
background-color: @sk-gray-light;
color: @sk-charcoal;
border: 1px solid @sk-mid-gray-light;
border-radius: 2px;
cursor: pointer;
@media @desktop {
.touchableText(@standard-type-scale);
}

.input:checked + .label & {
font-weight: @sk-bold;
Expand Down
Loading

0 comments on commit 961a19f

Please sign in to comment.