У меня есть приложение preact SSR, и я использовал Emotion JS 10 для стилизации.
Я хотел добавить поддержку RTL, поэтому использовал createEmotion
и createEmotionServer
и использовал renderStylesToString
для визуализации приложения.
Однако при создании createEmotion
требуется использование плагинов, для которых я добавил плагин stylis-rtl
, но это всегда будет применять стили RTL, в то время как я хочу, чтобы стили RTL применялись на основе каждого запроса.
Я не смог найти способ сказать эмоции для применения и получить стили для RTL для каждого запроса.
Они имеют прямую реализацию для React 16, в которой вы можете передавать несколько кэшей для каждого запроса в CacheProvider
.
Но я не могу понять это для Preact.
Одним из решений может быть обслуживание различных сборок веб-пакетов для RTL, но это не потребует дополнительных затрат.
РЕДАКТИРОВАТЬ 1:
для тех, кто хочет реализовать нечто подобное, это мой подход
Клиентская сторона, а также css
импорт на сервер:
import stylisRTL from 'stylis-rtl';
import createEmotion from 'create-emotion';
const {
cx: cxRTL,
injectGlobal: injectGlobalRTL,
css: cssRTL,
cache: cacheRTL,
keyframes: keyframesRTL
} = createEmotion({
key: 'c',
stylisPlugins: [stylisRTL]
});
const {
cx: cxLTR,
injectGlobal: injectGlobalLTR,
css: cssLTR,
cache: cacheLTR,
keyframes: keyframesLTR
} = createEmotion({
key: 'c',
stylisPlugins: []
});
const runForBoth = (rtlFn, ltrFn) => (...args) => {
//this would be ur store sent in html to check whether it is in rtl or ltr mode
const isRTL = typeof window !== 'undefined' && window.__PRELOADED_STATE__.shell.RTL;
let result;
if (__BROWSER__) {
if (isRTL) {
result = rtlFn(...args);
} else {
result = ltrFn(...args);
}
} else {
result = ltrFn(...args);
rtlFn(...args);
}
return result;
};
export const cx = runForBoth(cxRTL, cxLTR);
export const injectGlobal = runForBoth(injectGlobalRTL, injectGlobalLTR);
export const css = runForBoth(cssRTL, cssLTR);
export const keyframes = runForBoth(keyframesRTL, keyframesLTR);
export const cacheEmotionLTR = cacheLTR;
export const cacheEmotionRTL = cacheRTL;
и для ССР:
const { renderStylesToString: renderStylesToStringLTR } = createEmotionServer(cacheEmotionLTR);
const { renderStylesToString: renderStylesToStringRTL } = createEmotionServer(cacheEmotionRTL);
я создаю 2 кеша и, основываясь на заголовках запросов, решаю, какой renderStylesToString
использовать
Единственное, что меня беспокоит, это runForBoth
технически неправильно. Но это работает на данный момент.
Я не хотел менять способ css
Fn импортируется, так как теперь я могу просто использовать этот импорт пользовательских эмоций и псевдоним его в веб-пакете