mirror of
https://github.com/zoriya/yoshiki.git
synced 2026-06-06 03:45:29 +00:00
Convert css to a hook useCss
This commit is contained in:
@@ -14,10 +14,7 @@ const workspaceRoot = path.resolve(projectRoot, "../..");
|
||||
const config = getDefaultConfig(projectRoot);
|
||||
|
||||
// 1. Watch all files within the monorepo
|
||||
config.watchFolders = [
|
||||
path.resolve(workspaceRoot, "examples/expo-example"),
|
||||
path.resolve(workspaceRoot, "packages"),
|
||||
];
|
||||
config.watchFolders = [workspaceRoot];
|
||||
// 2. Let Metro know where to resolve packages and in what order
|
||||
config.resolver.nodeModulesPaths = [
|
||||
path.resolve(projectRoot, "node_modules"),
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
import { StatusBar } from "expo-status-bar";
|
||||
import { Text, View } from "react-native";
|
||||
import { registerRootComponent } from "expo";
|
||||
import { css } from "@yoshiki/native";
|
||||
import { useCss } from "@yoshiki/native";
|
||||
|
||||
const CustomBox = ({ color, ...props }: { color: string }) => {
|
||||
const css = useCss();
|
||||
|
||||
return (
|
||||
<View {...css({ backgroundColor: color }, props)}>
|
||||
<Text {...css({ color: "white" })}>Text inside the custom black box.</Text>
|
||||
@@ -17,14 +19,18 @@ const CustomBox = ({ color, ...props }: { color: string }) => {
|
||||
};
|
||||
|
||||
const BoxWithoutProps = (props: object) => {
|
||||
const css = useCss();
|
||||
|
||||
return (
|
||||
<View {...css({ backgroundColor: { xs: "00ff00", md: "#ff0000"} }, props)}>
|
||||
<Text>Text inside the box without props</Text>
|
||||
<View {...css({ backgroundColor: { xs: "#00ff00", md: "#ff0000"} }, props)}>
|
||||
<Text>Text inside the box without props (green on small screens, red on bigs)</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
function App() {
|
||||
const css = useCss();
|
||||
|
||||
return (
|
||||
<View
|
||||
{...css({
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//
|
||||
|
||||
import { ViewStyle, TextStyle, ImageStyle, useWindowDimensions } from "react-native";
|
||||
import { breakpoints, Breakpoints, YoushikiStyle } from "@yoshiki/core";
|
||||
import { breakpoints, Breakpoints, Theme, YoushikiStyle } from "@yoshiki/core";
|
||||
|
||||
// TODO: shorhands
|
||||
type EnhancedStyle<Properties> = {
|
||||
@@ -23,31 +23,58 @@ const useBreakpoint = (): number => {
|
||||
return idx - 1;
|
||||
};
|
||||
|
||||
export const css = (css: CssObject, leftOvers?: { style?: Properties }) => {
|
||||
const { style, ...leftOverProps } = leftOvers ?? {};
|
||||
export const useTheme = () => {
|
||||
return {} as Theme;
|
||||
};
|
||||
|
||||
let breakpoint: number | undefined = undefined;
|
||||
const ret: Properties = Object.fromEntries(
|
||||
Object.entries(css)
|
||||
.map(([key, value]) => {
|
||||
if (typeof value === "object") {
|
||||
if (!breakpoint) breakpoint = useBreakpoint();
|
||||
const isBreakpoints = <T,>(value: unknown): value is Breakpoints<T> => {
|
||||
if (typeof value !== "object" || !value) return false;
|
||||
for (const v of Object.keys(value)) {
|
||||
if (!(v in breakpoints)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const bpKeys = Object.keys(breakpoints);
|
||||
for (let i = breakpoint; i >= 0; i--) {
|
||||
if (bpKeys[i] in value) {
|
||||
return [key, value[bpKeys[i]]];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
return [key, value];
|
||||
})
|
||||
.filter((x) => x !== undefined),
|
||||
);
|
||||
const propertyMapper = <
|
||||
Property extends number | string | boolean | undefined | Property[] | object,
|
||||
>(
|
||||
value: Property | Breakpoints<Property> | ((theme: Theme) => Property),
|
||||
{ breakpoint, theme }: { breakpoint: number; theme: Theme },
|
||||
): Property | undefined => {
|
||||
if (isBreakpoints<Property>(value)) {
|
||||
const bpKeys = Object.keys(breakpoints) as Array<keyof Breakpoints<Property>>;
|
||||
for (let i = breakpoint; i >= 0; i--) {
|
||||
if (bpKeys[i] in value) {
|
||||
return value[bpKeys[i]];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
if (typeof value === "function") {
|
||||
return value(theme);
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
return {
|
||||
style: { ...ret, ...style },
|
||||
...leftOverProps,
|
||||
// TODO: do not use a hook and use a global window width.
|
||||
export const useCss = () => {
|
||||
const breakpoint = useBreakpoint();
|
||||
const theme = useTheme();
|
||||
|
||||
return (css: CssObject, leftOvers?: { style?: Properties }) => {
|
||||
const { style, ...leftOverProps } = leftOvers ?? {};
|
||||
|
||||
const ret: Properties = Object.fromEntries(
|
||||
Object.entries(css)
|
||||
.map(([key, value]) => [key, propertyMapper(value, { breakpoint, theme })])
|
||||
.filter(([, value]) => value !== undefined),
|
||||
);
|
||||
|
||||
return {
|
||||
style: { ...ret, ...style },
|
||||
...leftOverProps,
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user