DEV: Support passing component class to RenderGlimmer (#28660)

In particular, this allows us to use gjs `<template>` for RenderGlimmer, registerWidgetShim, and decorateCooked's `helper.renderGlimmer`.

```js
// Simple component class:
registerWidgetShim(
  "render-glimmer-test-component-shim",
  "div.initial-wrapper-class",
  SimpleComponent
);
```

```gjs
// Or an inline `<template>`
registerWidgetShim(
  "render-glimmer-test-component-shim",
  "div.initial-wrapper-class",
  <template>Hello world</template>
);
```
This commit is contained in:
David Taylor 2024-09-02 11:21:46 +01:00 committed by GitHub
parent a31dc0a84a
commit cef1dcfc7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 6 deletions

View File

@ -1,3 +1,4 @@
import { hasInternalComponentManager } from "@glimmer/manager";
import { tracked } from "@glimmer/tracking";
import { setComponentTemplate } from "@ember/component";
import templateOnly from "@ember/component/template-only";
@ -94,8 +95,8 @@ export default class RenderGlimmer {
*/
constructor(widget, renderInto, template, data) {
assert(
"`template` should be a template compiled via `ember-cli-htmlbars`",
template.name === "factory"
"`template` should be a template compiled via `ember-cli-htmlbars`, or a component",
template.name === "factory" || hasInternalComponentManager(template)
);
this.renderInto = renderInto;
if (widget) {
@ -148,9 +149,14 @@ export default class RenderGlimmer {
connectComponent() {
const { element, template } = this;
const component = templateOnly();
component.name = "Widgets/RenderGlimmer";
setComponentTemplate(template, component);
let component;
if (hasInternalComponentManager(template)) {
component = template;
} else {
component = templateOnly();
component.name = "Widgets/RenderGlimmer";
setComponentTemplate(template, component);
}
this._componentInfo = new ComponentInfo({
element,

View File

@ -1,4 +1,5 @@
import ClassicComponent from "@ember/component";
import ClassicComponent, { setComponentTemplate } from "@ember/component";
import templateOnly from "@ember/component/template-only";
import { click, fillIn, render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit";
@ -123,6 +124,9 @@ class ToggleDemoWidget extends Widget {
}
}
const SimpleComponent = templateOnly();
setComponentTemplate(hbs`<div class="component-shim"></div>`, SimpleComponent);
module("Integration | Component | Widget | render-glimmer", function (hooks) {
setupRenderingTest(hooks);
@ -142,6 +146,11 @@ module("Integration | Component | Widget | render-glimmer", function (hooks) {
"div.initial-wrapper-class",
hbs`{{@setWrapperElementAttrs class=(concat-class "static-extra-class" @data.extraClass) data-some-attr=@data.dataAttrValue}}`
);
registerWidgetShim(
"render-glimmer-test-component-shim",
"div.initial-wrapper-class",
SimpleComponent
);
});
hooks.afterEach(function () {
@ -150,6 +159,7 @@ module("Integration | Component | Widget | render-glimmer", function (hooks) {
this.registry.unregister("component:demo-component");
deleteFromRegistry("render-glimmer-test-shim");
deleteFromRegistry("render-glimmer-test-wrapper-attrs");
deleteFromRegistry("render-glimmer-test-component-shim");
});
test("argument handling", async function (assert) {
@ -230,6 +240,14 @@ module("Integration | Component | Widget | render-glimmer", function (hooks) {
);
});
test("rendering component directly", async function (assert) {
await render(hbs`
<MountWidget @widget="render-glimmer-test-component-shim" />
`);
assert.dom("div.component-shim").exists();
});
test("trigger widget actions from component", async function (assert) {
assert.false(
DemoWidget.actionTriggered,