mirror of
https://github.com/discourse/discourse.git
synced 2025-01-18 10:52:45 +08:00
DEV: Introduce element
helper (#27086)
Returns a wrapper component with the given tagname, or an empty wrapper for an empty string. Similar to the reference implementation of RFC389, with higher-performance shortcuts for common elements.
This commit is contained in:
parent
23b02a3824
commit
fb9a43c282
|
@ -1,6 +1,5 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { cached, tracked } from "@glimmer/tracking";
|
||||
import ClassicComponent from "@ember/component";
|
||||
import { concat } from "@ember/helper";
|
||||
import { on } from "@ember/modifier";
|
||||
import { action } from "@ember/object";
|
||||
|
@ -12,6 +11,7 @@ import { and, not, or } from "truth-helpers";
|
|||
import ConditionalInElement from "discourse/components/conditional-in-element";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import concatClass from "discourse/helpers/concat-class";
|
||||
import element from "discourse/helpers/element";
|
||||
import {
|
||||
disableBodyScroll,
|
||||
enableBodyScroll,
|
||||
|
@ -39,24 +39,24 @@ export default class DModal extends Component {
|
|||
@tracked wrapperElement;
|
||||
@tracked animating = false;
|
||||
|
||||
registerModalContainer = modifierFn((element) => {
|
||||
this.modalContainer = element;
|
||||
registerModalContainer = modifierFn((el) => {
|
||||
this.modalContainer = el;
|
||||
});
|
||||
|
||||
setupModalBody = modifierFn((element) => {
|
||||
setupModalBody = modifierFn((el) => {
|
||||
if (!this.site.mobileView) {
|
||||
return;
|
||||
}
|
||||
|
||||
disableBodyScroll(element);
|
||||
disableBodyScroll(el);
|
||||
|
||||
return () => {
|
||||
enableBodyScroll(element);
|
||||
enableBodyScroll(el);
|
||||
};
|
||||
});
|
||||
|
||||
@action
|
||||
async setupModal(element) {
|
||||
async setupModal(el) {
|
||||
document.documentElement.addEventListener(
|
||||
"keydown",
|
||||
this.handleDocumentKeydown
|
||||
|
@ -70,7 +70,7 @@ export default class DModal extends Component {
|
|||
if (this.site.mobileView) {
|
||||
this.animating = true;
|
||||
|
||||
await element.animate(
|
||||
await el.animate(
|
||||
[{ transform: "translateY(100%)" }, { transform: "translateY(0)" }],
|
||||
{
|
||||
duration: getMaxAnimationTimeMs(),
|
||||
|
@ -82,7 +82,7 @@ export default class DModal extends Component {
|
|||
this.animating = false;
|
||||
}
|
||||
|
||||
this.wrapperElement = element;
|
||||
this.wrapperElement = el;
|
||||
}
|
||||
|
||||
@action
|
||||
|
@ -226,9 +226,7 @@ export default class DModal extends Component {
|
|||
throw `@tagName must be form or div`;
|
||||
}
|
||||
|
||||
return class WrapperComponent extends ClassicComponent {
|
||||
tagName = tagName;
|
||||
};
|
||||
return element(tagName);
|
||||
}
|
||||
|
||||
@bind
|
||||
|
|
65
app/assets/javascripts/discourse/app/helpers/element.gjs
Normal file
65
app/assets/javascripts/discourse/app/helpers/element.gjs
Normal file
|
@ -0,0 +1,65 @@
|
|||
import ClassicComponent from "@ember/component";
|
||||
|
||||
const empty = <template>
|
||||
{{! template-lint-disable no-yield-only}}{{yield}}
|
||||
</template>;
|
||||
const shortcuts = {
|
||||
div: <template><div ...attributes>{{yield}}</div></template>,
|
||||
span: <template><span ...attributes>{{yield}}</span></template>,
|
||||
form: <template><form ...attributes>{{yield}}</form></template>,
|
||||
a: <template><a ...attributes>{{yield}}</a></template>,
|
||||
button: <template><button ...attributes>{{yield}}</button></template>,
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a wrapper component with the given tagname, or an empty wrapper for an empty string.
|
||||
* Similar to the reference implementation of RFC389, with higher-performance shortcuts for common elements.
|
||||
*
|
||||
* Can be used directly in a template:
|
||||
*
|
||||
* ```hbs
|
||||
* {{#let (element @tagName) as |Wrapper|}}
|
||||
* <Wrapper class="pt-10 pb-10 ps-20 box-shadow" ...attributes>
|
||||
* Content
|
||||
* </Wrapper>
|
||||
* {{/let}}
|
||||
* ```
|
||||
*
|
||||
* Or in js:
|
||||
*
|
||||
* ```gjs
|
||||
* class MyComponent {
|
||||
* get wrapper(){
|
||||
* return element(this.args.tagName);
|
||||
* }
|
||||
*
|
||||
* <template>
|
||||
* <this.wrapper>
|
||||
* Content
|
||||
* </this.wrapper>
|
||||
* </template>
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export default function element(tagName) {
|
||||
if (typeof tagName !== "string") {
|
||||
throw new Error(
|
||||
`element helper only accepts string literals, you passed ${tagName}`
|
||||
);
|
||||
}
|
||||
|
||||
if (tagName === null || tagName === undefined) {
|
||||
return null;
|
||||
} else if (tagName === "") {
|
||||
return empty;
|
||||
} else if (shortcuts[tagName]) {
|
||||
return shortcuts[tagName];
|
||||
} else {
|
||||
return <template>
|
||||
<ClassicComponent
|
||||
@tagName={{tagName}}
|
||||
...attributes
|
||||
>{{yield}}</ClassicComponent>
|
||||
</template>;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user