Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions common/changes/textfield-flexbox_2017-04-21-21-33.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "office-ui-fabric-react",
"comment": "TextField: Convert to flexbox, support addons",
"type": "minor"
}
],
"email": "micahgodbolt@gmail.com"
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { IRenderFunction } from '../../Utilities';

export interface ITextField {
/** Gets the current value of the input. */
Expand Down Expand Up @@ -61,6 +62,16 @@ export interface ITextFieldProps extends React.HTMLProps<HTMLInputElement | HTML
*/
description?: string;

/**
* String for addon.
*/
addonString?: string;

/**
* Custom render function for addon
*/
onRenderAddon?: IRenderFunction<ITextFieldProps>;

/**
* CSS class for the icon.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,32 +70,24 @@
top: auto;
}

.field {
.fieldGroup {
@include ms-u-normalize;
@include ms-baseFont;
border: 1px solid $ms-color-neutralTertiaryAlt;
border-radius: 0;
font-weight: $ms-font-weight-regular;
font-size: $ms-font-size-m;
color: $ms-color-neutralPrimary;
border: 1px solid $ms-color-neutralTertiaryAlt;
height: 32px;
@include padding(0, 12px, 1px, 12px);
width: 100%;
outline: 0;
text-overflow: ellipsis;

&.hasIcon {
@include padding-right(24px);
}

display: flex;
flex-direction: row;
align-items: stretch;
position: relative;
&:hover {
border-color: $ms-color-neutralSecondaryAlt;
}

&:focus {
border-color: $ms-color-themePrimary;
}

&:hover,
&:focus {
@media screen and (-ms-high-contrast: active) {
Expand All @@ -106,13 +98,42 @@
border-color: $ms-color-contrastWhiteSelected;
}
}

&[disabled] {
.rootIsDisabled > & {
background-color: $ms-color-neutralLighter;
border-color: $ms-color-neutralLighter;
pointer-events: none;
cursor: default;
}
}

.fieldAddon {
background: $ms-color-neutralLighter;
color: $ms-color-neutralSecondary;
display: flex;
align-items: center;
padding: 0 10px;
line-height: 1;
}

.field {
border-radius: 0;
border: none;
color: $ms-color-neutralPrimary;
@include padding(0, 12px, 0, 12px);
width: 100%;
outline: 0;
text-overflow: ellipsis;

&.hasIcon {
@include padding-right(24px);
}

&[disabled] {
background-color: transparent;
border-color: transparent;
pointer-events: none;
cursor: default;
}

@include input-placeholder {
color: $ms-color-neutralSecondary;
Expand All @@ -133,7 +154,7 @@
//
.root.rootIsUnderlined {
border-bottom: 1px solid $ms-color-neutralTertiaryAlt;
display: table;
display: flex;
width: 100%;

&:hover {
Expand All @@ -156,23 +177,15 @@
:global(.ms-Label) {
font-size: $ms-font-size-m;
@include margin-right(8px);
display: table-cell;
vertical-align: top;
@include padding-left(12px);
padding-top: 9px;
line-height: 22px; // 32px minus 5px padding top/bottom
height: 32px;
width: 1%;
white-space: nowrap;
}

.field {
.fieldGroup {
flex: 1 1 0;
border: 0;
@include float(left);
display: table-cell;
@include text-align(left);
padding-top: 8px;
padding-bottom: 3px;

&:active,
&:focus,
&:hover {
Expand Down Expand Up @@ -209,20 +222,26 @@

//== Modifier: Multiline textfield
//
.root.rootIsMultiline .field {
@include ms-baseFont;
color: $ms-color-neutralPrimary;
font-family: $ms-font-family-base;
font-size: $ms-font-size-m;
font-weight: $ms-font-weight-regular;
line-height: 17px;
min-height: 60px;
height: auto;
padding-top: 6px;
overflow: auto;

&.hasIcon {
@include padding-right(40px);
.root.rootIsMultiline {
.fieldGroup {
min-height: 60px;
height: auto;
display: flex;
}
.field {
@include ms-baseFont;
color: $ms-color-neutralPrimary;
font-family: $ms-font-family-base;
font-size: $ms-font-size-m;
font-weight: $ms-font-weight-regular;
line-height: 17px;
flex-grow: 1;
padding-top: 6px;
overflow: auto;
width: 100%;
&.hasIcon {
@include padding-right(40px);
}
}
}

Expand Down Expand Up @@ -255,7 +274,9 @@
.root.rootIsMultiline {

.icon {
@include right(24px);
@include padding-right(24px);
padding-bottom: 8px;
align-items: flex-end;
}

.field.fieldIsUnresizable {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import { ITextField, ITextFieldProps } from './TextField.Props';
import { Label } from '../../Label';
import { Icon } from '../../Icon';
import {
DelayedRender,
BaseComponent,
Expand Down Expand Up @@ -127,7 +128,9 @@ export class TextField extends BaseComponent<ITextFieldProps, ITextFieldState> i
label,
multiline,
required,
underlined
underlined,
addonString,
onRenderAddon = this._onRenderAddon
} = this.props;
let { isFocused } = this.state;
const errorMessage: string = this._errorMessage;
Expand All @@ -144,8 +147,15 @@ export class TextField extends BaseComponent<ITextFieldProps, ITextFieldState> i
return (
<div className={ textFieldClassName }>
{ label && <Label htmlFor={ this._id }>{ label }</Label> }
{ iconClass && <i className={ css(iconClass, styles.icon) }></i> }
{ multiline ? this._renderTextArea() : this._renderInput() }
<div className={ css(styles.fieldGroup) }>
{ (addonString !== undefined || this.props.onRenderAddon) && (
<div className={ css(styles.fieldAddon) }>
{ onRenderAddon(this.props, this._onRenderAddon) }
</div>
) }
{ multiline ? this._renderTextArea() : this._renderInput() }
{ iconClass && <i className={ css(iconClass, styles.icon) }></i> }
</div>
{ this._isDescriptionAvailable &&
<span id={ this._descriptionId }>
{ description && <span className={ css('ms-TextField-description', styles.description) }>{ description }</span> }
Expand Down Expand Up @@ -225,6 +235,13 @@ export class TextField extends BaseComponent<ITextFieldProps, ITextFieldState> i
}
}

private _onRenderAddon(props: ITextFieldProps): JSX.Element {
let { addonString } = props;
return (
<span style={ { paddingBottom: '1px' } }>{ addonString }</span>
);
}

private _getTextElementClassName(): string {
const errorMessage: string = this._errorMessage;
let textFieldClassName: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import * as React from 'react';
import { TextField } from 'office-ui-fabric-react/lib/TextField';
import { Icon } from 'office-ui-fabric-react/lib/Icon';
import { autobind } from 'office-ui-fabric-react/lib/Utilities';

export class TextFieldBasicExample extends React.Component<any, any> {
public render() {
return (
<div>
<TextField label='Default TextField' onChanged={ this._onChanged } />
<TextField
addonString='https://'
label='Default TextField' onChanged={ this._onChanged } />
<TextField label='Disabled TextField' disabled={ true } />
<TextField label='Required TextField' required={ true } />
<TextField label='TextField with a placeholder' placeholder='Now I am a Placeholder' ariaLabel='Please enter text here' />
Expand Down