diff --git a/src/lib/teact/teact.ts b/src/lib/teact/teact.ts index 6c3ac85bd..d2c683716 100644 --- a/src/lib/teact/teact.ts +++ b/src/lib/teact/teact.ts @@ -1,13 +1,13 @@ import type { ReactElement } from 'react'; +import { requestMeasure, requestMutation } from '../fasterdom/fasterdom'; import { DEBUG, DEBUG_MORE } from '../../config'; +import { throttleWith } from '../../util/schedulers'; +import { orderBy } from '../../util/iteratees'; import { logUnequalProps } from '../../util/arePropsShallowEqual'; import { incrementOverlayCounter } from '../../util/debugOverlay'; -import { orderBy } from '../../util/iteratees'; -import safeExec from '../../util/safeExec'; -import { throttleWith } from '../../util/schedulers'; import { isSignal } from '../../util/signals'; -import { requestMeasure, requestMutation } from '../fasterdom/fasterdom'; +import safeExec from '../../util/safeExec'; export type Props = AnyLiteral; export type FC
= (props: P) => any;
@@ -170,6 +170,8 @@ function createElement(
props: Props,
...children: any[]
): VirtualElementParent | VirtualElementChildren {
+ children = children.flat();
+
if (source === Fragment) {
return buildFragmentElement(children);
} else if (typeof source === 'function') {
@@ -182,13 +184,18 @@ function createElement(
function buildFragmentElement(children: any[]): VirtualElementFragment {
return {
type: VirtualElementTypesEnum.Fragment,
- children: buildChildren(children, true),
+ children: dropEmptyTail(children, true).map(buildChildElement),
};
}
function createComponentInstance(Component: FC, props: Props, children: any[]): VirtualElementComponent {
- if (children?.length) {
- props.children = children.length === 1 ? children[0] : children;
+ let parsedChildren: any | any[] | undefined;
+ if (children.length === 0) {
+ parsedChildren = undefined;
+ } else if (children.length === 1) {
+ [parsedChildren] = children;
+ } else {
+ parsedChildren = children;
}
const componentInstance: ComponentInstance = {
@@ -196,7 +203,10 @@ function createComponentInstance(Component: FC, props: Props, children: any[]):
$element: {} as VirtualElementComponent,
Component,
name: Component.name,
- props,
+ props: {
+ ...props,
+ ...(parsedChildren && { children: parsedChildren }),
+ },
mountState: MountState.New,
hooks: {
state: {
@@ -225,13 +235,13 @@ function createComponentInstance(Component: FC, props: Props, children: any[]):
function buildComponentElement(
componentInstance: ComponentInstance,
- children?: VirtualElementChildren,
+ children: VirtualElementChildren = [],
): VirtualElementComponent {
return {
type: VirtualElementTypesEnum.Component,
componentInstance,
props: componentInstance.props,
- children: children ? buildChildren(children, true) : [],
+ children: dropEmptyTail(children, true).map(buildChildElement),
};
}
@@ -240,26 +250,10 @@ function buildTagElement(tag: string, props: Props, children: any[]): VirtualEle
type: VirtualElementTypesEnum.Tag,
tag,
props,
- children: buildChildren(children),
+ children: dropEmptyTail(children).map(buildChildElement),
};
}
-function buildChildren(children: any[], noEmpty = false): VirtualElement[] {
- const cleanChildren = dropEmptyTail(children, noEmpty);
- const newChildren = [];
-
- for (let i = 0, l = cleanChildren.length; i < l; i++) {
- const child = cleanChildren[i];
- if (Array.isArray(child)) {
- newChildren.push(...buildChildren(child, noEmpty));
- } else {
- newChildren.push(buildChildElement(child));
- }
- }
-
- return newChildren;
-}
-
// We only need placeholders in the middle of collection (to ensure other elements order).
function dropEmptyTail(children: any[], noEmpty = false) {
let i = children.length - 1;
@@ -282,22 +276,31 @@ function dropEmptyTail(children: any[], noEmpty = false) {
}
function isEmptyPlaceholder(child: any) {
- return !child && child !== 0;
+ // eslint-disable-next-line no-null/no-null
+ return child === false || child === null || child === undefined;
}
function buildChildElement(child: any): VirtualElement {
if (isEmptyPlaceholder(child)) {
- return { type: VirtualElementTypesEnum.Empty };
+ return buildEmptyElement();
} else if (isParentElement(child)) {
return child;
} else {
- return {
- type: VirtualElementTypesEnum.Text,
- value: String(child),
- };
+ return buildTextElement(child);
}
}
+function buildTextElement(value: any): VirtualElementText {
+ return {
+ type: VirtualElementTypesEnum.Text,
+ value: String(value),
+ };
+}
+
+function buildEmptyElement(): VirtualElementEmpty {
+ return { type: VirtualElementTypesEnum.Empty };
+}
+
// eslint-disable-next-line @typescript-eslint/naming-convention
const DEBUG_components: AnyLiteral = { TOTAL: { name: 'TOTAL', renders: 0 } };
// eslint-disable-next-line @typescript-eslint/naming-convention
@@ -581,13 +584,12 @@ export function useState