diff --git a/examples/expo-example/app.json b/examples/expo-example/app.json
index 2be12af..fdcf381 100644
--- a/examples/expo-example/app.json
+++ b/examples/expo-example/app.json
@@ -3,7 +3,7 @@
"name": "expo-example",
"slug": "expo-example",
"version": "1.0.0",
- "orientation": "portrait",
+ "orientation": "default",
"icon": "./assets/icon.png",
"entryPoint": "./src/app.tsx",
"userInterfaceStyle": "light",
diff --git a/examples/expo-example/src/app.tsx b/examples/expo-example/src/app.tsx
index 2317e7d..c7a8d9f 100644
--- a/examples/expo-example/src/app.tsx
+++ b/examples/expo-example/src/app.tsx
@@ -31,9 +31,28 @@ const BoxWithoutProps = (props: Stylable) => {
{
backgroundColor: { xs: "#00ff00", md: "#ff0000" },
transform: [{ scaleY: 0.7 }],
- hover: { alignContent: "center", alignItems: "center" },
- press: { alignContent: "center" },
- focus: { alignContent: "center" },
+ press: {
+ self: {
+ bg: "red",
+ },
+ text: {
+ color: "white",
+ },
+ },
+ hover: {
+ text: {
+ color: "blue",
+ },
+ },
+ focus: {
+ self: {
+ bg: "yellow"
+ },
+ text: {
+ transform: [{ scale: 2 }],
+ color: "green"
+ },
+ },
},
md({
shadowOpacity: 0.5,
@@ -45,9 +64,12 @@ const BoxWithoutProps = (props: Stylable) => {
)}
>
Text inside the box without props (green on small screens, red on bigs)
@@ -85,12 +107,14 @@ function App() {
Open up App.tsx to start working on your app!
-
- Test
-
+
+
+ Test
+
+
);
diff --git a/packages/yoshiki/src/native/generator.tsx b/packages/yoshiki/src/native/generator.tsx
index 99c6763..4177f9a 100644
--- a/packages/yoshiki/src/native/generator.tsx
+++ b/packages/yoshiki/src/native/generator.tsx
@@ -3,12 +3,20 @@
// Licensed under the MIT license. See LICENSE file in the project root for details.
//
-import { useWindowDimensions } from "react-native";
+import { PressableProps, useWindowDimensions, ViewStyle } from "react-native";
import { breakpoints, Theme, useTheme } from "../theme";
-import { Breakpoints, YoshikiStyle, hasState, processStyleList } from "../type";
+import {
+ Breakpoints,
+ YoshikiStyle,
+ hasState,
+ processStyleList,
+ processStyleListWithChild,
+ assignChilds,
+} from "../type";
import { isBreakpoints } from "../utils";
import { shorthandsFn } from "../shorthands";
-import { StyleFunc, NativeCssFunc } from "./type";
+import { StyleFunc, NativeCssFunc, NativeStyle } from "./type";
+import { useReducer, useRef, useState } from "react";
const useBreakpoint = (): number => {
const { width } = useWindowDimensions();
@@ -46,12 +54,19 @@ const propertyMapper = (
return [[key, value]];
};
+const useForceRerender = () => {
+ return useReducer((x) => x + 1, 0)[1];
+};
+
export const useYoshiki = () => {
const breakpoint = useBreakpoint();
const theme = useTheme();
+ const rerender = useForceRerender();
+ const childStyles = useRef>({});
const css: NativeCssFunc = (cssList, leftOvers) => {
- const css = processStyleList(cssList);
+ // The as any is because we can't be sure the style type is right one.
+ const css = processStyleListWithChild(cssList, childStyles.current as any);
const processStyle = (styleList: Record>) => {
const ret = Object.fromEntries(
@@ -62,35 +77,63 @@ export const useYoshiki = () => {
return ret;
};
- if (hasState>(css)) {
+ if (hasState>(css)) {
const { hover, focus, press, ...inline } = css;
- const ret: StyleFunc = ({ hovered, focused, pressed }) => ({
- ...processStyle(inline),
- ...(hovered ? processStyle(hover ?? {}) : {}),
- ...(focused ? processStyle(focus ?? {}) : {}),
- ...(pressed ? processStyle(press ?? {}) : {}),
- ...(leftOvers?.style
- ? typeof leftOvers?.style === "function"
- ? processStyleList(leftOvers?.style({ hovered, focused, pressed }))
- : processStyleList(leftOvers?.style)
- : {}),
- });
+ const { onPressIn, onPressOut, onHoverIn, onHoverOut, onFocus, onBlur } =
+ leftOvers as PressableProps;
+ const ret: StyleFunc = ({ hovered, focused, pressed }) => {
+ childStyles.current = {};
+ if (hovered) assignChilds(childStyles.current, hover);
+ if (focused) assignChilds(childStyles.current, focus);
+ if (pressed) assignChilds(childStyles.current, press);
+
+ return [
+ processStyle(inline),
+ hovered && processStyle(hover?.self ?? {}),
+ focused && processStyle(focus?.self ?? {}),
+ pressed && processStyle(press?.self ?? {}),
+ leftOvers?.style &&
+ (typeof leftOvers?.style === "function"
+ ? processStyleList(leftOvers?.style({ hovered, focused, pressed }))
+ : leftOvers?.style),
+ ];
+ };
return {
...leftOvers,
- style: ret,
- };
+ style: ret as StyleFunc,
+ // We must use a setTimeout since the child styles are computed inside the style function (called after onIn/onOut)
+ // NOTE: The props onIn/onOut are overriden here and the user can't use them. Might want to find a way arround that.
+ onPressIn: (e) => {
+ onPressIn?.call(null, e);
+ setTimeout(rerender);
+ },
+ onPressOut: (e) => {
+ onPressOut?.call(null, e);
+ setTimeout(rerender);
+ },
+ onHoverIn: (e) => {
+ onHoverIn?.call(null, e);
+ setTimeout(rerender);
+ },
+ onHoverOut: (e) => {
+ onHoverOut?.call(null, e);
+ setTimeout(rerender);
+ },
+ onFocus: (e) => {
+ onFocus?.call(null, e);
+ setTimeout(rerender);
+ },
+ onBlur: (e) => {
+ onBlur?.call(null, e);
+ setTimeout(rerender);
+ },
+ } satisfies PressableProps;
} else {
- const loStyles =
- leftOvers?.style && typeof leftOvers?.style !== "function"
- ? processStyleList(leftOvers.style)
- : {};
- const ret = {
+ return {
...leftOvers,
- style: { ...processStyle(css), ...loStyles },
- };
-
- return ret as any;
+ style: [processStyle(css), leftOvers?.style],
+ } as any;
}
};
diff --git a/packages/yoshiki/src/native/type.ts b/packages/yoshiki/src/native/type.ts
index 514ef9f..5493e90 100644
--- a/packages/yoshiki/src/native/type.ts
+++ b/packages/yoshiki/src/native/type.ts
@@ -5,7 +5,7 @@
import { WithState, YoshikiStyle, StyleList } from "../type";
import { shorthandsFn } from "../shorthands";
-import { ImageStyle, StyleProp, TextStyle, ViewStyle } from "react-native";
+import { ImageStyle, PressableProps, StyleProp, TextStyle, ViewStyle } from "react-native";
import { Theme } from "../theme";
import { forceBreakpoint } from "../utils";
@@ -42,33 +42,18 @@ export type StyleFunc