Skip to content

Fix media merge with variants and compound variants #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions example/App.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import 'react-native-gesture-handler';

import { ColorModeProvider } from './src/components';
import Example from './src/Example';

export default function App() {
export function App() {
return (
<ColorModeProvider>
<Example />
Expand Down
3 changes: 2 additions & 1 deletion example/babel.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = function(api) {
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: ['react-native-reanimated/plugin'],
};
};
14 changes: 14 additions & 0 deletions example/entry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import 'expo/build/Expo.fx';
import { AppRegistry, Platform } from 'react-native';
import withExpoRoot from 'expo/build/launch/withExpoRoot';
import { createRoot } from 'react-dom/client';
import { App } from './App';

AppRegistry.registerComponent('main', () => withExpoRoot(App));
if (Platform.OS === 'web') {
const rootTag = createRoot(
document.getElementById('root') ?? document.getElementById('main')
);
const RootComponent = withExpoRoot(App);
rootTag.render(<RootComponent />);
}
22 changes: 12 additions & 10 deletions example/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "example",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"main": "entry.js",
"scripts": {
"start": "expo start",
"start:clean": "expo start --clear",
Expand All @@ -11,18 +11,20 @@
"eject": "expo eject"
},
"dependencies": {
"expo": "44.0.0",
"expo-device": "4.1.0",
"expo-status-bar": "1.2.0",
"expo": "^46.0.16",
"expo-device": "~4.3.0",
"expo-status-bar": "~1.4.0",
"lodash.merge": "4.6.2",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-gesture-handler": "2.1.0",
"react-native-reanimated": "2.3.1",
"react-native-web": "0.17.1"
"react": "18.0.0",
"react-dom": "18.0.0",
"react-native": "0.69.6",
"react-native-gesture-handler": "~2.5.0",
"react-native-reanimated": "~2.9.1",
"react-native-web": "~0.18.7",
"stitches-native": "link:../"
},
"devDependencies": {
"@expo/webpack-config": "^0.17.0",
"@babel/core": "7.12.9",
"@types/react": "17.0.21",
"@types/react-native": "0.64.12",
Expand Down
84 changes: 57 additions & 27 deletions example/src/Example.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,74 @@
import { Switch } from 'react-native';
import { StatusBar } from 'expo-status-bar';

import { Stack, Text, useColorMode } from './components';
import { useState } from 'react';
import { Stack, Text, useColorMode, Media, Heading } from './components';
import { styled } from './styles';

export default function Example() {
const { toggleColorMode, colorMode } = useColorMode();
const [example, changeExample] = useState(false);

return (
<Wrapper>
<Content>
<Stack axis="y" space="4">
<Text variant="title1">Example app</Text>

<Stack axis="y" space="2">
{Array.from({ length: 5 }).map((_, i) => (
<Box key={i}>
<Stack axis="x" space="4">
<Text variant="body" color="primaryText">
Box {i + 1}
</Text>
<Text variant="body" color="primaryText">
XXX
</Text>
<Text variant="body" color="primaryText">
YYY
</Text>
</Stack>
</Box>
))}
<Stack axis="x" space="3" align="center">
<Text variant="title1">Example app</Text>
<Stack axis="y" space="2">
<Text variant="body">Switch Examples</Text>
<Switch value={example} onValueChange={changeExample} />
</Stack>
</Stack>
{example && (
<Stack axis="y" space="2">
<Heading>Heading</Heading>
<Heading heading="h2">Heading</Heading>
<Heading heading="h3">Heading</Heading>
<Heading heading="h4">Heading</Heading>
<Heading heading="h5">Heading</Heading>
</Stack>
)}
{!example && (
<>
<Stack axis="y" space="2">
{Array.from({ length: 5 }).map((_, i) => (
<Box key={i}>
<Stack axis="x" space="4">
<Text variant="body" color="primaryText">
Box {i + 1}
</Text>
<Text variant="body" color="primaryText">
XXX
</Text>
<Text variant="body" color="primaryText">
YYY
</Text>
</Stack>
</Box>
))}
</Stack>

<Stack axis="x" space="3" align="center" justify="end">
<Text variant="body">Toggle color mode</Text>
<Media
color={{
'@xxl': 'primary',
'@xl': 'secondary',
'@lg': 'third',
'@md': 'forth',
'@sm': 'fifth',
}}
>
Font size and color should change as viewport changes
</Media>

<Switch
value={colorMode === 'dark'}
onValueChange={toggleColorMode}
/>
</Stack>
<Stack axis="x" space="3" align="center" justify="end">
<Text variant="body">Toggle color mode</Text>
<Switch
value={colorMode === 'dark'}
onValueChange={toggleColorMode}
/>
</Stack>
</>
)}
</Stack>
</Content>

Expand Down
32 changes: 32 additions & 0 deletions example/src/components/Heading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { TextProps as RNTextProps } from 'react-native';
import { styled } from '../styles';

export const Typography = styled('Text', {
color: '$plainText',
fontSizeRem: 1,
});

type HeadingSize = 'h1' | 'h2' | 'h3' | 'h4' | 'h5';

export type HeadingProps = RNTextProps & {
heading?: HeadingSize;
};

export const Heading = styled('Text', {
fontWeight: 'bold',
color: '$plainText',
variants: {
heading: {
h5: { fontSizeRem: 1.0, color: 'black' },
h4: { fontSizeRem: 1.1, color: 'red' },
h3: { fontSizeRem: 1.25, color: 'blue' },
h2: { fontSizeRem: 1.5, color: 'green' },
h1: { fontSizeRem: 2.5, color: 'purple' },
},
},
defaultVariants: {
heading: 'h1',
},
}).attrs(() => ({
accessibilityRole: 'text',
}));
31 changes: 31 additions & 0 deletions example/src/components/Media.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { styled } from '../styles';

export const Media = styled('Text', {
color: '$text',
'@xxl': {
fontSize: 64,
},
'@xl': {
fontSize: 48,
},
'@lg': {
fontSize: 32,
},
'@md': {
fontSize: 24,
},
'@sm': {
fontSize: 12,
},
marginTopRem: 1,
marginBottomRem: 1,
variants: {
color: {
primary: { color: 'red' },
secondary: { color: 'blue' },
third: { color: 'purple' },
forth: { color: 'green' },
fifth: { color: 'black' },
},
},
});
2 changes: 2 additions & 0 deletions example/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export { Text } from './Text';
export { Media } from './Media';
export { Heading } from './Heading';
export { Stack } from './Stack';
export { Spacer } from './Spacer';
export { ColorModeProvider, useColorMode } from './ColorMode';
26 changes: 25 additions & 1 deletion example/src/styles/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ import { getDeviceTypeAsync, DeviceType } from 'expo-device';
import { createStitches } from 'stitches-native';
import type * as Stitches from 'stitches-native';

import { size, shadow, typography, flexCenter, absoluteFill } from './utils';
import {
size,
shadow,
typography,
flexCenter,
absoluteFill,
remFunction,
} from './utils';

const media = {
// You can provide boolean values for breakpoints when you just need to
Expand Down Expand Up @@ -172,6 +179,23 @@ const { styled, css, createTheme, config, theme, useTheme, ThemeProvider } =
typography,
flexCenter,
absoluteFill,
fontSizeRem: remFunction('fontSize'),
widthRem: remFunction('width'),
heightRem: remFunction('height'),
lineHeightRem: remFunction('lineHeight'),
minWidthRem: remFunction('minWidth'),
minHeightRem: remFunction('minHeight'),
maxWidthRem: remFunction('maxWidth'),
maxHeightRem: remFunction('maxHeight'),
marginRightRem: remFunction('marginRight'),
marginLeftRem: remFunction('marginLeft'),
marginTopRem: remFunction('marginTop'),
marginBottomRem: remFunction('marginBottom'),
paddingRightRem: remFunction('paddingRight'),
paddingLeftRem: remFunction('paddingLeft'),
paddingTopRem: remFunction('paddingTop'),
paddingBottomRem: remFunction('paddingBottom'),
borderRadiusRem: remFunction('borderRadius'),
},
media,
});
Expand Down
67 changes: 67 additions & 0 deletions example/src/styles/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,70 @@ export const flexCenter = (
export const absoluteFill = () => ({
...StyleSheet.absoluteFillObject,
});

export const generateSameMediaProperty = <
Property extends keyof CSSProperties,
Value
>(
property: Property,
value: Value
) => {
return {
'@xl': {
[property]: value,
},
'@lg': {
[property]: value,
},
'@md': {
[property]: value,
},
'@sm': {
[property]: value,
},
'@xsm': {
[property]: value,
},
'@xxsm': {
[property]: value,
},
};
};

const fontSizes = {
xxs: 10,
xs: 14,
sm: 16,
md: 18,
lg: 20,
xl: 24,
xxl: 32,
};

export const remFunction =
<Property extends keyof CSSProperties>(property: Property) =>
(rValue: number) => {
return {
'@xxl': {
[property]: fontSizes.xxl * rValue,
},
'@xl': {
[property]: fontSizes.xl * rValue,
},
'@lg': {
[property]: fontSizes.lg * rValue,
},
'@md': {
[property]: fontSizes.md * rValue,
},
'@sm': {
[property]: fontSizes.sm * rValue,
},
'@xs': {
[property]: fontSizes.xs * rValue,
},
'@xxs': {
[property]: fontSizes.xs * rValue,
},
} as Record<`@${keyof typeof fontSizes}`, CSSProperties>;
};
14 changes: 14 additions & 0 deletions example/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const createExpoWebpackConfigAsync = require('@expo/webpack-config');
const path = require('path');
// Expo CLI will await this method so you can optionally return a promise.
module.exports = async function (env, argv) {
const config = await createExpoWebpackConfigAsync(env, argv);
// If you want to add a new alias to the config.
Object.assign(config.resolve.alias, {
react: path.join(__dirname, 'node_modules', 'react'),
'react-native': path.join(__dirname, 'node_modules', 'react-native-web'),
'react-native-web': path.join(__dirname, 'node_modules', 'react-native-web'), // prettier-ignore
});
return config;
};
Loading