From 5a520dc318c953251f89516e3be64fe8dcf64476 Mon Sep 17 00:00:00 2001 From: Bryce Osterhaus Date: Fri, 26 May 2017 09:08:26 -0700 Subject: [PATCH] Export utility for passing props for higher order components --- packages/metal-jsx/src/JSXComponent.js | 3 +- packages/metal-jsx/src/otherProps.js | 24 ++++++++++++ packages/metal-jsx/test/otherProps.js | 54 ++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 packages/metal-jsx/src/otherProps.js create mode 100644 packages/metal-jsx/test/otherProps.js diff --git a/packages/metal-jsx/src/JSXComponent.js b/packages/metal-jsx/src/JSXComponent.js index 4ca862b8..71343bd5 100644 --- a/packages/metal-jsx/src/JSXComponent.js +++ b/packages/metal-jsx/src/JSXComponent.js @@ -7,6 +7,7 @@ import DangerouslySetHTML from './DangerouslySetHTML'; import IncrementalDomRenderer from 'metal-incremental-dom'; import JSXDataManager from './JSXDataManager'; import JSXRenderer from './JSXRenderer'; +import otherProps from './otherProps'; /** * A component that has built-in integration with JSX templates. Example: @@ -39,4 +40,4 @@ JSXComponent.DATA_MANAGER = JSXDataManager; JSXComponent.RENDERER = JSXRenderer; export default JSXComponent; -export { DangerouslySetHTML, validators, Config, JSXComponent }; +export { DangerouslySetHTML, validators, Config, JSXComponent, otherProps }; diff --git a/packages/metal-jsx/src/otherProps.js b/packages/metal-jsx/src/otherProps.js new file mode 100644 index 00000000..740c408e --- /dev/null +++ b/packages/metal-jsx/src/otherProps.js @@ -0,0 +1,24 @@ +'use strict'; + +import { object } from 'metal'; + +/** + * Returns props that are not used or declared in the component. + * @param {Component} component Instance of metal-jsx component + * @return {Object} Object containing props + */ +export default function otherProps(component) { + const removeKeys = [...component.getDataManager().getPropsInstance(component).getStateKeys(), 'key', 'ref']; + + const retObj = object.mixin({}, component.props); + + for (let i = 0; i < removeKeys.length; i++) { + const key = removeKeys[i]; + + if (retObj.hasOwnProperty(key)) { + delete retObj[key]; + } + } + + return retObj; +} diff --git a/packages/metal-jsx/test/otherProps.js b/packages/metal-jsx/test/otherProps.js new file mode 100644 index 00000000..be0299d6 --- /dev/null +++ b/packages/metal-jsx/test/otherProps.js @@ -0,0 +1,54 @@ +'use strict'; + +import JSXComponent from '../src/JSXComponent'; +import otherProps from '../src/otherProps'; + +describe('otherProps', function() { + var component; + + afterEach(function() { + if (component) { + component.dispose(); + } + }); + + it('should return object', function() { + class TestComponent extends JSXComponent { + render() { + return
; + } + } + + assert.deepEqual(otherProps(new TestComponent()), {}); + }); + + it('should pass through unspecified props', function() { + class TestComponent extends JSXComponent { + render() { + return
; + } + } + + TestComponent.PROPS = { + foo: {}, + }; + + assert.deepEqual( + otherProps(new TestComponent({baz: 'qux', foo: 'bar'})), + {baz: 'qux'} + ); + }); + + it('should ignore key and ref', function() { + class TestComponent extends JSXComponent { + render() { + return
; + } + } + + assert.deepEqual( + otherProps(new TestComponent({key: 'bar', ref: 'qux'})), + {} + ); + }); +});