diff --git a/package.json b/package.json index f3ede45..bfba4dd 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,7 @@ }, { "path": "./packages/melody-streams/lib/index.js", - "maxSize": "1.53 kB" + "maxSize": "1.59 kB" } ], "husky": { diff --git a/packages/melody-streams/__tests__/__snapshots__/attachEventWithElementSpec.js.snap b/packages/melody-streams/__tests__/__snapshots__/attachEventWithElementSpec.js.snap new file mode 100644 index 0000000..cf33932 --- /dev/null +++ b/packages/melody-streams/__tests__/__snapshots__/attachEventWithElementSpec.js.snap @@ -0,0 +1,5 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`attachEventWithElement should attach a click handler 1`] = `"[{\\"type\\":\\"click\\"},{\\"type\\":\\"click\\"},{\\"type\\":\\"click\\"}]"`; + +exports[`attachEventWithElement should attach multiple handlers 1`] = `"[{\\"type\\":\\"click\\"},{\\"type\\":\\"click\\"},{\\"type\\":\\"click\\"},{\\"type\\":\\"mouseenter\\"},{\\"type\\":\\"mouseenter\\"},{\\"type\\":\\"mouseenter\\"}]"`; diff --git a/packages/melody-streams/__tests__/attachEventWithElementSpec.js b/packages/melody-streams/__tests__/attachEventWithElementSpec.js new file mode 100644 index 0000000..abff38e --- /dev/null +++ b/packages/melody-streams/__tests__/attachEventWithElementSpec.js @@ -0,0 +1,55 @@ +/** + * Copyright 2019 trivago N.V. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS-IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { attachEventWithElement } from '../src'; +import { applyGradualyAndComplete } from './util/testHelpers'; +import { createMouseEvent } from './util/mouseEvent'; + +const dispatchClick = createMouseEvent('click'); +const dispatchMouseEnter = createMouseEvent('mouseenter'); + +describe('attachEventWithElement', () => { + it('should attach a click handler', async () => { + const el = document.createElement('div'); + const [refHandler, subj, originEl] = attachEventWithElement('click'); + refHandler(el); + applyGradualyAndComplete(subj, dispatchClick(el), [ + undefined, + undefined, + undefined, + ]).then(handlers => { + expect(JSON.stringify(handlers)).toMatchSnapshot(); + expect(el).toBe(originEl.value); + }); + }); + + it('should attach multiple handlers', async () => { + const el = document.createElement('div'); + const [refHandler, subj, originEl] = attachEventWithElement( + 'click', + 'mouseenter' + ); + refHandler(el); + applyGradualyAndComplete( + subj, + [dispatchClick(el), dispatchMouseEnter(el)], + [undefined, undefined, undefined] + ).then(handlers => { + expect(JSON.stringify(handlers)).toMatchSnapshot(); + expect(el).toBe(originEl.value); + }); + }); +}); diff --git a/packages/melody-streams/src/index.js b/packages/melody-streams/src/index.js index d1030ab..724df6b 100644 --- a/packages/melody-streams/src/index.js +++ b/packages/melody-streams/src/index.js @@ -18,6 +18,7 @@ export { createComponent } from './component'; export { render } from './render'; export { createState } from './operators/createState'; export { attachEvent } from './operators/attachEvent'; +export { attachEventWithElement } from './operators/attachEventWithElement'; export { withElement } from './operators/withElement'; export { combine } from './operators/combine'; export { combineRefs } from './operators/combineRefs'; diff --git a/packages/melody-streams/src/operators/attachEventWithElement.js b/packages/melody-streams/src/operators/attachEventWithElement.js new file mode 100644 index 0000000..30b1ad3 --- /dev/null +++ b/packages/melody-streams/src/operators/attachEventWithElement.js @@ -0,0 +1,32 @@ +/** + * Copyright 2019 trivago N.V. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS-IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { attachEvent } from './attachEvent'; +import { withElement } from './withElement'; +import { combineRefs } from './combineRefs'; +import { of } from 'rxjs'; + +export const attachEventWithElement = (...events) => { + const eventsAndElement = [ + attachEvent(...events), + withElement(el => of(el), null), + ]; + const refHandler = combineRefs( + ...eventsAndElement.map(([handler]) => handler) + ); + const streams = eventsAndElement.map(([_, stream]) => stream); + return [refHandler, ...streams]; +};