Add breakpoints support

This commit is contained in:
Zoe Roux
2022-11-05 01:43:51 +09:00
parent a47b582537
commit 5a373c3b7a
7 changed files with 69 additions and 13 deletions
+1 -3
View File
@@ -27,9 +27,7 @@
},
"web": {
"build": {
"babel": {
"include": ["@yoshiki/native", "@yoshiki/core"]
}
"bundler": "metro"
},
"favicon": "./assets/favicon.png"
}
+4 -1
View File
@@ -14,7 +14,10 @@ const workspaceRoot = path.resolve(projectRoot, "../..");
const config = getDefaultConfig(projectRoot);
// 1. Watch all files within the monorepo
config.watchFolders = [workspaceRoot];
config.watchFolders = [
path.resolve(workspaceRoot, "examples/expo-example"),
path.resolve(workspaceRoot, "packages"),
];
// 2. Let Metro know where to resolve packages and in what order
config.resolver.nodeModulesPaths = [
path.resolve(projectRoot, "node_modules"),
+1 -1
View File
@@ -18,7 +18,7 @@ const CustomBox = ({ color, ...props }: { color: string }) => {
const BoxWithoutProps = (props: object) => {
return (
<View {...css({ backgroundColor: "#999999" }, props)}>
<View {...css({ backgroundColor: { xs: "00ff00", md: "#ff0000"} }, props)}>
<Text>Text inside the box without props</Text>
</View>
);
+18
View File
@@ -0,0 +1,18 @@
//
// Copyright (c) Zoe Roux and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
//
const createExpoWebpackConfigAsync = require("@expo/webpack-config");
module.exports = async function (env, argv) {
const config = await createExpoWebpackConfigAsync(
{
...env,
babel: {
dangerouslyAddModulePathsToTranspile: ["@yoshiki"],
},
},
argv,
);
return config;
};
+10 -4
View File
@@ -8,14 +8,20 @@ export type Theme = {
spacing: string;
};
export const breakpoints = {
xs: 0,
sm: 600,
md: 900,
lg: 1200,
xl: 1600,
}
export type YoushikiStyle<Property> =
| Property
| ((theme: Theme) => Property)
| Breakpoints<Property>;
export type Breakpoints<Property> = {
sm?: Property;
md?: Property;
lg?: Property;
xl?: Property;
[key in keyof (typeof breakpoints)]?: Property;
};
+34 -4
View File
@@ -3,21 +3,51 @@
// Licensed under the MIT license. See LICENSE file in the project root for details.
//
import { ViewStyle, TextStyle, ImageStyle } from "react-native";
import { YoushikiStyle } from "@yoshiki/core";
import { ViewStyle, TextStyle, ImageStyle, useWindowDimensions } from "react-native";
import { breakpoints, Breakpoints, YoushikiStyle } from "@yoshiki/core";
// TODO: shorhands
type EnhancedStyle<Properties> = {
[key in keyof Properties]: YoushikiStyle<Properties[key]>;
};
export type CssObject = EnhancedStyle<ViewStyle> | EnhancedStyle<TextStyle> | EnhancedStyle<ImageStyle>;
export type CssObject =
| EnhancedStyle<ViewStyle>
| EnhancedStyle<TextStyle>
| EnhancedStyle<ImageStyle>;
type Properties = ViewStyle | TextStyle | ImageStyle;
const useBreakpoint = (): number => {
const { width } = useWindowDimensions();
const idx = Object.values(breakpoints).findIndex((x) => width <= x);
if (idx === -1) return 0;
return idx - 1;
};
export const css = (css: CssObject, leftOvers?: { style?: Properties }) => {
const { style, ...leftOverProps } = leftOvers ?? {};
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 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),
);
return {
style: { ...css, ...style } as Properties,
style: { ...ret, ...style },
...leftOverProps,
};
};
+1
View File
@@ -1,5 +1,6 @@
{
"compilerOptions": {
"noErrorTruncation": true,
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"declaration": true,