Skip to content

Commit 3408a1e

Browse files
Deprecate Input assistiveText.fieldLevelHelpButton
* 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.
1 parent 1913d8f commit 3408a1e

File tree

9 files changed

+111
-81
lines changed

9 files changed

+111
-81
lines changed

components/combobox/__examples__/base-inline-help-tooltip.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ class Example extends React.Component {
139139
align="top left"
140140
content="Type to search Salesforce objects..."
141141
id="field-level-help-tooltip"
142-
position="overflowBoundaryElement"
143142
/>
144143
}
145144
labels={{

components/combobox/combobox.jsx

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,14 @@ import classNames from 'classnames';
2020

2121
import shortid from 'shortid';
2222

23-
import Button from '../button';
2423
import Dialog from '../utilities/dialog';
2524
import InnerInput from '../../components/input/private/inner-input';
2625
import InputIcon from '../icon/input-icon';
2726
import Menu from './private/menu';
2827
import Label from '../forms/private/label';
2928
import SelectedListBox from '../pill-container/private/selected-listbox';
30-
import Tooltip from '../tooltip';
3129

30+
import FieldLevelHelpTooltip from '../tooltip/private/field-level-help-tooltip';
3231
import KEYS from '../../utilities/key-code';
3332
import KeyBuffer from '../../utilities/key-buffer';
3433
import keyLetterMenuItemSelect from '../../utilities/key-letter-menu-item-select';
@@ -1379,33 +1378,6 @@ class Combobox extends React.Component {
13791378
);
13801379
};
13811380

1382-
renderFieldLevelHelpTooltip(fieldLevelHelpTooltip, labels, assistiveText) {
1383-
if (
1384-
(labels.label || (assistiveText && assistiveText.label)) &&
1385-
this.props.fieldLevelHelpTooltip
1386-
) {
1387-
const defaultTooltipProps = {
1388-
triggerClassName: 'slds-form-element__icon',
1389-
children: (
1390-
<Button
1391-
assistiveText={{ label: 'Help' }}
1392-
className="slds-m-bottom_xxx-small"
1393-
iconCategory="utility"
1394-
iconName="info"
1395-
variant="icon"
1396-
/>
1397-
),
1398-
};
1399-
const tooltipProps = {
1400-
...defaultTooltipProps,
1401-
...this.props.fieldLevelHelpTooltip.props,
1402-
};
1403-
return <Tooltip {...tooltipProps} />;
1404-
}
1405-
1406-
return null;
1407-
}
1408-
14091381
render() {
14101382
const props = this.props;
14111383
// Merge objects of strings with their default object
@@ -1415,11 +1387,8 @@ class Combobox extends React.Component {
14151387
props.assistiveText
14161388
);
14171389
const labels = assign({}, defaultProps.labels, this.props.labels);
1418-
const fieldLevelHelpTooltip = this.renderFieldLevelHelpTooltip(
1419-
this.props.fieldLevelHelpTooltip,
1420-
labels,
1421-
this.props.assistiveText
1422-
);
1390+
const hasRenderedLabel =
1391+
labels.label || (assistiveText && assistiveText.label);
14231392
const subRenderParameters = { assistiveText, labels, props: this.props };
14241393
const multipleOrSingle = this.props.multiple ? 'multiple' : 'single';
14251394
const subRenders = {
@@ -1448,7 +1417,11 @@ class Combobox extends React.Component {
14481417
label={labels.label}
14491418
required={props.required}
14501419
/>
1451-
{fieldLevelHelpTooltip}
1420+
{this.props.fieldLevelHelpTooltip && hasRenderedLabel ? (
1421+
<FieldLevelHelpTooltip
1422+
fieldLevelHelpTooltip={this.props.fieldLevelHelpTooltip}
1423+
/>
1424+
) : null}
14521425
{variantExists
14531426
? subRenders[this.props.variant][multipleOrSingle](
14541427
subRenderParameters

components/input/__examples__/field-level-help.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ class Example extends React.Component {
1818
</h1>
1919
<Input
2020
id="field-level-help"
21-
assistiveText={{ fieldLevelHelpButton: 'Info' }}
2221
label="My Label"
2322
fieldLevelHelpTooltip={
2423
<Tooltip

components/input/check-props.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ if (process.env.NODE_ENV !== 'production') {
2121
const iconDeprecatedMessage = `Please use \`iconLeft\` and \`iconRight\` to pass in a customized <Icon> component. ${createDocUrl()}`;
2222

2323
// Deprecated and changed to another property
24+
deprecatedProperty(
25+
COMPONENT,
26+
props.assistiveText.fieldLevelHelpButton,
27+
'assistiveText.fieldLevelHelpButton',
28+
undefined,
29+
`Please pass a \`Tooltip\` component into \`fieldLevelHelpTooltip\` with \`assistiveText.triggerLearnMoreIcon\`.`
30+
);
2431
deprecatedProperty(
2532
COMPONENT,
2633
props.iconCategory,

components/input/index.jsx

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import classNames from 'classnames';
2525
import shortid from 'shortid';
2626

2727
import Button from '../button';
28-
import Tooltip from '../tooltip';
2928

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

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

4141
const COUNTER = 'counter';
4242
const DECREMENT = 'Decrement';
@@ -45,7 +45,6 @@ const INCREMENT = 'Increment';
4545
const defaultProps = {
4646
assistiveText: {
4747
decrement: `${DECREMENT} ${COUNTER}`,
48-
fieldLevelHelpButton: 'Help',
4948
increment: `${INCREMENT} ${COUNTER}`,
5049
},
5150
type: 'text',
@@ -104,12 +103,10 @@ class Input extends React.Component {
104103
* **Assistive text for accessibility**
105104
* * `label`: Visually hidden label but read out loud by screen readers.
106105
* * `spinner`: Text for loading spinner icon.
107-
* * `fieldLevelHelpButton`: The field level help button, by default an 'info' icon.
108106
*/
109107
assistiveText: PropTypes.shape({
110108
label: PropTypes.string,
111109
spinner: PropTypes.string,
112-
fieldLevelHelpButton: PropTypes.string,
113110
}),
114111
/**
115112
* Elements are added after the `input`.
@@ -141,7 +138,7 @@ class Input extends React.Component {
141138
*/
142139
errorText: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
143140
/**
144-
* 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.
141+
* A [Tooltip](https://react.lightningdesignsystem.com/components/tooltips/) component that is displayed next to the label.
145142
*/
146143
fieldLevelHelpTooltip: PropTypes.node,
147144
/**
@@ -539,33 +536,11 @@ class Input extends React.Component {
539536
};
540537
const inputRef =
541538
this.props.variant === COUNTER ? this.setInputRef : this.props.inputRef;
542-
let fieldLevelHelpTooltip;
543539
let iconLeft = null;
544540
let iconRight = null;
545541

546-
if (
547-
(this.props.label ||
548-
(this.props.assistiveText && this.props.assistiveText.label)) &&
549-
this.props.fieldLevelHelpTooltip
550-
) {
551-
const defaultTooltipProps = {
552-
triggerClassName: 'slds-form-element__icon',
553-
triggerStyle: { position: 'static' },
554-
children: (
555-
<Button
556-
assistiveText={{ icon: assistiveText.fieldLevelHelpButton }}
557-
iconCategory="utility"
558-
iconName="info"
559-
variant="icon"
560-
/>
561-
),
562-
};
563-
const tooltipProps = {
564-
...defaultTooltipProps,
565-
...this.props.fieldLevelHelpTooltip.props,
566-
};
567-
fieldLevelHelpTooltip = <Tooltip {...tooltipProps} />;
568-
}
542+
const hasRenderedLabel =
543+
this.props.label || (assistiveText && assistiveText.label);
569544

570545
// Remove at next breaking change
571546
// this is a hack to make left the default prop unless overwritten by `iconPosition="right"`
@@ -608,13 +583,20 @@ class Input extends React.Component {
608583
)}
609584
>
610585
<Label
611-
assistiveText={this.props.assistiveText}
586+
assistiveText={assistiveText}
612587
htmlFor={this.props.isStatic ? undefined : this.getId()}
613588
label={this.props.label}
614589
required={this.props.required}
615590
variant={this.props.isStatic ? 'static' : 'base'}
616591
/>
617-
{fieldLevelHelpTooltip}
592+
{this.props.fieldLevelHelpTooltip && hasRenderedLabel ? (
593+
<FieldLevelHelpTooltip
594+
assistiveText={{
595+
triggerLearnMoreIcon: assistiveText.fieldLevelHelpButton,
596+
}}
597+
fieldLevelHelpTooltip={this.props.fieldLevelHelpTooltip}
598+
/>
599+
) : null}
618600
<InnerInput
619601
aria-activedescendant={this.props['aria-activedescendant']}
620602
aria-autocomplete={this.props['aria-autocomplete']}

components/tooltip/index.jsx

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -182,16 +182,15 @@ class Tooltip extends React.Component {
182182
];
183183
} else if (noChildrenProvided) {
184184
children = [
185-
<Button variant="icon" aria-disabled>
186-
<Icon
187-
category="utility"
188-
name="info"
189-
assistiveText={{
190-
label: this.props.assistiveText.triggerLearnMoreIcon,
191-
}}
192-
size="x-small"
193-
/>
194-
</Button>,
185+
<Button
186+
aria-disabled
187+
assistiveText={{
188+
icon: this.props.assistiveText.triggerLearnMoreIcon,
189+
}}
190+
iconCategory="utility"
191+
iconName="info"
192+
variant="icon"
193+
/>,
195194
];
196195
} else {
197196
children = this.props.children;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Field Level Help Tooltip for input labels
3+
*/
4+
import React from 'react';
5+
import PropTypes from 'prop-types';
6+
import assign from 'lodash.assign';
7+
8+
import Tooltip from '../index';
9+
10+
const propTypes = {
11+
/*
12+
* Assistive Text object from parent component such as Input, Combobox, etc.
13+
*/
14+
assistiveText: PropTypes.shape({
15+
triggerLearnMoreIcon: PropTypes.string,
16+
}),
17+
/*
18+
* Tooltip from external prop
19+
*/
20+
fieldLevelHelpTooltip: PropTypes.node.isRequired,
21+
};
22+
23+
const defaultProps = {
24+
triggerClassName: 'slds-form-element__icon',
25+
// This allows `position: absolute` Tooltips to align properly.
26+
// If not present, tooltip will always be below the info icon // instead of above it.
27+
triggerStyle: { position: 'static' },
28+
variant: 'learnMore',
29+
};
30+
31+
const FieldLevelHelpTooltip = ({
32+
fieldLevelHelpTooltip,
33+
assistiveText = {},
34+
}) => {
35+
// `assistiveTextInternal` is needed, because `Input` used to
36+
// have an `assistiveText.fieldLevelHelpButton` prop and that
37+
// prop needs to override the default Tooltip "Help" string.
38+
const assistiveTextInternal = assign(
39+
{},
40+
fieldLevelHelpTooltip.props.assistiveText,
41+
assistiveText
42+
);
43+
44+
return fieldLevelHelpTooltip ? (
45+
<Tooltip
46+
{...{
47+
// internal default props
48+
...defaultProps,
49+
// props from external developer
50+
...fieldLevelHelpTooltip.props,
51+
// allow backwards compatibility with Input's
52+
// assistiveText.fieldLevelHelpButton
53+
assistiveText: assistiveTextInternal,
54+
}}
55+
/>
56+
) : null;
57+
};
58+
59+
FieldLevelHelpTooltip.propTypes = propTypes;
60+
FieldLevelHelpTooltip.displayName = 'FieldLevelHelpTooltip';
61+
62+
export default FieldLevelHelpTooltip;

tests/__snapshots__/story-based-tests.snapshot-test.js.snap

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6112,12 +6112,14 @@ exports[`DOM snapshots SLDSCombobox Base Inline Help 1`] = `
61126112
style={
61136113
Object {
61146114
"display": "inline-block",
6115+
"position": "static",
61156116
}
61166117
}
61176118
>
61186119
<button
61196120
aria-describedby="field-level-help-tooltip"
6120-
className="slds-button slds-button_icon slds-m-bottom_xxx-small"
6121+
aria-disabled={true}
6122+
className="slds-button slds-button_icon"
61216123
disabled={false}
61226124
onBlur={[Function]}
61236125
onClick={[Function]}
@@ -6134,6 +6136,11 @@ exports[`DOM snapshots SLDSCombobox Base Inline Help 1`] = `
61346136
xlinkHref="/assets/icons/utility-sprite/svg/symbols.svg#info"
61356137
/>
61366138
</svg>
6139+
<span
6140+
className="slds-assistive-text"
6141+
>
6142+
Help
6143+
</span>
61376144
</button>
61386145
<span />
61396146
</div>
@@ -19974,6 +19981,7 @@ exports[`DOM snapshots SLDSInput Field Level Help 1`] = `
1997419981
>
1997519982
<button
1997619983
aria-describedby="field-level-help-tooltip"
19984+
aria-disabled={true}
1997719985
className="slds-button slds-button_icon"
1997819986
disabled={false}
1997919987
onBlur={[Function]}
@@ -19994,7 +20002,7 @@ exports[`DOM snapshots SLDSInput Field Level Help 1`] = `
1999420002
<span
1999520003
className="slds-assistive-text"
1999620004
>
19997-
Info
20005+
Test
1999820006
</span>
1999920007
</button>
2000020008
<span />
@@ -20044,6 +20052,7 @@ exports[`DOM snapshots SLDSInput Field Level Help, Tooltip Open 1`] = `
2004420052
>
2004520053
<button
2004620054
aria-describedby="field-level-help-tooltip"
20055+
aria-disabled={true}
2004720056
className="slds-button slds-button_icon"
2004820057
disabled={false}
2004920058
onBlur={[Function]}
@@ -20064,7 +20073,7 @@ exports[`DOM snapshots SLDSInput Field Level Help, Tooltip Open 1`] = `
2006420073
<span
2006520074
className="slds-assistive-text"
2006620075
>
20067-
Info
20076+
Test
2006820077
</span>
2006920078
</button>
2007020079
<div

0 commit comments

Comments
 (0)