Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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": "BaseButton sometimes has aria-labelledBy pointing to element that isn't in the DOM",
"type": "patch"
}
],
"packageName": "office-ui-fabric-react",
"email": "rpsenski@microsoft.com"
}
Original file line number Diff line number Diff line change
Expand Up @@ -311,14 +311,12 @@ export class BaseButton extends BaseComponent<IBaseButtonProps, IBaseButtonState

private _onRenderTextContents = (): JSX.Element | (JSX.Element | null)[] => {
const {
text,
children,
secondaryText = this.props.description,
onRenderText = this._onRenderText,
onRenderDescription = this._onRenderDescription
} = this.props;

if (text || typeof (children) === 'string' || secondaryText) {
if (this._hasText() || secondaryText) {

@rpsenski rpsenski May 24, 2018

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.

Wanted to point out that the refactor actually made this a stricter check. Before, if text was null and typeof (children) === 'string' evaluated to true, the if was true. Now, text must be undefined for typeof (children) check to make the if truthy. I think this was the original intention because falling back to string children for text is supposed to be for backward compatibility and assumes text property is not present, but it's still a change that I want scrutinized by reviewers. #Resolved

@jspurlin jspurlin May 24, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for bring this up. While I agree that this seems safe, let's not change the logic because it may have a ripple effect for some consumers. Feel free to log a bug and list it in a comment inside of _hasText so that it can be addressed later

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.

Reverted to reduce risk


In reply to: 190656224 [](ancestors = 190656224)

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.

reverted in Iteration 5


In reply to: 190709346 [](ancestors = 190709346)

return (
<div
className={ this._classNames.textContainer }
Expand Down Expand Up @@ -347,7 +345,7 @@ export class BaseButton extends BaseComponent<IBaseButtonProps, IBaseButtonState
text = children;
}

if (text) {
if (this._hasText()) {
return (
<div
key={ this._labelId }
Expand All @@ -362,6 +360,10 @@ export class BaseButton extends BaseComponent<IBaseButtonProps, IBaseButtonState
return null;
}

private _hasText(): boolean {
return this.props.text !== null && (this.props.text !== undefined || typeof (this.props.children) === 'string');
}

private _onRenderChildren = (): JSX.Element | null => {
const { children } = this.props;

Expand Down Expand Up @@ -427,6 +429,13 @@ export class BaseButton extends BaseComponent<IBaseButtonProps, IBaseButtonState
private _onRenderMenu = (menuProps: IContextualMenuProps): JSX.Element => {
const { onDismiss = this._dismissMenu } = menuProps;

// the accessible menu label (accessible name) has a relationship to the button.
// If the menu props do not specify an explicit value for aria-label or aria-labelledBy,
// AND the button has text, we'll set the menu aria-labelledBy to the text element id.
if (!menuProps.ariaLabel && !menuProps.labelElementId && this._hasText()) {
menuProps = { ...menuProps, labelElementId: this._labelId };
}

return (
<ContextualMenu
id={ this._labelId + '-menu' }
Expand All @@ -435,7 +444,6 @@ export class BaseButton extends BaseComponent<IBaseButtonProps, IBaseButtonState
shouldFocusOnContainer={ this.state.menuProps ? this.state.menuProps.shouldFocusOnContainer : undefined }
className={ css('ms-BaseButton-menuhost', menuProps.className) }
target={ this._isSplitButton ? this._splitButtonContainer.current : this._buttonElement.current }
labelElementId={ this._labelId }
onDismiss={ onDismiss }
/>
);
Expand Down