From 65328bd50945433a243583e713983ba41d34b2ff Mon Sep 17 00:00:00 2001 From: Tobias Date: Tue, 21 May 2019 11:22:02 +0200 Subject: [PATCH] feat: enhance components event handling. This update lets You always also define events the React way. So `on_click` is the same as `onClick`. --- .../src/components/button/Button.js | 4 ---- .../dnb-ui-lib/src/components/input/Input.js | 6 ++--- .../shared/__tests__/component-helper.test.js | 14 ++++++++++- .../dnb-ui-lib/src/shared/component-helper.js | 23 ++++++++++++++++++- .../dnb-ui-lib/stories/componentsStories.js | 17 +++++++++++++- 5 files changed, 53 insertions(+), 11 deletions(-) diff --git a/packages/dnb-ui-lib/src/components/button/Button.js b/packages/dnb-ui-lib/src/components/button/Button.js index 21beb1b38d5..30c6ad42437 100644 --- a/packages/dnb-ui-lib/src/components/button/Button.js +++ b/packages/dnb-ui-lib/src/components/button/Button.js @@ -128,10 +128,6 @@ export default class Button extends PureComponent { } } onClickHandler = event => { - // add web component event handler - if (typeof this.props.onClick === 'function') { - this.props.onClick({ event }) - } dispatchCustomElementEvent(this, 'on_click', { event }) } render() { diff --git a/packages/dnb-ui-lib/src/components/input/Input.js b/packages/dnb-ui-lib/src/components/input/Input.js index d03b24f5dca..83152739fe3 100644 --- a/packages/dnb-ui-lib/src/components/input/Input.js +++ b/packages/dnb-ui-lib/src/components/input/Input.js @@ -186,14 +186,12 @@ export default class Input extends PureComponent { dispatchCustomElementEvent(this, 'on_blur', { value, event }) } onChangeHandler = event => { - event.persist() const { value } = event.target this.setState({ value, _listenForPropChanges: false }) dispatchCustomElementEvent(this, 'on_change', { value, event }) } onKeyDownHandler = event => { if (event.key === 'Enter') { - event.persist() const { value } = event.target dispatchCustomElementEvent(this, 'on_submit', { value, event }) } @@ -258,11 +256,11 @@ export default class Input extends PureComponent { id, disabled, name: id, + ...attributes, onChange: this.onChangeHandler, onKeyDown: this.onKeyDownHandler, onFocus: this.onFocusHandler, - onBlur: this.onBlurHandler, - ...attributes + onBlur: this.onBlurHandler } // we may considder using: aria-details diff --git a/packages/dnb-ui-lib/src/shared/__tests__/component-helper.test.js b/packages/dnb-ui-lib/src/shared/__tests__/component-helper.test.js index 9065df5c33f..bb3fee8a016 100644 --- a/packages/dnb-ui-lib/src/shared/__tests__/component-helper.test.js +++ b/packages/dnb-ui-lib/src/shared/__tests__/component-helper.test.js @@ -8,6 +8,7 @@ import { validateDOMAttributes, processChildren, dispatchCustomElementEvent, + transformToReactEventCase, setCustomElementMethod, pickRenderProps } from '../component-helper' @@ -118,14 +119,17 @@ describe('"processChildren" should', () => { describe('"dispatchCustomElementEvent" should', () => { it('call a custom event function, set as a property in props', () => { const my_event = jest.fn() + const myEvent = jest.fn() const element = { props: { - my_event + my_event, + myEvent } } const event = {} dispatchCustomElementEvent(element, 'my_event', event) expect(my_event.mock.calls.length).toBe(1) + expect(myEvent.mock.calls.length).toBe(1) }) it('call a custom event function, set as a property in props', () => { const fireEvent = jest.fn() @@ -143,6 +147,14 @@ describe('"dispatchCustomElementEvent" should', () => { }) }) +describe('"transformToReactEventCase" should', () => { + it('transform a snail case event name to a React event case', () => { + expect(transformToReactEventCase('my_event_is_long')).toBe( + 'myEventIsLong' + ) + }) +}) + describe('"setCustomElementMethod" should', () => { it('call a custom event function, set as a property in props called "custom_method"', () => { const custom_method = jest.fn() diff --git a/packages/dnb-ui-lib/src/shared/component-helper.js b/packages/dnb-ui-lib/src/shared/component-helper.js index 46d9cdda635..15c2412eecd 100644 --- a/packages/dnb-ui-lib/src/shared/component-helper.js +++ b/packages/dnb-ui-lib/src/shared/component-helper.js @@ -161,10 +161,31 @@ export const dispatchCustomElementEvent = (element, eventName, event) => { } if (element && typeof element.props[eventName] === 'function') { - element.props[eventName].apply(element, [event]) // TODO: remove this because of security notation + element.props[eventName].apply(element, [event]) + } + + eventName = transformToReactEventCase(eventName) + if (element && typeof element.props[eventName] === 'function') { + element.props[eventName].apply(element, [event]) } } +// transform on_click to onClick +export const transformToReactEventCase = s => + s + .split(/_/g) + .reduce( + (acc, cur, i) => + acc + + (i === 0 + ? cur + : cur.replace( + /(\w)(\w*)/g, + (g0, g1, g2) => g1.toUpperCase() + g2.toLowerCase() + )), + '' + ) + export const setCustomElementMethod = ( element, methodName, diff --git a/packages/dnb-ui-lib/stories/componentsStories.js b/packages/dnb-ui-lib/stories/componentsStories.js index 0ce13a44a22..0d4ec5e8036 100644 --- a/packages/dnb-ui-lib/stories/componentsStories.js +++ b/packages/dnb-ui-lib/stories/componentsStories.js @@ -241,12 +241,27 @@ stories.push([ on_change={event => { console.log('on_change', event) }} + onChange={event => { + console.log('onChange', event) + }} on_submit={event => { console.log('on_submit', event) }} + onSubmit={event => { + console.log('on_submit', event) + }} value="Input ..." /> -