Files
yoshiki/packages/yoshiki/src/native/generator.web.ts
2023-01-09 18:10:49 +09:00

67 lines
2.1 KiB
TypeScript

//
// Copyright (c) Zoe Roux and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
//
import { useInsertionEffect } from "react";
import { RegisteredStyle } from "react-native";
import { useTheme } from "../theme";
import { processStyleList, processStyleListWithoutChild, StyleList } from "../type";
import { NativeCssFunc } from "./type";
import createReactDOMStyle from "react-native-web/dist/exports/StyleSheet/compiler/createReactDOMStyle";
import preprocess from "react-native-web/dist/exports/StyleSheet/preprocess";
import { useClassId, yoshikiCssToClassNames } from "../web/generator";
import { useStyleRegistry } from "../web";
const rnwPreprocess = (block: Record<string, unknown>) => {
return createReactDOMStyle(block);
};
export const useYoshiki = () => {
const registry = useStyleRegistry();
const theme = useTheme();
const childPrefix = useClassId();
useInsertionEffect(() => {
registry.flushToBrowser();
}, [registry]);
const css: NativeCssFunc = (cssList, leftOvers) => {
const [css, parentKeys] = processStyleListWithoutChild(cssList);
const getStyle = (
inlineList: StyleList<{ $$css?: true; yoshiki?: string } | RegisteredStyle<unknown>>,
) => {
const inline = processStyleList(inlineList);
const overrides = "$$css" in inline && inline.$$css ? inline.yoshiki : undefined;
const classNames = yoshikiCssToClassNames(
css,
[...parentKeys.map((x) => `${childPrefix}${x}`), ...(overrides?.split(" ") ?? [])],
{
registry,
theme,
preprocessBlock: rnwPreprocess,
preprocess,
},
);
// We use the inlineList and not the inline we have locally since $$css and inlines are not mergable.
return [inlineList, { $$css: true, yoshiki: classNames }];
};
const loStyle = leftOvers?.style;
const style =
typeof loStyle === "function"
? (state: { hovered?: boolean; focused?: boolean; pressed?: boolean }) =>
getStyle(loStyle(state))
: getStyle(loStyle);
return {
...leftOvers,
style,
};
};
return {
css,
theme,
};
};