DEV: Allow registering a widget shim which renders using hbs (#20177)
This is an alternative way to use `RenderGlimmer` which can be more ergonomic for iterative updates of a codebase. For documentation, see `widgets/render-glimmer.js`
This commit is contained in:
parent
2f8ad17aed
commit
95999c80ce
|
@ -2,6 +2,7 @@ import templateOnly from "@ember/component/template-only";
|
|||
import { setComponentTemplate } from "@ember/component";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import { assert } from "@ember/debug";
|
||||
import { createWidgetFrom } from "discourse/widgets/widget";
|
||||
|
||||
/*
|
||||
|
||||
|
@ -89,7 +90,9 @@ export default class RenderGlimmer {
|
|||
template.name === "factory"
|
||||
);
|
||||
this.renderInto = renderInto;
|
||||
this.widget = widget;
|
||||
if (widget) {
|
||||
this.widget = widget;
|
||||
}
|
||||
this.template = template;
|
||||
this.data = data;
|
||||
}
|
||||
|
@ -108,7 +111,9 @@ export default class RenderGlimmer {
|
|||
|
||||
destroy() {
|
||||
if (this._componentInfo) {
|
||||
this.widget._findView().unmountChildComponent(this._componentInfo);
|
||||
this.parentMountWidgetComponent.unmountChildComponent(
|
||||
this._componentInfo
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,7 +137,7 @@ export default class RenderGlimmer {
|
|||
}
|
||||
|
||||
connectComponent() {
|
||||
const { element, template, widget } = this;
|
||||
const { element, template } = this;
|
||||
|
||||
const component = templateOnly();
|
||||
component.name = "Widgets/RenderGlimmer";
|
||||
|
@ -143,9 +148,39 @@ export default class RenderGlimmer {
|
|||
component,
|
||||
@tracked data: this.data,
|
||||
};
|
||||
const parentMountWidgetComponent = widget._findView();
|
||||
parentMountWidgetComponent.mountChildComponent(this._componentInfo);
|
||||
|
||||
this.parentMountWidgetComponent.mountChildComponent(this._componentInfo);
|
||||
}
|
||||
|
||||
get parentMountWidgetComponent() {
|
||||
return this.widget?._findView() || this._emberView;
|
||||
}
|
||||
}
|
||||
|
||||
RenderGlimmer.prototype.type = "Widget";
|
||||
|
||||
/**
|
||||
* Define a widget shim which renders a Glimmer template. Designed for incrementally migrating
|
||||
* a widget-based UI to Glimmer. Widget attrs will be made available to your template at `@data`.
|
||||
* For more details, see documentation for the RenderGlimmer class.
|
||||
* @param name - the widget's name (which can then be used in `.attach` elsewhere)
|
||||
* @param tagName - a string describing a new wrapper element (e.g. `div.my-class`)
|
||||
* @param template - a glimmer template compiled via ember-cli-htmlbars
|
||||
*/
|
||||
export function registerWidgetShim(name, tagName, template) {
|
||||
const RenderGlimmerShim = class MyClass extends RenderGlimmer {
|
||||
constructor(attrs) {
|
||||
super(null, tagName, template, attrs);
|
||||
return this;
|
||||
}
|
||||
|
||||
get widget() {
|
||||
return this.parentWidget;
|
||||
}
|
||||
|
||||
didRenderWidget() {}
|
||||
willRerenderWidget() {}
|
||||
};
|
||||
|
||||
createWidgetFrom(RenderGlimmerShim, name, {});
|
||||
}
|
||||
|
|
|
@ -30,6 +30,10 @@ export function queryRegistry(name) {
|
|||
return _registry[name];
|
||||
}
|
||||
|
||||
export function deleteFromRegistry(name) {
|
||||
return delete _registry[name];
|
||||
}
|
||||
|
||||
const _decorators = {};
|
||||
|
||||
export function decorateWidget(widgetName, cb) {
|
||||
|
|
|
@ -4,9 +4,11 @@ import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
|||
import { click, fillIn, render } from "@ember/test-helpers";
|
||||
import { hbs } from "ember-cli-htmlbars";
|
||||
import widgetHbs from "discourse/widgets/hbs-compiler";
|
||||
import Widget from "discourse/widgets/widget";
|
||||
import Widget, { deleteFromRegistry } from "discourse/widgets/widget";
|
||||
import ClassicComponent from "@ember/component";
|
||||
import RenderGlimmer from "discourse/widgets/render-glimmer";
|
||||
import RenderGlimmer, {
|
||||
registerWidgetShim,
|
||||
} from "discourse/widgets/render-glimmer";
|
||||
import { bind } from "discourse-common/utils/decorators";
|
||||
|
||||
class DemoWidget extends Widget {
|
||||
|
@ -126,12 +128,18 @@ module("Integration | Component | Widget | render-glimmer", function (hooks) {
|
|||
this.registry.register("widget:demo-widget", DemoWidget);
|
||||
this.registry.register("widget:toggle-demo-widget", ToggleDemoWidget);
|
||||
this.registry.register("component:demo-component", DemoComponent);
|
||||
registerWidgetShim(
|
||||
"render-glimmer-test-shim",
|
||||
"div.my-wrapper",
|
||||
hbs`<span class='shim-content'>{{@data.attr1}}</span>`
|
||||
);
|
||||
});
|
||||
|
||||
hooks.afterEach(function () {
|
||||
this.registry.unregister("widget:demo-widget");
|
||||
this.registry.unregister("widget:toggle-demo-widget");
|
||||
this.registry.unregister("component:demo-component");
|
||||
deleteFromRegistry("render-glimmer-test-shim");
|
||||
});
|
||||
|
||||
test("argument handling", async function (assert) {
|
||||
|
@ -310,4 +318,13 @@ module("Integration | Component | Widget | render-glimmer", function (hooks) {
|
|||
await click(".toggleButton");
|
||||
assert.strictEqual(query("div.glimmer-wrapper").innerText, "One");
|
||||
});
|
||||
|
||||
test("registerWidgetShim can register a fake widget", async function (assert) {
|
||||
await render(
|
||||
hbs`<MountWidget @widget="render-glimmer-test-shim" @args={{hash attr1="val1"}} />`
|
||||
);
|
||||
|
||||
assert.dom("div.my-wrapper span.shim-content").exists();
|
||||
assert.dom("div.my-wrapper span.shim-content").hasText("val1");
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue