Skip to content

Commit 6ae06cf

Browse files
committed
Clickable input icons now use SLDSButton
1 parent 68b2b00 commit 6ae06cf

File tree

2 files changed

+111
-34
lines changed

2 files changed

+111
-34
lines changed

components/forms/input/index.jsx

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ import InputIcon from '../../icon/input-icon';
2828
// This component's `checkProps` which issues warnings to developers about properties when in development mode (similar to React's built in development tools)
2929
import checkProps from './check-props';
3030

31+
// ### isFunction
32+
import isFunction from 'lodash.isfunction';
33+
34+
import Button from '../../button';
35+
3136
// Remove the need for `React.PropTypes`
3237
const { PropTypes } = React;
3338

@@ -161,6 +166,24 @@ const Input = React.createClass({
161166
};
162167
},
163168

169+
getIconRender (position) {
170+
if (position !== this.props.iconPosition) return '';
171+
172+
return isFunction(this.props.onIconClick)
173+
? (<Button
174+
iconVariant="small"
175+
variant="base"
176+
className="slds-input__icon slds-button--icon"
177+
iconName={this.props.iconName}
178+
iconCategory={this.props.iconCategory}
179+
onClick={this.props.onIconClick}
180+
/>)
181+
: (<InputIcon
182+
name={this.props.iconName}
183+
category={this.props.iconCategory}
184+
/>);
185+
},
186+
164187
// ### Render
165188
render () {
166189
const {
@@ -176,7 +199,6 @@ const Input = React.createClass({
176199
id,
177200
label,
178201
onChange,
179-
onIconClick,
180202
placeholder,
181203
readOnly,
182204
required,
@@ -222,11 +244,8 @@ const Input = React.createClass({
222244
'slds-has-divider--bottom': readOnly
223245
})}
224246
>
225-
{hasIcon && iconPosition === 'left' && <InputIcon
226-
name={iconName}
227-
category={iconCategory}
228-
onClick={onIconClick}
229-
/>}
247+
{hasIcon && this.getIconRender('left')}
248+
230249
{!readOnly && <input
231250
{...props}
232251
aria-controls={ariaControls}
@@ -240,11 +259,9 @@ const Input = React.createClass({
240259
type={type}
241260
value={value}
242261
/>}
243-
{hasIcon && iconPosition === 'right' && <InputIcon
244-
name={iconName}
245-
category={iconCategory}
246-
onClick={onIconClick}
247-
/>}
262+
263+
{hasIcon && this.getIconRender('right')}
264+
248265
{readOnly && <span className="slds-form-element__static">
249266
{value}
250267
</span>}

tests/input/input.test.jsx

Lines changed: 83 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import TestUtils from 'react-addons-test-utils';
66

77
import { SLDSInput } from '../../components';
88
const {
9-
// Simulate,
9+
Simulate,
1010
findRenderedDOMComponentWithTag,
1111
scryRenderedDOMComponentsWithTag,
1212
findRenderedDOMComponentWithClass
@@ -146,27 +146,87 @@ describe('SLDS INPUT **************************************************', () =>
146146
});
147147
});
148148

149+
describe('Input with Left Clickable Icon', () => {
150+
let component;
151+
let elementControl;
152+
let leftButton;
153+
154+
const clickCallback = sinon.spy();
155+
156+
beforeEach(() => {
157+
component = getInput({ iconName: 'search', iconCategory: 'utility', iconPosition: 'left', onIconClick: clickCallback });
158+
leftButton = findRenderedDOMComponentWithTag(component, 'button');
159+
elementControl = findRenderedDOMComponentWithClass(component, 'slds-form-element__control');
160+
});
161+
162+
afterEach(() => {
163+
removeInput();
164+
});
165+
166+
it('element control has class "slds-input-has-icon"', () => {
167+
expect(elementControl.className).to.include('slds-input-has-icon');
168+
});
169+
170+
it('icon renders button BEFORE input in DOM', () => {
171+
const render = elementControl.innerHTML;
172+
expect(render.indexOf('<button')).to.be.below(render.indexOf('<input'));
173+
});
174+
175+
it('icon can be clicked', () => {
176+
TestUtils.Simulate.click(leftButton);
177+
178+
expect(clickCallback.calledOnce).to.be.true;
179+
});
180+
});
181+
182+
describe('Input with Right Clickable Icon', () => {
183+
let component;
184+
let elementControl;
185+
let leftButton;
186+
187+
const clickCallback = sinon.spy();
188+
189+
beforeEach(() => {
190+
component = getInput({ iconName: 'search', iconCategory: 'utility', iconPosition: 'right', onIconClick: clickCallback });
191+
leftButton = findRenderedDOMComponentWithTag(component, 'button');
192+
elementControl = findRenderedDOMComponentWithClass(component, 'slds-form-element__control');
193+
});
149194

150-
// describe('Input with Clickable Icon', () => {
151-
// let component;
152-
// let input;
153-
// let label;
154-
// let icon;
155-
156-
// beforeEach(() => {
157-
// component = getInput({ label: 'Input Label' });
158-
// input = findRenderedDOMComponentWithTag(component, 'input');
159-
// inputWrapper = findRenderedDOMComponentWithClass(component, 'slds-form-element__control');
160-
// label = findRenderedDOMComponentWithClass(component, 'slds-form-element__label');
161-
// icon = findRenderedDOMComponentWithTag(component, 'svg');
162-
// });
163-
164-
// afterEach(() => {
165-
// removeInput();
166-
// });
167-
168-
// // input wrapper has class "slds-input-has-icon"
169-
// // icon has class "slds-input__icon"
170-
// // icon can be clicked (Simulate)
171-
// });
195+
afterEach(() => {
196+
removeInput();
197+
});
198+
199+
it('element control has class "slds-input-has-icon"', () => {
200+
expect(elementControl.className).to.include('slds-input-has-icon');
201+
});
202+
203+
it('icon renders button AFTER input in DOM', () => {
204+
const render = elementControl.innerHTML;
205+
expect(render.indexOf('<button')).to.be.above(render.indexOf('<input'));
206+
});
207+
208+
it('icon can be clicked', () => {
209+
TestUtils.Simulate.click(leftButton);
210+
211+
expect(clickCallback.calledOnce).to.be.true;
212+
});
213+
});
214+
215+
describe('Input with Non-Clickable Icon', () => {
216+
let component;
217+
let elementControl;
218+
219+
beforeEach(() => {
220+
component = getInput({ iconName: 'search', iconCategory: 'utility', iconPosition: 'right' });
221+
elementControl = findRenderedDOMComponentWithClass(component, 'slds-form-element__control');
222+
});
223+
224+
afterEach(() => {
225+
removeInput();
226+
});
227+
228+
it('button tag does not exist', () => {
229+
expect(elementControl.getElementsByTagName('button')[0]).to.not.be.ok;
230+
});
231+
});
172232
});

0 commit comments

Comments
 (0)