Skip to content

Commit

Permalink
Deprecate Input assistiveText.fieldLevelHelpButton
Browse files Browse the repository at this point in the history
* Deprecate Input’s `assistiveText.fieldLevelHelpButton` prop and add a checkProp warning to use fieldLevelHelpTooltip.
* Centralizes the default Tooltip props into it’s own module, so that code can be re-used across Combobox and Input.
* Combobox/Tooltip: Use learnMore variant and remove custom Button/children props
* Documents triggerStyle: { position: 'static' } usage and removes overflowBoundaryElement from example
* Remove default for Input’s assistiveText.fieldLevelHelpButton so that Tooltip has the default “Help” text and not the Input component. Having defaults in two locations causing problems when merging objects.
* Adds removeUndefined helper function
  • Loading branch information
interactivellama committed Jan 5, 2019
1 parent 1913d8f commit 06880c2
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ class Example extends React.Component {
align="top left"
content="Type to search Salesforce objects..."
id="field-level-help-tooltip"
position="overflowBoundaryElement"
/>
}
labels={{
Expand Down
43 changes: 8 additions & 35 deletions components/combobox/combobox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@ import classNames from 'classnames';

import shortid from 'shortid';

import Button from '../button';
import Dialog from '../utilities/dialog';
import InnerInput from '../../components/input/private/inner-input';
import InputIcon from '../icon/input-icon';
import Menu from './private/menu';
import Label from '../forms/private/label';
import SelectedListBox from '../pill-container/private/selected-listbox';
import Tooltip from '../tooltip';

import FieldLevelHelpTooltip from '../tooltip/private/field-level-help-tooltip';
import KEYS from '../../utilities/key-code';
import KeyBuffer from '../../utilities/key-buffer';
import keyLetterMenuItemSelect from '../../utilities/key-letter-menu-item-select';
Expand Down Expand Up @@ -1379,33 +1378,6 @@ class Combobox extends React.Component {
);
};

renderFieldLevelHelpTooltip(fieldLevelHelpTooltip, labels, assistiveText) {
if (
(labels.label || (assistiveText && assistiveText.label)) &&
this.props.fieldLevelHelpTooltip
) {
const defaultTooltipProps = {
triggerClassName: 'slds-form-element__icon',
children: (
<Button
assistiveText={{ label: 'Help' }}
className="slds-m-bottom_xxx-small"
iconCategory="utility"
iconName="info"
variant="icon"
/>
),
};
const tooltipProps = {
...defaultTooltipProps,
...this.props.fieldLevelHelpTooltip.props,
};
return <Tooltip {...tooltipProps} />;
}

return null;
}

render() {
const props = this.props;
// Merge objects of strings with their default object
Expand All @@ -1415,11 +1387,8 @@ class Combobox extends React.Component {
props.assistiveText
);
const labels = assign({}, defaultProps.labels, this.props.labels);
const fieldLevelHelpTooltip = this.renderFieldLevelHelpTooltip(
this.props.fieldLevelHelpTooltip,
labels,
this.props.assistiveText
);
const hasRenderedLabel =
labels.label || (assistiveText && assistiveText.label);
const subRenderParameters = { assistiveText, labels, props: this.props };
const multipleOrSingle = this.props.multiple ? 'multiple' : 'single';
const subRenders = {
Expand Down Expand Up @@ -1448,7 +1417,11 @@ class Combobox extends React.Component {
label={labels.label}
required={props.required}
/>
{fieldLevelHelpTooltip}
{this.props.fieldLevelHelpTooltip && hasRenderedLabel ? (
<FieldLevelHelpTooltip
fieldLevelHelpTooltip={this.props.fieldLevelHelpTooltip}
/>
) : null}
{variantExists
? subRenders[this.props.variant][multipleOrSingle](
subRenderParameters
Expand Down
1 change: 0 additions & 1 deletion components/input/__examples__/field-level-help.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class Example extends React.Component {
</h1>
<Input
id="field-level-help"
assistiveText={{ fieldLevelHelpButton: 'Info' }}
label="My Label"
fieldLevelHelpTooltip={
<Tooltip
Expand Down
7 changes: 7 additions & 0 deletions components/input/check-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ if (process.env.NODE_ENV !== 'production') {
const iconDeprecatedMessage = `Please use \`iconLeft\` and \`iconRight\` to pass in a customized <Icon> component. ${createDocUrl()}`;

// Deprecated and changed to another property
deprecatedProperty(
COMPONENT,
props.assistiveText.fieldLevelHelpButton,
'assistiveText.fieldLevelHelpButton',
undefined,
`Please pass a \`Tooltip\` component into \`fieldLevelHelpTooltip\` with \`assistiveText.triggerLearnMoreIcon\`.`
);
deprecatedProperty(
COMPONENT,
props.iconCategory,
Expand Down
44 changes: 13 additions & 31 deletions components/input/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import classNames from 'classnames';
import shortid from 'shortid';

import Button from '../button';
import Tooltip from '../tooltip';

// ## Children
import InputIcon from '../icon/input-icon';
Expand All @@ -37,6 +36,7 @@ import checkProps from './check-props';

import { INPUT } from '../../utilities/constants';
import componentDoc from './docs.json';
import FieldLevelHelpTooltip from '../tooltip/private/field-level-help-tooltip';

const COUNTER = 'counter';
const DECREMENT = 'Decrement';
Expand All @@ -45,7 +45,6 @@ const INCREMENT = 'Increment';
const defaultProps = {
assistiveText: {
decrement: `${DECREMENT} ${COUNTER}`,
fieldLevelHelpButton: 'Help',
increment: `${INCREMENT} ${COUNTER}`,
},
type: 'text',
Expand Down Expand Up @@ -104,12 +103,10 @@ class Input extends React.Component {
* **Assistive text for accessibility**
* * `label`: Visually hidden label but read out loud by screen readers.
* * `spinner`: Text for loading spinner icon.
* * `fieldLevelHelpButton`: The field level help button, by default an 'info' icon.
*/
assistiveText: PropTypes.shape({
label: PropTypes.string,
spinner: PropTypes.string,
fieldLevelHelpButton: PropTypes.string,
}),
/**
* Elements are added after the `input`.
Expand Down Expand Up @@ -141,7 +138,7 @@ class Input extends React.Component {
*/
errorText: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
/**
* A [Tooltip](https://react.lightningdesignsystem.com/components/tooltips/) component that is displayed next to the label. The props from the component will be merged and override any default props.
* A [Tooltip](https://react.lightningdesignsystem.com/components/tooltips/) component that is displayed next to the label.
*/
fieldLevelHelpTooltip: PropTypes.node,
/**
Expand Down Expand Up @@ -539,33 +536,11 @@ class Input extends React.Component {
};
const inputRef =
this.props.variant === COUNTER ? this.setInputRef : this.props.inputRef;
let fieldLevelHelpTooltip;
let iconLeft = null;
let iconRight = null;

if (
(this.props.label ||
(this.props.assistiveText && this.props.assistiveText.label)) &&
this.props.fieldLevelHelpTooltip
) {
const defaultTooltipProps = {
triggerClassName: 'slds-form-element__icon',
triggerStyle: { position: 'static' },
children: (
<Button
assistiveText={{ icon: assistiveText.fieldLevelHelpButton }}
iconCategory="utility"
iconName="info"
variant="icon"
/>
),
};
const tooltipProps = {
...defaultTooltipProps,
...this.props.fieldLevelHelpTooltip.props,
};
fieldLevelHelpTooltip = <Tooltip {...tooltipProps} />;
}
const hasRenderedLabel =
this.props.label || (assistiveText && assistiveText.label);

// Remove at next breaking change
// this is a hack to make left the default prop unless overwritten by `iconPosition="right"`
Expand Down Expand Up @@ -608,13 +583,20 @@ class Input extends React.Component {
)}
>
<Label
assistiveText={this.props.assistiveText}
assistiveText={assistiveText}
htmlFor={this.props.isStatic ? undefined : this.getId()}
label={this.props.label}
required={this.props.required}
variant={this.props.isStatic ? 'static' : 'base'}
/>
{fieldLevelHelpTooltip}
{this.props.fieldLevelHelpTooltip && hasRenderedLabel ? (
<FieldLevelHelpTooltip
assistiveText={{
triggerLearnMoreIcon: assistiveText.fieldLevelHelpButton,
}}
fieldLevelHelpTooltip={this.props.fieldLevelHelpTooltip}
/>
) : null}
<InnerInput
aria-activedescendant={this.props['aria-activedescendant']}
aria-autocomplete={this.props['aria-autocomplete']}
Expand Down
19 changes: 9 additions & 10 deletions components/tooltip/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,16 +182,15 @@ class Tooltip extends React.Component {
];
} else if (noChildrenProvided) {
children = [
<Button variant="icon" aria-disabled>
<Icon
category="utility"
name="info"
assistiveText={{
label: this.props.assistiveText.triggerLearnMoreIcon,
}}
size="x-small"
/>
</Button>,
<Button
aria-disabled
assistiveText={{
icon: this.props.assistiveText.triggerLearnMoreIcon,
}}
iconCategory="utility"
iconName="info"
variant="icon"
/>,
];
} else {
children = this.props.children;
Expand Down
55 changes: 55 additions & 0 deletions components/tooltip/private/field-level-help-tooltip.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Field Level Help Tooltip for input labels
*/
import React from 'react';
import PropTypes from 'prop-types';

import Tooltip from '../index';
import objectHelpers from '../../../utilities/object';

const propTypes = {
/*
* Assistive Text object from parent component such as Input, Combobox, etc.
*/
assistiveText: PropTypes.shape({
triggerLearnMoreIcon: PropTypes.string,
}),
/*
* Tooltip from external prop
*/
fieldLevelHelpTooltip: PropTypes.node.isRequired,
};

const defaultProps = {
triggerClassName: 'slds-form-element__icon',
// This allows `position: absolute` Tooltips to align properly.
// If not present, tooltip will always be below the info icon // instead of above it.
triggerStyle: { position: 'static' },
variant: 'learnMore',
};

const FieldLevelHelpTooltip = ({ fieldLevelHelpTooltip, assistiveText = {} }) =>
fieldLevelHelpTooltip ? (
<Tooltip
{...{
// internal default props
...defaultProps,
// props from external developer
...fieldLevelHelpTooltip.props,
// allow backwards compatibility with Input's
// assistiveText.fieldLevelHelpButton
// `Input` used to have an `assistiveText.fieldLevelHelpButton`
// prop and that prop needs to override the default Tooltip
// "Help" string.
assistiveText: {
...fieldLevelHelpTooltip.props.assistiveText,
...objectHelpers.removeUndefined(assistiveText),
},
}}
/>
) : null;

FieldLevelHelpTooltip.propTypes = propTypes;
FieldLevelHelpTooltip.displayName = 'FieldLevelHelpTooltip';

export default FieldLevelHelpTooltip;
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 12 additions & 3 deletions tests/__snapshots__/story-based-tests.snapshot-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6112,12 +6112,14 @@ exports[`DOM snapshots SLDSCombobox Base Inline Help 1`] = `
style={
Object {
"display": "inline-block",
"position": "static",
}
}
>
<button
aria-describedby="field-level-help-tooltip"
className="slds-button slds-button_icon slds-m-bottom_xxx-small"
aria-disabled={true}
className="slds-button slds-button_icon"
disabled={false}
onBlur={[Function]}
onClick={[Function]}
Expand All @@ -6134,6 +6136,11 @@ exports[`DOM snapshots SLDSCombobox Base Inline Help 1`] = `
xlinkHref="/assets/icons/utility-sprite/svg/symbols.svg#info"
/>
</svg>
<span
className="slds-assistive-text"
>
Help
</span>
</button>
<span />
</div>
Expand Down Expand Up @@ -19974,6 +19981,7 @@ exports[`DOM snapshots SLDSInput Field Level Help 1`] = `
>
<button
aria-describedby="field-level-help-tooltip"
aria-disabled={true}
className="slds-button slds-button_icon"
disabled={false}
onBlur={[Function]}
Expand All @@ -19994,7 +20002,7 @@ exports[`DOM snapshots SLDSInput Field Level Help 1`] = `
<span
className="slds-assistive-text"
>
Info
Help
</span>
</button>
<span />
Expand Down Expand Up @@ -20044,6 +20052,7 @@ exports[`DOM snapshots SLDSInput Field Level Help, Tooltip Open 1`] = `
>
<button
aria-describedby="field-level-help-tooltip"
aria-disabled={true}
className="slds-button slds-button_icon"
disabled={false}
onBlur={[Function]}
Expand All @@ -20064,7 +20073,7 @@ exports[`DOM snapshots SLDSInput Field Level Help, Tooltip Open 1`] = `
<span
className="slds-assistive-text"
>
Info
Help
</span>
</button>
<div
Expand Down
19 changes: 19 additions & 0 deletions utilities/object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Remove keys with undefined values. This is useful
* for merging object props like `assistiveText` and `labels`
* and keeping default prop values.
*/

const removeUndefined = (obj) => {
const newObj = {};
Object.keys(obj).forEach((prop) => {
if (typeof obj[prop] !== 'undefined') {
newObj[prop] = obj[prop];
}
});
return newObj;
};

const helpers = { removeUndefined };

export default helpers;

0 comments on commit 06880c2

Please sign in to comment.