Teact: Introduce setExtraStyles

This commit is contained in:
Alexander Zinchuk 2023-07-05 13:16:11 +02:00
parent 4e87c56fb9
commit 392b2d53cb
3 changed files with 85 additions and 28 deletions

View File

@ -1,7 +1,9 @@
import type { RefObject } from 'react';
import React, { useEffect, useLayoutEffect, useRef } from '../../lib/teact/teact';
import { addExtraClass, removeExtraClass, toggleExtraClass } from '../../lib/teact/teact-dom';
import { requestMutation, requestForcedReflow } from '../../lib/fasterdom/fasterdom';
import {
addExtraClass, removeExtraClass, setExtraStyles, toggleExtraClass,
} from '../../lib/teact/teact-dom';
import { requestForcedReflow, requestMutation } from '../../lib/fasterdom/fasterdom';
import { getGlobal } from '../../global';
@ -146,8 +148,10 @@ function Transition({
addExtraClass(activeChild, CLASSES.active);
if (isSlideOptimized) {
activeChild.style.transition = 'none';
activeChild.style.transform = 'translate3d(0, 0, 0)';
setExtraStyles(activeChild, {
transition: 'none',
transform: 'translate3d(0, 0, 0)',
});
}
}
@ -233,8 +237,8 @@ function Transition({
if (shouldRestoreHeight) {
if (activeElement) {
activeElement.style.height = 'auto';
container.style.height = `${clientHeight}px`;
setExtraStyles(activeElement, { height: 'auto' });
setExtraStyles(container, { height: `${clientHeight}px` });
}
}
@ -290,9 +294,11 @@ function Transition({
}
requestMutation(() => {
activeElement.style.height = 'auto';
container.style.height = `${clientHeight}px`;
container.style.flexBasis = `${clientHeight}px`;
setExtraStyles(activeElement, { height: 'auto' });
setExtraStyles(container, {
height: `${clientHeight}px`,
flexBasis: `${clientHeight}px`,
});
});
}, [shouldRestoreHeight, children]);
@ -347,15 +353,19 @@ function performSlideOptimized(
toggleExtraClass(container, `Transition-${name}Backwards`, isBackwards);
if (fromSlide instanceof HTMLElement) {
fromSlide.style.transition = 'none';
fromSlide.style.transform = '';
removeExtraClass(fromSlide, CLASSES.active);
setExtraStyles(fromSlide, {
transition: 'none',
transform: '',
});
}
if (toSlide instanceof HTMLElement) {
toSlide.style.transition = 'none';
toSlide.style.transform = 'translate3d(0, 0, 0)';
addExtraClass(toSlide, CLASSES.active);
setExtraStyles(toSlide, {
transition: 'none',
transform: 'translate3d(0, 0, 0)',
});
}
cleanup();
@ -375,13 +385,17 @@ function performSlideOptimized(
toggleExtraClass(container, `Transition-${name}Backwards`, isBackwards);
if (fromSlide instanceof HTMLElement) {
fromSlide.style.transition = 'none';
fromSlide.style.transform = 'translate3d(0, 0, 0)';
setExtraStyles(fromSlide, {
transition: 'none',
transform: 'translate3d(0, 0, 0)',
});
}
if (toSlide instanceof HTMLElement) {
toSlide.style.transition = 'none';
toSlide.style.transform = `translate3d(${isBackwards ? '-' : ''}100%, 0, 0)`;
setExtraStyles(toSlide, {
transition: 'none',
transform: `translate3d(${isBackwards ? '-' : ''}100%, 0, 0)`,
});
}
requestForcedReflow(() => {
@ -391,15 +405,19 @@ function performSlideOptimized(
return () => {
if (fromSlide instanceof HTMLElement) {
fromSlide.style.transition = '';
fromSlide.style.transform = `translate3d(${isBackwards ? '' : '-'}100%, 0, 0)`;
removeExtraClass(fromSlide, CLASSES.active);
setExtraStyles(fromSlide, {
transition: '',
transform: `translate3d(${isBackwards ? '' : '-'}100%, 0, 0)`,
});
}
if (toSlide instanceof HTMLElement) {
toSlide.style.transition = '';
toSlide.style.transform = 'translate3d(0, 0, 0)';
addExtraClass(toSlide, CLASSES.active);
setExtraStyles(toSlide, {
transition: '',
transform: 'translate3d(0, 0, 0)',
});
}
};
});
@ -413,13 +431,15 @@ function performSlideOptimized(
}
if (fromSlide instanceof HTMLElement) {
fromSlide.style.transition = 'none';
fromSlide.style.transform = '';
setExtraStyles(fromSlide, {
transition: 'none',
transform: '',
});
}
if (shouldRestoreHeight && clientHeight && toSlide instanceof HTMLElement) {
toSlide.style.height = 'auto';
container.style.height = `${clientHeight}px`;
setExtraStyles(toSlide, { height: 'auto' });
setExtraStyles(container, { height: `${clientHeight}px` });
}
onStop?.();

View File

@ -46,6 +46,7 @@ const INDEX_KEY_PREFIX = '__indexKey#';
const headsByElement = new WeakMap<Element, VirtualDomHead>();
const extraClasses = new WeakMap<Element, Set<string>>();
const extraStyles = new WeakMap<Element, Record<string, string>>();
// eslint-disable-next-line @typescript-eslint/naming-convention
let DEBUG_virtualTreeSize = 1;
@ -669,7 +670,7 @@ function setAttribute(element: HTMLElement, key: string, value: any) {
}
}
} else if (key === 'style') {
element.style.cssText = value;
updateStyle(element, value);
} else if (key === 'dangerouslySetInnerHTML') {
// eslint-disable-next-line no-underscore-dangle
element.innerHTML = value.__html;
@ -688,7 +689,7 @@ function removeAttribute(element: HTMLElement, key: string, value: any) {
} else if (key === 'value') {
(element as HTMLInputElement).value = '';
} else if (key === 'style') {
element.style.cssText = '';
updateStyle(element, '');
} else if (key === 'dangerouslySetInnerHTML') {
element.innerHTML = '';
} else if (key.startsWith('on')) {
@ -713,6 +714,15 @@ function updateClassName(element: HTMLElement, value: string) {
element.className = extraArray.join(' ');
}
function updateStyle(element: HTMLElement, value: string) {
element.style.cssText = value;
const extraObject = extraStyles.get(element);
if (extraObject) {
applyExtraStyles(element);
}
}
export function addExtraClass(element: Element, className: string, forceSingle = false) {
if (!forceSingle) {
const classNames = className.split(' ');
@ -780,6 +790,28 @@ export function toggleExtraClass(element: Element, className: string, force?: bo
}
}
export function setExtraStyles(element: HTMLElement, styles: Partial<CSSStyleDeclaration> & AnyLiteral) {
extraStyles.set(element, styles);
applyExtraStyles(element);
}
function applyExtraStyles(element: HTMLElement) {
const standardStyles = Object.entries(extraStyles.get(element)!).reduce<Record<string, string>>(
(acc, [prop, value]) => {
if (prop.startsWith('--')) {
element.style.setProperty(prop, value);
} else {
acc[prop] = value;
}
return acc;
},
{},
);
Object.assign(element.style, standardStyles);
}
// eslint-disable-next-line @typescript-eslint/naming-convention
function DEBUG_addToVirtualTreeSize($current: VirtualElementParent | VirtualDomHead) {
DEBUG_virtualTreeSize += $current.children.length;

View File

@ -745,7 +745,12 @@ function useEffectBase(
};
function setupSignals() {
const cleanups = dependencies?.filter(isSignal).map((signal) => signal.subscribe(() => {
const cleanups = dependencies?.filter(isSignal).map((signal, i) => signal.subscribe(() => {
if (debugKey) {
// eslint-disable-next-line no-console
console.log(`[Teact] Effect "${debugKey}" caused by signal #${i} new value:`, signal());
}
byCursor[cursor].schedule();
}));