Skip to content

Commit

Permalink
<Checkbox> refactoring and STCOM-529 (vertical label) (#974)
Browse files Browse the repository at this point in the history
* Added 'vertical'-prop for Checkbox which makes it possible to render the label above the checkbox. This change required both structural and style changes. While making the changes I did some minor refactoring and cleaned up the CSS a bit. Updated FilterGroups to match the changes for Checkbox. Added label margin as a variable because I needed to reference it within the Checkbox-component. Also updated Checkbox examples to display a vertical example.

* Only apply the 'for'-prop on the root <label>-element if a 'label'-prop is present. This allows for a checkbox to be rendered inline without a label which makes it possible to render an external label-element and link the two using the 'for'-attribute on the label with the ID of the checkbox. This ensures that there's no double for-attributes which can confuse screen readers. Also added an example for this in Storybook.

* Added readme (WIP)

* Minor readme changes, fixed basic usage example and more clean up and refactoring of the <Checkbox>-component

* Removed obsolete 'labelStyle'-prop

* Removed obsolete 'hover'-prop

* Removed obsolete prop 'marginBottom0'

* Fixed Checkbox tests

* Added inputRef-prop for Checkbox with a corresponding test.

* Updated storybook example

* Warning/error messages were rendered next to the checkbox/label which looked odd in tight spaced UI's. Instead, I changed the feedback messages to be rendered below the checkbox/label like other form elements.

* Further Storybook examples cleanup. Removed some unnecessary logic that could make the exmaples more confusing

* Removed .only from tests

* Updated warning color because it's contrast ratio with a white background was insufficient according to WCAG standards.

* Minor linting fix and removed name from checkboxes in storybook example

* Updated readme

* Setting checkbox as 'inline' if there's no label.

* Updated sr-only helper class after experiencing a weird bug in the stripes-platform when clicking a checkbox

* Renamed some class names, added 'innerClass'-prop which is needed to properly style the FilterGroups component checkboxes and updated the readme

* Fixed tests

* Simplified feedback rendering logic

* Updated readme

* Added additional tests

* Only render a <label> if there's a label to show. Changed poitioning of the input element so that it's on top of the custom checkbox but hidden with opacity: 0; With this change we no longer have any accessibility issues with double label's if a developer uses a checkbox with an external <label>

* Utilized the 'tagName'-prop on the <Label>-component instead of setting a conditional on a separate Element constant.

* Fixed tests and added additional tests. Test coverage is now 100% 🎉

* Removed .only from tests and added 'storybook-static' to eslintignore (it was causing linting to run very slowly and potentially never finish)
  • Loading branch information
rasmuswoelk authored May 31, 2019
1 parent b42bbb8 commit fbb69b0
Show file tree
Hide file tree
Showing 12 changed files with 524 additions and 320 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/artifacts
/node_modules
/storybook-static
207 changes: 106 additions & 101 deletions lib/Checkbox/Checkbox.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,57 +6,28 @@

.checkbox {
display: flex;
flex-direction: column;
position: relative;
color: var(--color-text);
line-height: var(--line-height);
margin-bottom: 0;

&.fullWidth {
width: 100%;
}

&.marginBottom0 {
margin-bottom: 0;
}

/**
* Inline checkbox
*/
&.inline {
display: inline-flex;

/**
* If we only render the checkbox (no label)
*/

&.noLabel {
height: auto;

& label.checkboxLabel {
height: auto;
padding: 6px;
margin: 0;

&::before {
left: 0;
right: 0;
}
}
}
}
}

/* Apply spacing between inline checkboxes when stacked */
.inline + .inline {
margin-left: var(--gutter-static-two-thirds);
margin-right: 0;
}

[dir="rtl"] .inline + .inline {
margin-right: var(--gutter-static-two-thirds);
margin-left: 0;
/**
* Label
*/
.label {
margin-bottom: 0;
}

.labelCheck {
/**
* Custom checkbox styling
*/
.checkboxIcon {
position: relative;
width: var(--checkbox-size);
height: var(--checkbox-size);
Expand All @@ -66,31 +37,103 @@
display: flex;
overflow: hidden;
flex-shrink: 0;
top: 1px;

& svg {
opacity: 0;
}
}

.inner {
min-height: var(--control-min-size-desktop);
display: flex;
align-items: baseline;
cursor: pointer;
flex-grow: 2;
position: relative;
border-radius: var(--radius);
font-size: var(--font-size-medium);
}

/**
* Label text
*/
.labelText {
margin: 0 0 0 var(--gutter-static-one-third);
display: flex;
align-items: center;
min-height: var(--control-min-size-desktop);
}

[dir="rtl"] .labelText {
margin: 0 var(--gutter-static-one-third) 0 0;
}

/**
* Input
*/
.input {
position: absolute;
z-index: 10;
opacity: 0;
cursor: pointer;
}

.noLabel .input {
transform: scale(1.9);
}

/**
* Vertical label alignment
*/
.vertical .label {
flex-direction: column;
align-items: flex-start;

& .labelText {
margin: 0 0 var(--control-label-margin-bottom) 0;
min-height: 0;
}

& path {
stroke: #000;
}
& .inner {
align-items: center;
}
}

/**
* Inline checkbox
*/
.inline {
display: inline-flex;

&.noLabel .inner {
align-items: center;
}
}

/* Apply spacing between inline checkboxes when stacked */
.inline + .inline {
margin-left: var(--gutter-static-two-thirds);
margin-right: 0;
}

[dir="rtl"] .inline + .inline {
margin-right: var(--gutter-static-two-thirds);
margin-left: 0;
}

/**
* Checkbox feedback
*/
.checkboxFeedback {
font-size: var(--font-size-small);
font-size: var(--font-size-medium);
}

/* Warning and error states */
.hasWarning {
& .checkboxFeedback {
color: var(--warn);
}

& .labelCheck {
& .checkboxIcon {
border-color: var(--warn);
}
}
Expand All @@ -100,30 +143,16 @@
color: var(--error);
}

& .labelCheck {
& .checkboxIcon {
border-color: var(--error);
}
}

.checkboxLabel {
padding: var(--input-vertical-padding) 0;
display: flex;
align-items: baseline;
cursor: pointer;
flex-grow: 2;
position: relative;
border-radius: var(--radius);
font-size: var(--font-size-medium);
margin-bottom: 0;

&.disabledLabel {
cursor: not-allowed;
color: var(--color-text-p2);

& .labelCheck {
opacity: 0.5;
}
}
/**
* Interaction styles (hover, focus, active)
*/
.checkboxInteractionStylesControl {
composes: interactionStylesControl from "../sharedStyles/interactionStyles.css";
}

.checkboxInteractionStyles {
Expand All @@ -134,48 +163,24 @@
composes: isFocused from "../sharedStyles/interactionStyles.css";
}

.formLabel {
composes: checkboxLabel;
font-weight: bold;
text-transform: Uppercase;
}

.labelText {
margin: 0 0 0 var(--gutter-static-one-third);
display: flex;
align-items: center;
min-height: var(--control-min-size-desktop);
}

[dir="rtl"] .labelText {
margin: 0 var(--gutter-static-one-third) 0 0;
}

/* fix for shrinkage issues with checkbox as a flex-child */
:global input[type='checkbox'] {
min-width: 16px;
}

/**
* Custom input styling
* Disabled
*/
input.checkboxInput {
margin: 0 9px;
margin-bottom: 2px;
position: absolute;
clip: rect(1px, 1px, 1px, 1px);
z-index: -1;
}
.disabled {
& .checkboxIcon {
opacity: 0.5;
}

/* disabled styles */
.checkboxInput:disabled .labelCheck {
opacity: 0.65;
&:hover .inner {
cursor: default;
}
}

/**
* Checked state
*/
.checkboxInput:checked + .labelCheck {

.input:checked + .checkboxIcon {
background-color: #000;

& svg {
Expand Down
Loading

0 comments on commit fbb69b0

Please sign in to comment.