From 9a1a3906c4dad3e09b6f0515ccedc78d7bda8bdb Mon Sep 17 00:00:00 2001 From: David Taylor Date: Mon, 10 Jul 2023 10:28:45 +0100 Subject: [PATCH] DEV: Support rendering `` as a `
` element (#22507) --- .../discourse/app/components/d-modal.hbs | 4 +-- .../discourse/app/components/d-modal.js | 17 ++++++++++++- .../integration/components/d-modal-test.js | 25 +++++++++++++++++++ .../components/sections/organisms/modal.hbs | 9 +++++++ .../components/sections/organisms/modal.js | 2 ++ 5 files changed, 54 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/discourse/app/components/d-modal.hbs b/app/assets/javascripts/discourse/app/components/d-modal.hbs index c9c2f14611a..467813988db 100644 --- a/app/assets/javascripts/discourse/app/components/d-modal.hbs +++ b/app/assets/javascripts/discourse/app/components/d-modal.hbs @@ -5,7 +5,7 @@ @element={{this.modal.containerElement}} @inline={{@inline}} > -
- + {{#unless @inline}} {{/unless}} diff --git a/app/assets/javascripts/discourse/app/components/d-modal.js b/app/assets/javascripts/discourse/app/components/d-modal.js index 8afc0436043..c262a3b979a 100644 --- a/app/assets/javascripts/discourse/app/components/d-modal.js +++ b/app/assets/javascripts/discourse/app/components/d-modal.js @@ -1,6 +1,7 @@ import Component from "@glimmer/component"; +import ClassicComponent from "@ember/component"; import { action } from "@ember/object"; -import { tracked } from "@glimmer/tracking"; +import { cached, tracked } from "@glimmer/tracking"; import { inject as service } from "@ember/service"; export const CLOSE_INITIATED_BY_BUTTON = "initiatedByCloseButton"; @@ -170,4 +171,18 @@ export default class DModal extends Component { throw `@flashType must be one of ${FLASH_TYPES.join(", ")}`; } } + + // Could be optimised to remove classic component once RFC389 is implemented + // https://rfcs.emberjs.com/id/0389-dynamic-tag-names + @cached + get dynamicElement() { + const tagName = this.args.tagName || "div"; + if (!["div", "form"].includes(tagName)) { + throw `@tagName must be form or div`; + } + + return class WrapperComponent extends ClassicComponent { + tagName = tagName; + }; + } } diff --git a/app/assets/javascripts/discourse/tests/integration/components/d-modal-test.js b/app/assets/javascripts/discourse/tests/integration/components/d-modal-test.js index 0349fcca19e..3bb63656186 100644 --- a/app/assets/javascripts/discourse/tests/integration/components/d-modal-test.js +++ b/app/assets/javascripts/discourse/tests/integration/components/d-modal-test.js @@ -86,4 +86,29 @@ module("Integration | Component | d-modal", function (hooks) { assert.dom(".d-modal .modal-header").hasClass("my-header-class"); assert.dom(".d-modal .modal-body").hasClass("my-body-class"); }); + + test("as a form", async function (assert) { + let submittedFormData; + this.handleSubmit = (event) => { + event.preventDefault(); + submittedFormData = new FormData(event.currentTarget); + }; + + await render( + hbs` + + <:body> + + + <:footer> + + + + ` + ); + + assert.dom("form.d-modal").exists(); + await click(".d-modal button[type=submit]"); + assert.deepEqual(submittedFormData.get("name"), "John Doe"); + }); }); diff --git a/plugins/styleguide/assets/javascripts/discourse/components/sections/organisms/modal.hbs b/plugins/styleguide/assets/javascripts/discourse/components/sections/organisms/modal.hbs index a0cd9b54630..2da5d63612e 100644 --- a/plugins/styleguide/assets/javascripts/discourse/components/sections/organisms/modal.hbs +++ b/plugins/styleguide/assets/javascripts/discourse/components/sections/organisms/modal.hbs @@ -32,6 +32,15 @@ {{on "click" this.toggleDismissable}} /> + + + diff --git a/plugins/styleguide/assets/javascripts/discourse/components/sections/organisms/modal.js b/plugins/styleguide/assets/javascripts/discourse/components/sections/organisms/modal.js index 8f719f8a6bd..05374113e4e 100644 --- a/plugins/styleguide/assets/javascripts/discourse/components/sections/organisms/modal.js +++ b/plugins/styleguide/assets/javascripts/discourse/components/sections/organisms/modal.js @@ -6,6 +6,7 @@ import I18n from "I18n"; export default class extends Component { @tracked inline = true; @tracked dismissable = true; + @tracked modalTagName = "div"; @tracked title = I18n.t("styleguide.sections.modal.header"); @tracked body = this.args.dummy.shortLorem; @tracked subtitle = ""; @@ -13,6 +14,7 @@ export default class extends Component { @tracked flashType = "success"; flashTypes = ["success", "info", "warning", "error"]; + modalTagNames = ["div", "form"]; @action toggleInline() {