Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "office-ui-fabric-react",
"comment": "add onRenderDescription to TextField",
"type": "minor"
}
],
"packageName": "office-ui-fabric-react",
"email": "chrismo@microsoft.com"
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ export class TextField extends BaseComponent<ITextFieldProps, ITextFieldState> i
onRenderAddon = this._onRenderAddon, // @deprecated
onRenderPrefix = this._onRenderPrefix,
onRenderSuffix = this._onRenderSuffix,
onRenderLabel = this._onRenderLabel
onRenderLabel = this._onRenderLabel,
onRenderDescription = this._onRenderDescription
} = this.props;
const { isFocused } = this.state;
const errorMessage = this._errorMessage;
Expand Down Expand Up @@ -192,7 +193,7 @@ export class TextField extends BaseComponent<ITextFieldProps, ITextFieldState> i
</div>
{ this._isDescriptionAvailable &&
<span id={ this._descriptionId }>
{ description && <span className={ css('ms-TextField-description', styles.description) }>{ description }</span> }
{ onRenderDescription(this.props, this._onRenderDescription) }
{ errorMessage &&
<div aria-live='assertive'>
<DelayedRender>
Expand Down Expand Up @@ -304,6 +305,14 @@ export class TextField extends BaseComponent<ITextFieldProps, ITextFieldState> i
return null;
}

private _onRenderDescription = (props: ITextFieldProps): JSX.Element | null => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null [](start = 73, length = 4)

undefined

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manishgarg1 I've updated both _onRenderDescription and _onRenderLabel.

A bit different than you suggested though. Rather than replacing null with undefined, I was able to remove null from the return type by moving the guard into the render method.
(I wasn't sure for the motivation behind your suggestion, so please let me know if I missed the point.)

The reason I did it this way was because changing null to undefined on the return type resulted in the following error at the onRenderLabel invokation, which I don't yet understand.

[ts] Cannot invoke an expression whose type lacks a call signature. Type 'IRenderFunction<ITextFieldProps> | ((props: ITextFieldProps) => Element | undefined)' has no compatible call signatures.
const onRenderLabel: IRenderFunction<ITextFieldProps> | ((props: ITextFieldProps) => JSX.Element | undefined)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manishgarg1 On further consideration, I don't think what I did will work for us. We'd want the provided onRenderDescription to be invoked even when description is absent. I've reverted this last change.

If you still think null should be changed to undefined, can you please help me understand the motivation? And suggest a course of action given the error that I encountered above?

const { description } = props;
if (description) {
return (<span className={ css('ms-TextField-description', styles.description) }>{ description }</span>);
}
return null;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following code will do the same

return description && <span....>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slight challenge here was that we'd have to add string to the return type, because of falsey empty strings.

}

// @deprecated
private _onRenderAddon(props: ITextFieldProps): JSX.Element {
const { addonString } = props;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ export interface ITextFieldProps extends React.AllHTMLAttributes<HTMLInputElemen
*/
description?: string;

/**
* Optional custom renderer for the description
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

description [](start = 38, length = 11)

nit: . at the end of the sentence.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

*/
onRenderDescription?: IRenderFunction<ITextFieldProps>;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onRenderDescription [](start = 2, length = 19)

Please add this along with the rest of the onRender APIs below

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added periods to the descriptions of all onRender.... functions


/**
* @deprecated
* Deprecated; use prefix instead.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { TextFieldStatus } from './TextField.checklist';
import { TextFieldSuffixExample } from './examples/TextField.Suffix.Example';
import { TextFieldUnderlinedExample } from './examples/TextField.Underlined.Example';
import { TextFieldAutoCompleteExample } from './examples/TextField.AutoComplete.Example';
import { TextFieldOnRenderDescriptionExample } from './examples/TextField.OnRenderDescription.Example';

const TextFieldBasicExampleCode = require('!raw-loader!office-ui-fabric-react/src/components/TextField/examples/TextField.Basic.Example.tsx') as string;
const TextFieldBorderlessExampleCode = require('!raw-loader!office-ui-fabric-react/src/components/TextField/examples/TextField.Borderless.Example.tsx') as string;
Expand All @@ -32,6 +33,7 @@ const TextFieldPrefixAndSuffixExampleCode = require('!raw-loader!office-ui-fabri
const TextFieldSuffixExampleCode = require('!raw-loader!office-ui-fabric-react/src/components/TextField/examples/TextField.Suffix.Example.tsx') as string;
const TextFieldUnderlinedExampleCode = require('!raw-loader!office-ui-fabric-react/src/components/TextField/examples/TextField.Underlined.Example.tsx') as string;
const TextFieldAutoCompleteExampleCode = require('!raw-loader!office-ui-fabric-react/src/components/TextField/examples/TextField.AutoComplete.Example.tsx') as string;
const TextFieldOnRenderDescriptionExampleCode = require('!raw-loader!office-ui-fabric-react/src/components/TextField/examples/TextField.OnRenderDescription.Example.tsx') as string;

export class TextFieldPage extends React.Component<IComponentDemoPageProps, {}> {
public render() {
Expand Down Expand Up @@ -111,6 +113,12 @@ export class TextFieldPage extends React.Component<IComponentDemoPageProps, {}>
>
<TextFieldCustomRenderExample />
</ExampleCard>
<ExampleCard
title='TextField with custom description'
code={ TextFieldOnRenderDescriptionExampleCode }
>
<TextFieldOnRenderDescriptionExample />
</ExampleCard>
<ExampleCard
title='TextField error message variations'
code={ TextFieldErrorMessageExampleCode }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as React from 'react';
import { TextField, ITextFieldProps } from 'office-ui-fabric-react/lib/TextField';
import './TextField.Examples.scss';

export class TextFieldOnRenderDescriptionExample extends React.Component<{}, {}> {
public render() {
return (
<div className='docs-TextFieldExample'>
<TextField
description={ 'A custom description that appends a link.' }
onRenderDescription={ this._onRenderDescription }
/>
</div>
);
}

private _onRenderDescription = (props: ITextFieldProps): JSX.Element => {
return (
<div>
{ props.description }{ ' ' }
<a href='#' onClick={ this._onLinkClick } >Link</a>
</div>);
}

private _onLinkClick = (e: React.MouseEvent<HTMLElement>) => {
e.preventDefault();
}
}