feat: modernize addon, add optional Ember mixin props to decorator, testing helper
REVIEWER NOTE: Not nearly as big as it seems. The yarn.lock file consists of 8,041 additions and 5,810 deletions.
Description
This PR does two major things:
-
Modernizes the addon; i.e. updates Ember to 3.18 and nearly all dependencies, enables Octane support, and drops support for Ember <3.13 (BREAKING CHANGE)
-
Adds an option to provide mixin props to the decorator/higher-order function
This allows an addon user to, say, define their own
tagNamefor component wrapper nodes, which is very helpful for wrapping a simple React<button/>component with aspan(rather than the defaultdiv). For this case, the need to compose complicated CSS around such components is mitigated, which ensures that simple components rendered as expected. -
Adds a global hooks testing helper, which restores expected behaviour of https://github.com/emberjs/ember-test-helpers when changing React component form field values.
For more on this issue, see:
- https://github.com/facebook/react/issues/11488#issuecomment-347775628
- https://github.com/emberjs/ember-test-helpers/pull/1185
Other changes
- Fixes and refactors the horribly busted tests.
- Added a test for React hooks.
- Replaces
testdoublewithsinondue to some issues related toember-auto-importthat I couldn't resolve. (I'm aware of your involvement with thetestdoublecommunity, so tried to avoid this, but wasn't able to.) - Removes
ember-metricdue to some odd recursion errors. (Again, I fought this for a while, but was unsuccessful in finding a way around it.) - Tidied up various configs and updated some JS/Ember syntax.
Background
I had originally planned to migrate the addon to use Glimmer components (resolving #41), but it turns out that is infeasible due to (1) Glimmer's drastically simplified API and (2) a combination of limitations within the React DOM API and the nature of the DOM itself. The next best thing was to provide the means for modifying aspects of the wrapper node.
I found some small issues in live testing, and fixed them, so I think this is now ready for review
In live testing, we found another issue related to the Ember internals MutableCell class, which is now resolved
Thank you for this! I'll do some experimentation and let you know if I find any issues.
Hi @shamrt. I am testing react-ember-component locally and have some questions need your help.
- I tested data/action down works as expect. But if I want trigger action up, like call ember function from react child component, is that be supported as well?
- May I know is this library can never support Glimmer for some reasons?
Hope to hearing from you and thanks ahead.
@shamrt For whatever reason, production builds (i.e. those where Terser did things) don't work quite right when mapping over an array
I'm on Ember 3.28 with ember-auto-import 2.4.2 and ember-cli-terser 4.0.2.
The ember template that invokes an annotated React component (other ember stuff omitted):
{{#if this.someArrayFromEmber}}
<MyReactComponent @json={{this.someArrayFromEmber}} />
{{/if}}
The annotated React component:
import React from 'react';
import WithEmberSupport from '@rewardops-forks/ember-react-components';
// eslint-disable-next-line no-unused-vars
import PreviewDetails from '../react/preview-details';
@WithEmberSupport
export default class MyReactComponent extends React.Component {
render() {
const { json } = this.props;
return (
<PreviewDetails entities={json} />
);
}
}
And <PreviewDetails /> is a normal react component:
import React from 'react';
import PropTypes from 'prop-types';
const PreviewDetails = ({ entities }) => {
function pickComponent(e) {
if (!e) return <p>No active entity</p>;
if (e.entityType === 'VIEW') {
return <OtherReactFunctionalComponent
key={e.id}
view={e}
/>;
}
return `Not Yet Supported: "${e.entityType}"`;
}
console.error(Array.isArray(entities)); // true in dev build, false in prod build!
return (
<div className={`preview-details-container`}>
{ entities.map((e) => pickComponent(e)) } // dies here in prod build, since "entities" transpiles into an object with a "value" property that is the "entities" when running a dev build
</div>
);
};
PreviewDetails.propTypes = {
entities: PropTypes.array,
};
PreviewDetails.defaultProps = {
entities: [],
};
export default PreviewDetails;