From cfa234a62cb764d44daa465313d4bbaf0bbcb4cf Mon Sep 17 00:00:00 2001 From: Aniket Handa Date: Fri, 29 Jul 2016 16:08:06 -0700 Subject: [PATCH 1/9] ChoiceField to Checkbox --- src/components/Checkbox/Checkbox.scss | 249 +++++++++++--------------- src/components/Checkbox/Checkbox.tsx | 14 +- 2 files changed, 112 insertions(+), 151 deletions(-) diff --git a/src/components/Checkbox/Checkbox.scss b/src/components/Checkbox/Checkbox.scss index f17399560a0d3..91b7ddc143f24 100644 --- a/src/components/Checkbox/Checkbox.scss +++ b/src/components/Checkbox/Checkbox.scss @@ -5,199 +5,160 @@ // // Office UI Fabric // -------------------------------------------------- -// Choice fields (radio buttons and checkboxes) styles +// Checkbox styles -// Unselected, radio button (default) -.ms-ChoiceField { - @include ms-font-m; - @include ms-u-normalize; +$ms-checkbox-field-size: 20px; +$ms-checkbox-transition-duration: 200ms; +$ms-checkbox-transition-timing: cubic-bezier(.4, 0, .23, 1); + + +.ms-Checkbox { + box-sizing: border-box; + color: $ms-color-neutralPrimary; + font-family: $ms-font-family-base; + font-size: $ms-font-size-m; + font-weight: $ms-font-weight-regular; min-height: 36px; position: relative; .ms-Label { font-size: $ms-font-size-m; padding: 0 0 0 26px; + display: inline-block; } } -//== State: Disabled choicefield -.ms-ChoiceField-input:disabled { - + .ms-ChoiceField-field { - pointer-events: none; - cursor: default; - - &:before { - background-color: $ms-color-neutralTertiaryAlt; - color: $ms-color-neutralTertiaryAlt; - } - - &:after { - border-color: $ms-color-neutralLight; - } - - .ms-Label { - color: $ms-color-neutralTertiary; - } - - @media screen and (-ms-high-contrast: active) { - &:before { - background-color: $ms-color-contrastBlackDisabled; - color: $ms-color-contrastBlackDisabled; - } - - &:after { - border-color: $ms-color-contrastBlackDisabled; - } - - .ms-Label { - color: $ms-color-contrastBlackDisabled; - } - } - - @media screen and (-ms-high-contrast: black-on-white) { - &:before { - background-color: $ms-color-contrastWhiteDisabled; - color: $ms-color-contrastWhiteDisabled; - } - - &:after { - border-color: $ms-color-contrastWhiteDisabled; - } +// The hidden input +.ms-Checkbox-input { + position: absolute; + opacity: 0; +} - .ms-Label { - color: $ms-color-contrastWhiteDisabled; - } - } - } +// The checkbox square container +.ms-Checkbox-field::before { + content: ''; + display: inline-block; + border: 2px solid $ms-color-neutralTertiary; + width: $ms-checkbox-field-size; + height: $ms-checkbox-field-size; + font-weight: normal; + position: absolute; + box-sizing: border-box; + transition-property: background, border, border-color; + transition-duration: $ms-checkbox-transition-duration; + transition-timing-function: $ms-checkbox-transition-timing; } -// The original unstyled input element -.ms-ChoiceField-input { +// The check mark icon +.ms-Checkbox-field::after { + @include ms-Icon--CheckMark; + font-family: 'FabricMDL2Icons'; + display: none; position: absolute; - opacity: 0; - top: 8px; + font-weight: 900; + background-color: transparent; + font-size: $ms-font-size-s-plus; + top: 0; + color: $ms-color-white; + line-height: $ms-checkbox-field-size; + width: $ms-checkbox-field-size; + text-align: center; + + @media screen and (-ms-high-contrast: active) { + color: $ms-color-black; + } - &:focus:not(:disabled) { - + .ms-ChoiceField-field:after { - border-color: $ms-color-neutralSecondaryAlt; - } + @media screen and (-ms-high-contrast: black-on-white) { + color: $ms-color-white; } } -// The choicefield radio button or checkbox -.ms-ChoiceField-field { +// The checkbox field +.ms-Checkbox-field { display: inline-block; cursor: pointer; margin-top: 8px; position: relative; - - // The actual styled choicefield element - radio button by default - &:after { - content: ''; - display: inline-block; - border: 1px $ms-color-neutralTertiaryAlt solid; - width: 19px; - height: 19px; - cursor: pointer; - position: relative; - font-weight: normal; - left: -1px; - top: -1px; - border-radius: 50%; - position: absolute; - } + outline: 0; + vertical-align: top; &:hover { - &:after { + &::before { + border-color: $ms-color-neutralSecondaryAlt; + } + .ms-Label { + color: $ms-color-black; + } + } + &:focus { + outline: 1px solid $ms-color-neutralSecondaryAlt; + } + &:active { + &::before { border-color: $ms-color-neutralSecondaryAlt; } - .ms-Label { color: $ms-color-black; } } -} -// A selected radio button -.ms-ChoiceField-input:checked { - + .ms-ChoiceField-field { - // Circle indicating a checked radio button - &:before { - background-color: $ms-color-neutralSecondary; - border-color: $ms-color-neutralSecondary; - color: $ms-color-neutralSecondary; - border-radius: 50%; - content: '\00a0'; - display: inline-block; - position: absolute; - top: 4px; - bottom: 0; - left: 4px; - width: 11px; - height: 11px; - box-sizing: border-box; + //== State: A disabled checkbox + // + &.is-disabled { + cursor: default; + + &::before { + background-color: $ms-color-neutralTertiaryAlt; + border-color: $ms-color-neutralTertiaryAlt; + color: $ms-color-neutralTertiaryAlt; @media screen and (-ms-high-contrast: active) { - border-color: $ms-color-white; - background-color: $ms-color-white; + border-color: $ms-color-contrastBlackDisabled; } @media screen and (-ms-high-contrast: black-on-white) { - border-color: $ms-color-black; - background-color: $ms-color-black; + border-color: $ms-color-contrastWhiteDisabled; } } - &:hover:before { - background-color: $ms-color-neutralDark; - color: $ms-color-neutralDark; - } - } -} + .ms-Label { + color: $ms-color-neutralTertiary; -// Checkbox -.ms-ChoiceField-input[type="checkbox"] { - + .ms-ChoiceField-field:after { - border-radius: 0; + @media screen and (-ms-high-contrast: active) { + color: $ms-color-contrastBlackDisabled; + } + + @media screen and (-ms-high-contrast: black-on-white) { + color: $ms-color-contrastWhiteDisabled; + } + } } -} -// A selected checkbox -.ms-ChoiceField-input[type="checkbox"]:checked { - + .ms-ChoiceField-field { - &:before { - @include ms-Icon; - content: '\e041'; - background-color: transparent; - border-radius: 0; - font-size: $ms-font-size-s-plus; - top: 3px; - left: 3px; + //== State: A checkbox is checked + // + &.is-checked { + &::before { + border: 10px solid $ms-color-themePrimary; + background-color: $ms-color-themePrimary; @media screen and (-ms-high-contrast: active) { - color: $ms-color-white; - border-color: transparent; - background-color: transparent; + border-color: $ms-color-contrastBlackSelected; } @media screen and (-ms-high-contrast: black-on-white) { - color: $ms-color-black; - border-color: transparent; - background-color: transparent; + border-color: $ms-color-contrastWhiteSelected; } } - } -} + &::after { + display: block; + } -//== Component: Choicefield group -// -// Choice field groups contain multiple radio buttons or checkboxes -.ms-ChoiceFieldGroup { - margin-bottom: 4px; -} - -// TODO: overrides that need to be removed. -.ms-ChoiceField { - user-select: none; + &:hover, + &:focus { + &::before { + border-color: $ms-color-themeDarkAlt; + } + } + } } \ No newline at end of file diff --git a/src/components/Checkbox/Checkbox.tsx b/src/components/Checkbox/Checkbox.tsx index 7cbc66e3525bb..d8366b1426678 100644 --- a/src/components/Checkbox/Checkbox.tsx +++ b/src/components/Checkbox/Checkbox.tsx @@ -16,7 +16,7 @@ export class Checkbox extends React.Component { }; private _id: string; - private _checkBox: HTMLInputElement; + private _checkbox: HTMLInputElement; constructor(props: ICheckboxProps) { super(props); @@ -43,12 +43,12 @@ export class Checkbox extends React.Component { let { isChecked } = this.state; return ( -
+
this._checkBox = c } + ref={ (c): HTMLInputElement => this._checkbox = c } id={ this._id } name={ this._id } - className='ms-ChoiceField-input' + className='ms-Checkbox-input' type='checkbox' role='checkbox' checked={ isChecked } @@ -56,7 +56,7 @@ export class Checkbox extends React.Component { onChange={ this._handleInputChange } aria-checked={ isChecked } /> -
@@ -64,8 +64,8 @@ export class Checkbox extends React.Component { } public focus() { - if (this._checkBox) { - this._checkBox.focus(); + if (this._checkbox) { + this._checkbox.focus(); } } From 05ae8f55e8bc581a30d9f8edf54903bcf3e7be5f Mon Sep 17 00:00:00 2001 From: Aniket Handa Date: Fri, 29 Jul 2016 17:51:17 -0700 Subject: [PATCH 2/9] fixing focus, rtl, added example --- src/components/Checkbox/Checkbox.scss | 84 ++++++++++++++----- src/components/Checkbox/Checkbox.tsx | 38 +++++++-- .../examples/Checkbox.Basic.Example.tsx | 1 + 3 files changed, 94 insertions(+), 29 deletions(-) diff --git a/src/components/Checkbox/Checkbox.scss b/src/components/Checkbox/Checkbox.scss index 91b7ddc143f24..761f6a4b0cd76 100644 --- a/src/components/Checkbox/Checkbox.scss +++ b/src/components/Checkbox/Checkbox.scss @@ -11,7 +11,6 @@ $ms-checkbox-field-size: 20px; $ms-checkbox-transition-duration: 200ms; $ms-checkbox-transition-timing: cubic-bezier(.4, 0, .23, 1); - .ms-Checkbox { box-sizing: border-box; color: $ms-color-neutralPrimary; @@ -19,11 +18,13 @@ $ms-checkbox-transition-timing: cubic-bezier(.4, 0, .23, 1); font-size: $ms-font-size-m; font-weight: $ms-font-weight-regular; min-height: 36px; + border: 1px solid transparent; position: relative; + @include padding-left(8px); .ms-Label { font-size: $ms-font-size-m; - padding: 0 0 0 26px; + @include padding(0, 0, 0, 26px); display: inline-block; } } @@ -32,6 +33,7 @@ $ms-checkbox-transition-timing: cubic-bezier(.4, 0, .23, 1); .ms-Checkbox-input { position: absolute; opacity: 0; + top: 8px } // The checkbox square container @@ -79,7 +81,6 @@ $ms-checkbox-transition-timing: cubic-bezier(.4, 0, .23, 1); cursor: pointer; margin-top: 8px; position: relative; - outline: 0; vertical-align: top; &:hover { @@ -91,7 +92,17 @@ $ms-checkbox-transition-timing: cubic-bezier(.4, 0, .23, 1); } } &:focus { - outline: 1px solid $ms-color-neutralSecondaryAlt; + &::before { + border-color: $ms-color-neutralSecondaryAlt; + } + + &.is-disabled::before { + border-color: $ms-color-neutralTertiaryAlt; + } + + &.is-checked::before { + border-color: $ms-color-themeDarkAlt; + } } &:active { &::before { @@ -102,11 +113,46 @@ $ms-checkbox-transition-timing: cubic-bezier(.4, 0, .23, 1); } } + //== State: A checkbox is checked + // + &.is-checked { + &::before { + border: 10px solid $ms-color-themePrimary; + background-color: $ms-color-themePrimary; + + @media screen and (-ms-high-contrast: active) { + border-color: $ms-color-contrastBlackSelected; + } + + @media screen and (-ms-high-contrast: black-on-white) { + border-color: $ms-color-contrastWhiteSelected; + } + } + + &::after { + display: block; + } + + &:hover, + &:focus { + &::before { + border-color: $ms-color-themeDarkAlt; + } + } + } + //== State: A disabled checkbox // &.is-disabled { cursor: default; + &:hover, + &:focus { + &::before { + border-color: $ms-color-neutralTertiaryAlt; + } + } + &::before { background-color: $ms-color-neutralTertiaryAlt; border-color: $ms-color-neutralTertiaryAlt; @@ -134,31 +180,23 @@ $ms-checkbox-transition-timing: cubic-bezier(.4, 0, .23, 1); } } - //== State: A checkbox is checked + //== State: A checkbox in focus // - &.is-checked { + &.is-inFocus { &::before { - border: 10px solid $ms-color-themePrimary; - background-color: $ms-color-themePrimary; - - @media screen and (-ms-high-contrast: active) { - border-color: $ms-color-contrastBlackSelected; - } - - @media screen and (-ms-high-contrast: black-on-white) { - border-color: $ms-color-contrastWhiteSelected; - } + border-color: $ms-color-neutralSecondaryAlt; } - &::after { - display: block; + &.is-disabled::before { + border-color: $ms-color-neutralTertiaryAlt; } - &:hover, - &:focus { - &::before { - border-color: $ms-color-themeDarkAlt; - } + &.is-checked::before { + border-color: $ms-color-themeDarkAlt; } } +} + +.is-focusVisible .ms-Checkbox.is-inFocus { + border: 1px solid $ms-color-neutralPrimary; } \ No newline at end of file diff --git a/src/components/Checkbox/Checkbox.tsx b/src/components/Checkbox/Checkbox.tsx index d8366b1426678..0d931b7787744 100644 --- a/src/components/Checkbox/Checkbox.tsx +++ b/src/components/Checkbox/Checkbox.tsx @@ -16,7 +16,8 @@ export class Checkbox extends React.Component { }; private _id: string; - private _checkbox: HTMLInputElement; + private _checkbox: HTMLElement; + private _checkboxInput: HTMLInputElement; constructor(props: ICheckboxProps) { super(props); @@ -30,6 +31,11 @@ export class Checkbox extends React.Component { this._handleInputChange = this._handleInputChange.bind(this); } + public componentDidMount() { + this._checkboxInput.addEventListener("focus", this._onFocus.bind(this), false); + this._checkboxInput.addEventListener("blur", this._onBlur.bind(this), false); + } + public componentWillReceiveProps(newProps: ICheckboxProps) { if (newProps.isChecked !== this.props.isChecked) { this.setState({ @@ -38,14 +44,22 @@ export class Checkbox extends React.Component { } } + public componentWillUnmount() { + this._checkboxInput.removeEventListener("focus", this._onFocus.bind(this)); + this._checkboxInput.removeEventListener("blur", this._onBlur.bind(this)); + } + public render() { let { text, isEnabled, className } = this.props; let { isChecked } = this.state; return ( -
+
this._checkbox = c } + > this._checkbox = c } + ref={ (c): HTMLInputElement => this._checkboxInput = c } id={ this._id } name={ this._id } className='ms-Checkbox-input' @@ -56,7 +70,11 @@ export class Checkbox extends React.Component { onChange={ this._handleInputChange } aria-checked={ isChecked } /> -
@@ -64,11 +82,19 @@ export class Checkbox extends React.Component { } public focus() { - if (this._checkbox) { - this._checkbox.focus(); + if (this._checkboxInput) { + this._checkboxInput.focus(); } } + private _onFocus(): void { + this._checkbox.classList.add("is-inFocus"); + } + + private _onBlur(): void { + this._checkbox.classList.remove("is-inFocus"); + } + private _handleInputChange(evt: React.FormEvent) { let { onChanged } = this.props; const isChecked = (evt.target as HTMLInputElement).checked; diff --git a/src/demo/pages/CheckboxPage/examples/Checkbox.Basic.Example.tsx b/src/demo/pages/CheckboxPage/examples/Checkbox.Basic.Example.tsx index e77760d62807b..eac06c966bf4d 100644 --- a/src/demo/pages/CheckboxPage/examples/Checkbox.Basic.Example.tsx +++ b/src/demo/pages/CheckboxPage/examples/Checkbox.Basic.Example.tsx @@ -14,6 +14,7 @@ export class CheckboxBasicExample extends React.Component {
+
); From e2c5447441640e59145164785a5db033314b26f4 Mon Sep 17 00:00:00 2001 From: Aniket Handa Date: Mon, 1 Aug 2016 11:21:07 -0700 Subject: [PATCH 3/9] Fixing tslint errors --- src/components/Checkbox/Checkbox.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/Checkbox/Checkbox.tsx b/src/components/Checkbox/Checkbox.tsx index 0d931b7787744..cfe15d4e01b06 100644 --- a/src/components/Checkbox/Checkbox.tsx +++ b/src/components/Checkbox/Checkbox.tsx @@ -32,8 +32,8 @@ export class Checkbox extends React.Component { } public componentDidMount() { - this._checkboxInput.addEventListener("focus", this._onFocus.bind(this), false); - this._checkboxInput.addEventListener("blur", this._onBlur.bind(this), false); + this._checkboxInput.addEventListener('focus', this._onFocus.bind(this), false); + this._checkboxInput.addEventListener('blur', this._onBlur.bind(this), false); } public componentWillReceiveProps(newProps: ICheckboxProps) { @@ -45,8 +45,8 @@ export class Checkbox extends React.Component { } public componentWillUnmount() { - this._checkboxInput.removeEventListener("focus", this._onFocus.bind(this)); - this._checkboxInput.removeEventListener("blur", this._onBlur.bind(this)); + this._checkboxInput.removeEventListener('focus', this._onFocus.bind(this)); + this._checkboxInput.removeEventListener('blur', this._onBlur.bind(this)); } public render() { @@ -88,11 +88,11 @@ export class Checkbox extends React.Component { } private _onFocus(): void { - this._checkbox.classList.add("is-inFocus"); + this._checkbox.classList.add('is-inFocus'); } private _onBlur(): void { - this._checkbox.classList.remove("is-inFocus"); + this._checkbox.classList.remove('is-inFocus'); } private _handleInputChange(evt: React.FormEvent) { From d7df4d3d59ef905492aaee60d76a780c5695e692 Mon Sep 17 00:00:00 2001 From: Aniket Handa Date: Mon, 1 Aug 2016 15:28:56 -0700 Subject: [PATCH 4/9] Fixing styles for choiceField --- src/components/Checkbox/Checkbox.scss | 1 + src/components/ChoiceGroup/ChoiceGroup.scss | 304 ++++++++++-------- src/components/ChoiceGroup/ChoiceGroup.tsx | 10 +- .../examples/ChoiceGroup.Basic.Example.tsx | 6 + 4 files changed, 177 insertions(+), 144 deletions(-) diff --git a/src/components/Checkbox/Checkbox.scss b/src/components/Checkbox/Checkbox.scss index 761f6a4b0cd76..a763fb331f338 100644 --- a/src/components/Checkbox/Checkbox.scss +++ b/src/components/Checkbox/Checkbox.scss @@ -82,6 +82,7 @@ $ms-checkbox-transition-timing: cubic-bezier(.4, 0, .23, 1); margin-top: 8px; position: relative; vertical-align: top; + user-select: none; &:hover { &::before { diff --git a/src/components/ChoiceGroup/ChoiceGroup.scss b/src/components/ChoiceGroup/ChoiceGroup.scss index 20b6222343a41..0c0dcf9885ff4 100644 --- a/src/components/ChoiceGroup/ChoiceGroup.scss +++ b/src/components/ChoiceGroup/ChoiceGroup.scss @@ -5,211 +5,233 @@ // // Office UI Fabric // -------------------------------------------------- -// Choice fields (radio buttons and checkboxes) styles +// Choice fields (radio buttons and choiceFieldes) styles -//== Component: Choicefield group -// -// Choice field groups contain multiple radio buttons or checkboxes -.ms-ChoiceFieldGroup { - @include ms-baseFont; - margin-bottom: 4px; - .ms-ChoiceFieldGroup-list { - padding: 0; - margin: 0; - } -} -// TODO: remove overrides and scrub CSS +$ms-choiceField-field-size: 20px; +$ms-choiceField-transition-duration: 200ms; +$ms-choiceField-transition-duration-inner: 150ms; +$ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); -// Unselected, radio button (default) .ms-ChoiceField { - @include ms-font-m; - @include ms-u-normalize; + box-sizing: border-box; + color: $ms-color-neutralPrimary; + font-family: $ms-font-family-base; + font-size: $ms-font-size-m; + font-weight: $ms-font-weight-regular; min-height: 36px; + border: 1px solid transparent; position: relative; + @include padding-left(8px); .ms-Label { font-size: $ms-font-size-m; - padding: 0 0 0 26px; + @include padding(0, 0, 0, 26px); + display: inline-block; } } -//== State: Disabled choicefield -.ms-ChoiceField-input:disabled { - + .ms-ChoiceField-field { - pointer-events: none; - cursor: default; - - &:before { - background-color: $ms-color-neutralTertiaryAlt; - color: $ms-color-neutralTertiaryAlt; - } - - &:after { - border-color: $ms-color-neutralLight; - } - - .ms-Label { - color: $ms-color-neutralTertiary; - } - - @media screen and (-ms-high-contrast: active) { - &:before { - background-color: $ms-color-contrastBlackDisabled; - color: $ms-color-contrastBlackDisabled; - } - - &:after { - border-color: $ms-color-contrastBlackDisabled; - } - - .ms-Label { - color: $ms-color-contrastBlackDisabled; - } - } - - @media screen and (-ms-high-contrast: black-on-white) { - &:before { - background-color: $ms-color-contrastWhiteDisabled; - color: $ms-color-contrastWhiteDisabled; - } - - &:after { - border-color: $ms-color-contrastWhiteDisabled; - } +// The hidden input +.ms-ChoiceField-input { + position: absolute; + opacity: 0; + top: 8px +} - .ms-Label { - color: $ms-color-contrastWhiteDisabled; - } - } - } +// The choiceField square container +.ms-ChoiceField-field::before { + content: ''; + display: inline-block; + border: 2px solid $ms-color-neutralTertiary; + width: $ms-choiceField-field-size; + height: $ms-choiceField-field-size; + font-weight: normal; + position: absolute; + box-sizing: border-box; + transition-property: background, border, border-color; + transition-duration: $ms-choiceField-transition-duration; + transition-timing-function: $ms-choiceField-transition-timing; + border-radius: 50%; } -// The original unstyled input element -.ms-ChoiceField-input { +// The check mark icon +.ms-ChoiceField-field::after { + content: ''; + width: 0; + height: 0; + border-radius: 50%; position: absolute; - opacity: 0; top: 8px; + @include left(8px); + bottom: 0; + right: 0; + transition-property: top, left, width, height; + transition-duration: $ms-choiceField-transition-duration-inner; + transition-timing-function: $ms-choiceField-transition-timing; + box-sizing: border-box; + + @media screen and (-ms-high-contrast: active) { + color: $ms-color-contrastBlackDisabled; + } - &:focus:not(:disabled) { - + .ms-ChoiceField-field:after { - border-color: $ms-color-neutralSecondaryAlt; - } + @media screen and (-ms-high-contrast: black-on-white) { + color: $ms-color-contrastWhiteDisabled; } } -// The choicefield radio button or checkbox +// The choiceField field .ms-ChoiceField-field { display: inline-block; cursor: pointer; margin-top: 8px; position: relative; - - // The actual styled choicefield element - radio button by default - &:after { - content: ''; - display: inline-block; - border: 1px $ms-color-neutralTertiaryAlt solid; - width: 19px; - height: 19px; - cursor: pointer; - position: relative; - font-weight: normal; - left: -1px; - top: -1px; - border-radius: 50%; - position: absolute; - } + vertical-align: top; + user-select: none; &:hover { - &:after { + &::before { border-color: $ms-color-neutralSecondaryAlt; } + .ms-Label { + color: $ms-color-black; + } + } + &:focus { + &::before { + border-color: $ms-color-neutralSecondaryAlt; + } + + &.is-disabled::before { + border-color: $ms-color-neutralTertiaryAlt; + } + &.is-checked::before { + border-color: $ms-color-themeDarkAlt; + } + } + &:active { + &::before { + border-color: $ms-color-neutralSecondaryAlt; + } .ms-Label { color: $ms-color-black; } } -} -// A selected radio button -.ms-ChoiceField-input:checked { - + .ms-ChoiceField-field { - // Circle indicating a checked radio button - &:before { - background-color: $ms-color-neutralSecondary; - border-color: $ms-color-neutralSecondary; - color: $ms-color-neutralSecondary; - border-radius: 50%; - content: '\00a0'; - display: inline-block; - position: absolute; - top: 4px; - bottom: 0; - left: 4px; - width: 11px; - height: 11px; - box-sizing: border-box; + //== State: A choiceField is checked + // + &.is-checked { + &::before { + border: 2px solid $ms-color-themePrimary; + background-color: transparent; + + @media screen and (-ms-high-contrast: active) { + border-color: $ms-color-contrastBlackSelected; + } + + @media screen and (-ms-high-contrast: black-on-white) { + border-color: $ms-color-contrastWhiteSelected; + } + } + + &::after { + background-color: $ms-color-themePrimary; + top: 5px; + @include left(5px); + width: 10px; + height: 10px; @media screen and (-ms-high-contrast: active) { - border-color: $ms-color-white; - background-color: $ms-color-white; + background-color: $ms-color-contrastBlackSelected; } @media screen and (-ms-high-contrast: black-on-white) { - border-color: $ms-color-black; - background-color: $ms-color-black; + background-color: $ms-color-contrastWhiteSelected; } } - &:hover:before { - background-color: $ms-color-neutralDark; - color: $ms-color-neutralDark; + &:hover, + &:focus { + &::before { + border-color: $ms-color-themeDarkAlt; + } } } -} -// Checkbox -.ms-ChoiceField-input[type="checkbox"] { - + .ms-ChoiceField-field:after { - border-radius: 0; - } -} + //== State: A disabled choiceField + // + &.is-disabled { + cursor: default; -// A selected checkbox -.ms-ChoiceField-input[type="checkbox"]:checked { - + .ms-ChoiceField-field { - &:before { - @include ms-Icon; - content: '\e041'; - background-color: transparent; - border-radius: 0; - font-size: $ms-font-size-s-plus; - top: 3px; - left: 3px; + &:hover, + &:focus { + &::before { + border-color: $ms-color-neutralTertiaryAlt; + } + } + + &::before { + background-color: $ms-color-neutralTertiaryAlt; + border-color: $ms-color-neutralTertiaryAlt; + color: $ms-color-neutralTertiaryAlt; @media screen and (-ms-high-contrast: active) { - color: $ms-color-white; - border-color: transparent; - background-color: transparent; + border-color: $ms-color-contrastBlackDisabled; } @media screen and (-ms-high-contrast: black-on-white) { - color: $ms-color-black; - border-color: transparent; - background-color: transparent; + border-color: $ms-color-contrastWhiteDisabled; + } + } + + .ms-Label { + color: $ms-color-neutralTertiary; + + @media screen and (-ms-high-contrast: active) { + color: $ms-color-contrastBlackDisabled; + } + + @media screen and (-ms-high-contrast: black-on-white) { + color: $ms-color-contrastWhiteDisabled; } } } + + //== State: A choiceField in focus + // + &.is-inFocus { + &::before { + border-color: $ms-color-neutralSecondaryAlt; + } + + &.is-disabled::before { + border-color: $ms-color-neutralTertiaryAlt; + } + + &.is-checked::before { + border-color: $ms-color-themeDarkAlt; + } + } +} + +.is-focusVisible .ms-ChoiceField.is-inFocus { + border: 1px solid $ms-color-neutralPrimary; } + //== Component: Choicefield group // -// Choice field groups contain multiple radio buttons or checkboxes +// Choice field groups contain multiple radio buttons or choiceFieldes .ms-ChoiceFieldGroup { + @include ms-baseFont; margin-bottom: 4px; + + .ms-ChoiceFieldGroup-list { + padding: 0; + margin: 0; + } } // TODO: overrides that need to be removed. diff --git a/src/components/ChoiceGroup/ChoiceGroup.tsx b/src/components/ChoiceGroup/ChoiceGroup.tsx index 455fa20f46803..cff09c5119d24 100644 --- a/src/components/ChoiceGroup/ChoiceGroup.tsx +++ b/src/components/ChoiceGroup/ChoiceGroup.tsx @@ -60,7 +60,7 @@ export class ChoiceGroup extends React.Component (
this._inputElement = c } @@ -94,7 +94,11 @@ export class ChoiceGroup extends React.Component { option.imageSrc @@ -119,7 +123,7 @@ export class ChoiceGroup extends React.Component - + { option.text }
: { option.text } diff --git a/src/demo/pages/ChoiceGroupPage/examples/ChoiceGroup.Basic.Example.tsx b/src/demo/pages/ChoiceGroupPage/examples/ChoiceGroup.Basic.Example.tsx index 0108d007bbda0..d0f936e299e31 100644 --- a/src/demo/pages/ChoiceGroupPage/examples/ChoiceGroup.Basic.Example.tsx +++ b/src/demo/pages/ChoiceGroupPage/examples/ChoiceGroup.Basic.Example.tsx @@ -41,6 +41,12 @@ export class ChoiceGroupBasicExample extends React.Component Date: Mon, 1 Aug 2016 17:50:46 -0700 Subject: [PATCH 5/9] Adding in-focus state, image choice field clean up --- src/components/ChoiceGroup/ChoiceGroup.scss | 75 ++++++++------------- src/components/ChoiceGroup/ChoiceGroup.tsx | 38 +++++++++-- 2 files changed, 59 insertions(+), 54 deletions(-) diff --git a/src/components/ChoiceGroup/ChoiceGroup.scss b/src/components/ChoiceGroup/ChoiceGroup.scss index 0c0dcf9885ff4..123245cb51640 100644 --- a/src/components/ChoiceGroup/ChoiceGroup.scss +++ b/src/components/ChoiceGroup/ChoiceGroup.scss @@ -3,17 +3,27 @@ // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information. // -// Office UI Fabric // -------------------------------------------------- // Choice fields (radio buttons and choiceFieldes) styles - - $ms-choiceField-field-size: 20px; $ms-choiceField-transition-duration: 200ms; $ms-choiceField-transition-duration-inner: 150ms; $ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); +//== Component: Choicefield group +// + +.ms-ChoiceFieldGroup { + @include ms-baseFont; + margin-bottom: 4px; + + .ms-ChoiceFieldGroup-list { + padding: 0; + margin: 0; + } +} + .ms-ChoiceField { box-sizing: border-box; color: $ms-color-neutralPrimary; @@ -39,7 +49,7 @@ $ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); top: 8px } -// The choiceField square container +// The choiceField container .ms-ChoiceField-field::before { content: ''; display: inline-block; @@ -55,7 +65,7 @@ $ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); border-radius: 50%; } -// The check mark icon +// The circle .ms-ChoiceField-field::after { content: ''; width: 0; @@ -198,7 +208,7 @@ $ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); } } - //== State: A choiceField in focus + //== State: A choiceField in focus // &.is-inFocus { &::before { @@ -215,27 +225,6 @@ $ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); } } -.is-focusVisible .ms-ChoiceField.is-inFocus { - border: 1px solid $ms-color-neutralPrimary; -} - - - -//== Component: Choicefield group -// -// Choice field groups contain multiple radio buttons or choiceFieldes -.ms-ChoiceFieldGroup { - @include ms-baseFont; - margin-bottom: 4px; - - .ms-ChoiceFieldGroup-list { - padding: 0; - margin: 0; - } -} - -// TODO: overrides that need to be removed. - .ms-ChoiceField--image { $fieldMinWidth: 164px; $fieldPadding: 20px; @@ -245,6 +234,7 @@ $ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); font-size: 0; @include margin-right(6px); + @include padding-left(0px); @include ms-bgColor-neutralLighter; .ms-ChoiceField-field--image { @@ -252,19 +242,16 @@ $ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); box-sizing: border-box; min-width: $fieldMinWidth; - cursor: pointer; padding: $fieldPadding $fieldPadding 12px $fieldPadding; - text-align: center; - - transition: all 200ms ease; + transition: all $ms-choiceField-transition-duration ease; .ms-ChoiceField-innerField { position: relative; .ms-ChoiceField-imageWrapper { - transition: opacity 200ms ease; + transition: opacity $ms-choiceField-transition-duration ease; &.is-hidden { position: absolute; @@ -307,27 +294,19 @@ $ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); @include ms-fontColor-neutralPrimary; } } - } - .ms-ChoiceField-input:checked { - & + .ms-ChoiceField-field--image .ms-ChoiceField-labelWrapper .ms-ChoiceField-icon { - display: inline-block; - } - - & + .ms-ChoiceField-field--image { + &.is-checked { @include ms-bgColor-themeLighter; + + .ms-ChoiceField-labelWrapper .ms-ChoiceField-icon { + display: inline-block; + } } } } -.is-focusVisible .ms-ChoiceField-input:focus + .ms-ChoiceField-field--image:before { - position: absolute; - top: -2px; - right: -2px; - bottom: -2px; - left: -2px; - +.is-focusVisible .ms-ChoiceField.is-inFocus { border: 1px solid $ms-color-neutralPrimary; - - content: ''; } + + diff --git a/src/components/ChoiceGroup/ChoiceGroup.tsx b/src/components/ChoiceGroup/ChoiceGroup.tsx index cff09c5119d24..904b4da0e64d1 100644 --- a/src/components/ChoiceGroup/ChoiceGroup.tsx +++ b/src/components/ChoiceGroup/ChoiceGroup.tsx @@ -17,7 +17,8 @@ export class ChoiceGroup extends React.Component { + inputElement.addEventListener('focus', this._onFocus.bind(this), false); + inputElement.addEventListener('blur', this._onBlur.bind(this), false); + }); } public componentWillReceiveProps(newProps: IChoiceGroupProps) { @@ -41,6 +51,13 @@ export class ChoiceGroup extends React.Component { + inputElement.removeEventListener('focus', this._onFocus.bind(this)); + inputElement.removeEventListener('blur', this._onBlur.bind(this)); + }); + } + public render() { let { label, options, className, required } = this.props; let { keyChecked } = this.state; @@ -57,13 +74,14 @@ export class ChoiceGroup extends React.Component{ label } : null }
- { options.map(option => ( + { options.map((option, index) => (
{ this._choiceFieldElements.push(c); return c; } } > this._inputElement = c } + ref={ (c): HTMLInputElement => { this._inputElements.push(c); return c; } } id={ `${this._id}-${option.key}` } className='ms-ChoiceField-input' type='radio' @@ -83,9 +101,17 @@ export class ChoiceGroup extends React.Component Date: Mon, 1 Aug 2016 18:08:59 -0700 Subject: [PATCH 6/9] fixing focus() --- src/components/ChoiceGroup/ChoiceGroup.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/components/ChoiceGroup/ChoiceGroup.tsx b/src/components/ChoiceGroup/ChoiceGroup.tsx index 904b4da0e64d1..c27537c39469d 100644 --- a/src/components/ChoiceGroup/ChoiceGroup.tsx +++ b/src/components/ChoiceGroup/ChoiceGroup.tsx @@ -17,6 +17,7 @@ export class ChoiceGroup extends React.Component -
+
this._choiceFieldGroup = c } + >
{ this.props.label ? : null }
@@ -101,9 +107,9 @@ export class ChoiceGroup extends React.Component Date: Tue, 2 Aug 2016 10:56:17 -0700 Subject: [PATCH 7/9] Tslint errors --- src/components/ChoiceGroup/ChoiceGroup.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/ChoiceGroup/ChoiceGroup.tsx b/src/components/ChoiceGroup/ChoiceGroup.tsx index c27537c39469d..a2b9bf68a5f03 100644 --- a/src/components/ChoiceGroup/ChoiceGroup.tsx +++ b/src/components/ChoiceGroup/ChoiceGroup.tsx @@ -113,11 +113,15 @@ export class ChoiceGroup extends React.Component Date: Tue, 2 Aug 2016 12:09:00 -0700 Subject: [PATCH 8/9] Adding role to children of ChoiceGroup --- src/components/ChoiceGroup/ChoiceGroup.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/ChoiceGroup/ChoiceGroup.tsx b/src/components/ChoiceGroup/ChoiceGroup.tsx index a2b9bf68a5f03..bfb20adb2f041 100644 --- a/src/components/ChoiceGroup/ChoiceGroup.tsx +++ b/src/components/ChoiceGroup/ChoiceGroup.tsx @@ -91,6 +91,7 @@ export class ChoiceGroup extends React.Component Date: Tue, 2 Aug 2016 14:37:29 -0700 Subject: [PATCH 9/9] Removing unnecessary attributes, addressing comments, whitespace --- src/components/Checkbox/Checkbox.scss | 10 +++++++--- src/components/Checkbox/Checkbox.tsx | 3 --- src/components/ChoiceGroup/ChoiceGroup.scss | 17 +++++++++-------- src/components/ChoiceGroup/ChoiceGroup.tsx | 8 ++++---- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/components/Checkbox/Checkbox.scss b/src/components/Checkbox/Checkbox.scss index a763fb331f338..0ab128bf4ef53 100644 --- a/src/components/Checkbox/Checkbox.scss +++ b/src/components/Checkbox/Checkbox.scss @@ -88,12 +88,14 @@ $ms-checkbox-transition-timing: cubic-bezier(.4, 0, .23, 1); &::before { border-color: $ms-color-neutralSecondaryAlt; } + .ms-Label { color: $ms-color-black; } } + &:focus { - &::before { + &::before { border-color: $ms-color-neutralSecondaryAlt; } @@ -105,16 +107,18 @@ $ms-checkbox-transition-timing: cubic-bezier(.4, 0, .23, 1); border-color: $ms-color-themeDarkAlt; } } + &:active { &::before { border-color: $ms-color-neutralSecondaryAlt; } + .ms-Label { color: $ms-color-black; } } - //== State: A checkbox is checked + //== State: A checkbox is checked // &.is-checked { &::before { @@ -200,4 +204,4 @@ $ms-checkbox-transition-timing: cubic-bezier(.4, 0, .23, 1); .is-focusVisible .ms-Checkbox.is-inFocus { border: 1px solid $ms-color-neutralPrimary; -} \ No newline at end of file +} diff --git a/src/components/Checkbox/Checkbox.tsx b/src/components/Checkbox/Checkbox.tsx index cfe15d4e01b06..66bf8f6715319 100644 --- a/src/components/Checkbox/Checkbox.tsx +++ b/src/components/Checkbox/Checkbox.tsx @@ -64,16 +64,13 @@ export class Checkbox extends React.Component { name={ this._id } className='ms-Checkbox-input' type='checkbox' - role='checkbox' checked={ isChecked } disabled={ !isEnabled } onChange={ this._handleInputChange } - aria-checked={ isChecked } /> diff --git a/src/components/ChoiceGroup/ChoiceGroup.scss b/src/components/ChoiceGroup/ChoiceGroup.scss index 123245cb51640..206d150389e46 100644 --- a/src/components/ChoiceGroup/ChoiceGroup.scss +++ b/src/components/ChoiceGroup/ChoiceGroup.scss @@ -4,7 +4,7 @@ // // -------------------------------------------------- -// Choice fields (radio buttons and choiceFieldes) styles +// ChoiceField styles $ms-choiceField-field-size: 20px; $ms-choiceField-transition-duration: 200ms; @@ -75,8 +75,8 @@ $ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); top: 8px; @include left(8px); bottom: 0; - right: 0; - transition-property: top, left, width, height; + @include right(0); + transition-property: top, left, right, width, height; transition-duration: $ms-choiceField-transition-duration-inner; transition-timing-function: $ms-choiceField-transition-timing; box-sizing: border-box; @@ -103,12 +103,14 @@ $ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); &::before { border-color: $ms-color-neutralSecondaryAlt; } + .ms-Label { color: $ms-color-black; } } + &:focus { - &::before { + &::before { border-color: $ms-color-neutralSecondaryAlt; } @@ -124,6 +126,7 @@ $ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); &::before { border-color: $ms-color-neutralSecondaryAlt; } + .ms-Label { color: $ms-color-black; } @@ -255,7 +258,7 @@ $ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); &.is-hidden { position: absolute; - left: 0; + @include left(0); top: 0; width: 100%; height: 100%; @@ -278,7 +281,7 @@ $ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); .ms-ChoiceField-icon { display: none; position: absolute; - left: 0; + @include left(0); line-height: $ms-font-size-s; @include ms-fontSize-l; @@ -308,5 +311,3 @@ $ms-choiceField-transition-timing: cubic-bezier(.4, 0, .23, 1); .is-focusVisible .ms-ChoiceField.is-inFocus { border: 1px solid $ms-color-neutralPrimary; } - - diff --git a/src/components/ChoiceGroup/ChoiceGroup.tsx b/src/components/ChoiceGroup/ChoiceGroup.tsx index bfb20adb2f041..84a2cdf8f5b56 100644 --- a/src/components/ChoiceGroup/ChoiceGroup.tsx +++ b/src/components/ChoiceGroup/ChoiceGroup.tsx @@ -54,8 +54,10 @@ export class ChoiceGroup extends React.Component { - inputElement.removeEventListener('focus', this._onFocus.bind(this)); - inputElement.removeEventListener('blur', this._onBlur.bind(this)); + if (inputElement) { + inputElement.removeEventListener('focus', this._onFocus.bind(this)); + inputElement.removeEventListener('blur', this._onBlur.bind(this)); + } }); } @@ -91,11 +93,9 @@ export class ChoiceGroup extends React.Component