Skip to content
This repository has been archived by the owner on Aug 21, 2023. It is now read-only.

Commit

Permalink
Merge 574ad72 into 6118786
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon Quach committed Mar 8, 2019
2 parents 6118786 + 574ad72 commit 034a96e
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 39 deletions.
58 changes: 39 additions & 19 deletions src/components/Input/Input.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,44 +51,47 @@ type Props = {
autoFocus: boolean,
className: string,
disabled: boolean,
forceAutoFocusTimeout: number,
errorMessage?: string,
errorIcon?: string,
errorMessage?: string,
forceAutoFocusTimeout: number,
helpText: any,
hintText: any,
id: string,
inlinePrefix?: string,
inlineSuffix?: string,
inputRef: (ref: HTMLElement) => void,
innerRef: (ref: HTMLElement) => void,
isFocused: boolean,
inputRef: (ref: HTMLElement) => void,
isFirst: boolean,
isNotOnly: boolean,
isFocused: boolean,
isLast: boolean,
isNotOnly: boolean,
isSubtleReadOnly: boolean,
label: any,
maxHeight: number | string,
modalhelpText: string,
moveCursorToEnd: boolean,
multiline: boolean | number,
maxHeight: number | string,
name: string,
offsetAmount: number,
onBlur: (event: AnyInputEvent) => void,
onChange: (value: InputValue) => void,
onEnterDown: (event: AnyInputEvent) => void,
onEnterUp: (event: AnyInputEvent) => void,
onFocus: (event: AnyInputEvent) => void,
onKeyDown: (event: AnyInputEvent) => void,
onKeyUp: (event: AnyInputEvent) => void,
onResize: (height: number) => void,
onWheel: (event: AnyInputEvent) => void,
onStartTyping: (now?: number) => void,
onStopTyping: () => void,
onWheel: (event: AnyInputEvent) => void,
placeholder: string,
prefix: any,
readOnly: boolean,
refApplyCallStopTyping: (fn: () => void) => void,
removeStateStylesOnFocus: boolean,
resizable: boolean,
seamless: boolean,
scrollLock: boolean,
seamless: boolean,
size: UISize,
state?: ?UIState,
style: Object,
Expand Down Expand Up @@ -116,21 +119,24 @@ export class Input extends Component<Props, State> {
disabled: false,
errorIcon: 'alert',
forceAutoFocusTimeout: 0,
inputRef: noop,
innerRef: noop,
hasInsertCarriageReturns: false,
isFocused: false,
innerRef: noop,
inputRef: noop,
isFirst: false,
isNotOnly: false,
isFocused: false,
isLast: false,
isNotOnly: false,
isSubtleReadOnly: false,
moveCursorToEnd: false,
multiline: null,
offsetAmount: 0,
onBlur: noop,
onChange: noop,
onEnterDown: noop,
onEnterUp: noop,
onFocus: noop,
onKeyDown: noop,
onKeyUp: noop,
onResize: noop,
onStartTyping: noop,
onStopTyping: noop,
Expand Down Expand Up @@ -386,6 +392,10 @@ export class Input extends Component<Props, State> {
handleOnKeyDown = (event: Event) => {
const { hasInsertCarriageReturns } = this.props

if (event.keyCode === Keys.ENTER) {
this.props.onEnterDown(event)
}

if (hasInsertCarriageReturns && event.keyCode === Keys.ENTER) {
this.insertCarriageReturnAtCursorIndex(event)
}
Expand All @@ -394,6 +404,13 @@ export class Input extends Component<Props, State> {
this.scrollToBottom()
}

handleOnKeyUp = (event: Event) => {
if (event.keyCode === Keys.ENTER) {
this.props.onEnterUp(event)
}
this.props.onKeyUp(event)
}

handleExpandingResize = (height: number) => {
this.props.onResize(height)
this.setState({ height })
Expand Down Expand Up @@ -597,10 +614,10 @@ export class Input extends Component<Props, State> {
helpText,
hintText,
inputRef,
isFocused,
isFirst,
isNotOnly,
isFocused,
isLast,
isNotOnly,
isSubtleReadOnly,
label,
maxHeight,
Expand All @@ -609,20 +626,22 @@ export class Input extends Component<Props, State> {
name,
offsetAmount,
onBlur,
onEnterDown,
onEnterUp,
onFocus,
onResize,
onScroll,
onStartTyping,
onStopTyping,
onWheel,
onScroll,
placeholder,
prefix,
readOnly,
refApplyCallStopTyping,
removeStateStylesOnFocus,
resizable,
seamless,
scrollLock,
seamless,
size,
state: stateProp,
style: styleProp,
Expand Down Expand Up @@ -667,14 +686,15 @@ export class Input extends Component<Props, State> {
/* We manually set autoFocus after component mounts. */
autoFocus: this.state.isFocused,
className: fieldClassName,
disabled,
id,
onChange: this.handleOnChange,
onKeyDown: this.handleOnKeyDown,
innerRef: this.setInputNodeRef,
disabled,
name,
onBlur: this.handleOnInputBlur,
onChange: this.handleOnChange,
onFocus: this.handleOnInputFocus,
onKeyDown: this.handleOnKeyDown,
onKeyUp: this.handleOnKeyUp,
onWheel: this.handleOnWheel,
placeholder,
readOnly,
Expand Down
140 changes: 140 additions & 0 deletions src/components/Input/__tests__/Input.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -969,3 +969,143 @@ describe('Action', () => {
expect(wrapper.find('button.cancel').length).toBeTruthy()
})
})

describe('onEnterDown', () => {
test('Fires onEnterDown when key enter is pressed (down)', () => {
const spy = jest.fn()
const wrapper = mount(<Input onEnterDown={spy} />)
const el = wrapper.find('input')

el.simulate('keydown', {
keyCode: 13,
})

expect(spy).toHaveBeenCalled()
})

test('Fires onEnterDown when key enter + shift is pressed (down)', () => {
const spy = jest.fn()
const wrapper = mount(<Input onEnterDown={spy} />)
const el = wrapper.find('input')

el.simulate('keydown', {
keyCode: 13,
shiftKey: true,
})

expect(spy).toHaveBeenCalled()
})

test('Fires onEnterDown when key enter + shift is pressed (down)', () => {
const spy = jest.fn()
const wrapper = mount(<Input onEnterDown={spy} />)
const el = wrapper.find('input')

el.simulate('keydown', {
keyCode: 13,
ctrlKey: true,
})

expect(spy).toHaveBeenCalled()
})

test('onKeyDown still fires when Enter key is pressed', () => {
const enterSpy = jest.fn()
const keyDownSpy = jest.fn()
const wrapper = mount(
<Input onEnterDown={enterSpy} onKeyDown={keyDownSpy} />
)
const el = wrapper.find('input')

el.simulate('keydown', {
keyCode: 13,
})

expect(enterSpy).toHaveBeenCalled()
expect(keyDownSpy).toHaveBeenCalled()
})

test('onKeyDown does not fire when a non-Enter key is pressed (down)', () => {
const enterSpy = jest.fn()
const keyDownSpy = jest.fn()
const wrapper = mount(
<Input onEnterDown={enterSpy} onKeyDown={keyDownSpy} />
)
const el = wrapper.find('input')

el.simulate('keydown', {
keyCode: 40,
})

expect(enterSpy).not.toHaveBeenCalled()
expect(keyDownSpy).toHaveBeenCalled()
})
})

describe('onEnterUp', () => {
test('Fires onEnterUp when key enter is pressed (up)', () => {
const spy = jest.fn()
const wrapper = mount(<Input onEnterUp={spy} />)
const el = wrapper.find('input')

el.simulate('keyup', {
keyCode: 13,
})

expect(spy).toHaveBeenCalled()
})

test('Fires onEnterUp when key enter + shift is pressed (up)', () => {
const spy = jest.fn()
const wrapper = mount(<Input onEnterUp={spy} />)
const el = wrapper.find('input')

el.simulate('keyup', {
keyCode: 13,
shiftKey: true,
})

expect(spy).toHaveBeenCalled()
})

test('Fires onEnterUp when key enter + shift is pressed (up)', () => {
const spy = jest.fn()
const wrapper = mount(<Input onEnterUp={spy} />)
const el = wrapper.find('input')

el.simulate('keyup', {
keyCode: 13,
ctrlKey: true,
})

expect(spy).toHaveBeenCalled()
})

test('onKeyUp still fires when Enter key is pressed', () => {
const enterSpy = jest.fn()
const keyUpSpy = jest.fn()
const wrapper = mount(<Input onEnterUp={enterSpy} onKeyUp={keyUpSpy} />)
const el = wrapper.find('input')

el.simulate('keyup', {
keyCode: 13,
})

expect(enterSpy).toHaveBeenCalled()
expect(keyUpSpy).toHaveBeenCalled()
})

test('onKeyUp does not fire when a non-Enter key is pressed (up)', () => {
const enterSpy = jest.fn()
const keyUpSpy = jest.fn()
const wrapper = mount(<Input onEnterUp={enterSpy} onKeyUp={keyUpSpy} />)
const el = wrapper.find('input')

el.simulate('keyup', {
keyCode: 40,
})

expect(enterSpy).not.toHaveBeenCalled()
expect(keyUpSpy).toHaveBeenCalled()
})
})
40 changes: 21 additions & 19 deletions src/components/Input/docs/Input.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,51 +53,53 @@ Note: Be sure the version for `Button` is at least version 2.
| Prop | Type | Description |
| ------------------------ | -------------------------- | -------------------------------------------------------------------------- |
| action | `React.Component` | Embedded actions for the Input. |
| autoFocus | `bool` | Automatically focuses the input. |
| autoFocus | `boolean` | Automatically focuses the input. |
| className | `string` | Custom class names to be added to the component. |
| disabled | `bool` | Disable the input. |
| disabled | `boolean` | Disable the input. |
| errorIcon | `string` | Icon that renders when the state is `error`. |
| errorMessage | `string` | Error message that renders into a Tooltip. |
| forceAutoFocusTimeout | `bool` | Determines the amount of time (`ms`) for the component to focus on mount. |
| hasCarriageReturns | `bool` | If `true` and `enter + special` key is pressed, a return will be inserted |
| forceAutoFocusTimeout | `boolean` | Determines the amount of time (`ms`) for the component to focus on mount. |
| hasCarriageReturns | `boolean` | If `true` and `enter + special` key is pressed, a return will be inserted |
| helpText | `string`/`React.Component` | Displays text underneath input. |
| hintText | `string`/`React.Component` | Displays text above input. |
| id | `string` | ID for the input. |
| inlinePrefix | `string` | Text to appear before the input. |
| inlineSuffix | `string` | Text to after before the input. |
| innerRef | `function` | Retrieves the `input` DOM node. |
| innerRef | `Function` | Retrieves the `input` DOM node. |
| isFirst | `boolean` | Helps render component without right borders. |
| isFocused | `string` | Determines if the component is focused. |
| isLast | `boolean` | Helps render component without left borders. |
| isNotOnly | `boolean` | Helps render component without left/right borders. |
| label | `string`/`React.Component` | Label for the input. |
| maxHeight | `number`/`string` | Sets the `max-height` for the input. Used with `multiline`. |
| moveCursorToEnd | `boolean` | Moves the selection cursor to the end, on focus. Default `false`. |
| multiline | `bool`/`number` | Transforms input into an auto-expanding textarea. |
| multiline | `boolean`/`number` | Transforms input into an auto-expanding textarea. |
| name | `string` | Name for the input. |
| offsetAmount | `number` | Number of characters to offset (bottom-right) for multiline resizing. |
| onBlur | `function` | Callback when input is blurred. |
| onChange | `function` | Callback when input value is changed. |
| onFocus | `function` | Callback when input is focused. |
| onResize | `function` | Callback when input is resized. |
| onStartTyping | `function` | Callback when user starts typing, rate limited by `typingThrottleInterval` |
| onStopTyping | `function` | Callback when user stops typing after delay of `typingTimeoutDelay`. |
| onBlur | `Function` | Callback when input is blurred. |
| onChange | `Function` | Callback when input value is changed. |
| onEnterDown | `Function` | Callback when `Enter` is pressed down. |
| onEnterUp | `Function` | Callback when `Enter` is pressed up. |
| onFocus | `Function` | Callback when input is focused. |
| onResize | `Function` | Callback when input is resized. |
| onStartTyping | `Function` | Callback when user starts typing, rate limited by `typingThrottleInterval` |
| onStopTyping | `Function` | Callback when user stops typing after delay of `typingTimeoutDelay`. |
| placeholder | `string` | Placeholder text for the input. |
| prefix | `any` | Component to render before the input. |
| readOnly | `bool` | Disable editing of the input. |
| refApplyCallStopTyping | `function` | Exposes `CallStopTyping`, so that it can be called outside itself. |
| removeStateStylesOnFocus | `bool` | Removes the `state` styles on input focus. Default `false`. |
| resizable | `bool` | Enables resizing for the textarea (only enabled for `multiline`). |
| scrollLock | `bool` | Enables scrollLock for component. Default `false`. |
| seamless | `bool` | Removes the border around the input. |
| readOnly | `boolean` | Disable editing of the input. |
| refApplyCallStopTyping | `Function` | Exposes `CallStopTyping`, so that it can be called outside itself. |
| removeStateStylesOnFocus | `boolean` | Removes the `state` styles on input focus. Default `false`. |
| resizable | `boolean` | Enables resizing for the textarea (only enabled for `multiline`). |
| scrollLock | `boolean` | Enables scrollLock for component. Default `false`. |
| seamless | `boolean` | Removes the border around the input. |
| size | `string` | Determines the size of the input. |
| state | `string` | Change input to state color. |
| suffix | `any` | Component to render after the input. |
| type | `string` | Determines the input type. |
| typingThrottleInterval | `number` | Determines the rate limiting interval for firing `onStartTyping`. |
| typingTimeoutDelay | `number` | Determines the delay of when `onStopTyping` fires after typing stops. |
| value | `string` | Initial value of the input. |
| withTypingEvent | `bool` | Enables typing `onStartTyping` and `onStopTyping` event callbacks. |
| withTypingEvent | `boolean` | Enables typing `onStartTyping` and `onStopTyping` event callbacks. |

### States

Expand Down

0 comments on commit 034a96e

Please sign in to comment.