Comments (12)
I also had issues figuring out a way to make my own button.
What I had to do for my button label to match the button variant style (for example, I want the primary button to be blue and the text white) is to have the same variant name in both components. You could define your button properties as following:
type Props = VariantProps<Theme, "buttonVariants"> & {
label: string;
onPress?: () => void;
};
So, for example, you can create a ButtonContainer component,
const ButtonContainer = createRestyleComponent<
VariantProps<Theme, "buttonVariants"> & React.ComponentProps<typeof Box>,
Theme
>([createVariant({ themeKey: "buttonVariants" })], Box);
and use it in your Button
component
<ButtonContainer variant={variant}> <Text variant={variant}>{label}</Text></ButtonContainer>
Instead of just passing the VariantProps
you could also pass your ButtonContainer props, to be more flexible
So at the end you could have:
type Props = React.ComponentProps<typeof ButtonContainer> & {
label: string;
onPress?: () => void;
};
const Button = ({ label, variant, onPress, ...rest }: Props) => (
<ButtonContainer variant={variant} {...rest}>
<Touchableopacity onPress={onPress}>
<Text variant={variant}>
{label}
</Text>
</Touchableopacity>
</ButtonContainer>
)
The only downside i see is having to manually maintain the same variant names in both a Button container (just a box with variants) and the Text component, but it works...
There might be some coding mistakes since, but that's the idea
Hope this helps someone looking for a way to define a button component
from restyle.
Here is how I fix the TS issue
<Text
variant="itemTitle"
fontSize={theme.buttonVariants[variant as keyof Theme['buttonVariants']].fontSize}
color={theme.buttonVariants[variant as keyof Theme['buttonVariants']].color as keyof Theme['colors']}>
{children}
</Text>
from restyle.
There's unfortunately no good way to do this right now, but I'll keep this shortcoming in mind and see if we can solve this in a nice way in future versions.
from restyle.
Okay thank you!
from restyle.
@Charly6596 can you please add your theme, I have the same problem, having hard time understanding how did you define your variants
from restyle.
@minawalphonce sure thing, here's a simplified version of my theme
const theme = createTheme({
colors: {
buttonPrimary: palette.blue,
buttonPrimaryForeground: palette.white,
buttonSecondary: palette.white,
buttonSecondaryForeground: palette.darkBlue,
},
spacing: {}, // omitted
breakpoints: {}, // omitted
textVariants: {
buttonPrimary: {
color: "buttonPrimaryForeground",
fontSize: 16,
},
buttonSecondary: {
color: "buttonSecondaryForeground",
fontSize: 16,
},
},
buttonVariants: {
buttonPrimary: {
backgroundColor: "buttonPrimary",
padding: "m",
},
buttonSecondary: {
backgroundColor: "buttonSecondary",
padding: "m",
},
},
});
from restyle.
The ability to define styles for subcomponents when using variants would be a great addition to the library.
Not being able to do so feels limitating when trying to build component like : <Message variant="error">Something went wrong</Message>
, that renders a Box
and a Text
under the hood in the appropriate styles.
These kind of components, where you don't have to thing too much about the moving parts, are a good practice (IMO), resulting in a low overhead for developers when building screens, and overall more consistent styles.
@Charly6596 workaround works but it breaks the colocation of styles, which sounds like hard to maintain in the long run with hundreds of components.
from restyle.
I had this problem too and solved it by accessing the variant prop from useTheme
like so:
import {
SpacingProps,
createRestyleComponent,
VariantProps,
createVariant,
useTheme,
spacing,
} from "@shopify/restyle";
import React from "react";
import { TouchableOpacity } from "react-native";
import { Text } from "./Text";
import { Theme } from "./theme";
export const BaseButton = createRestyleComponent<
VariantProps<Theme, "buttonVariants"> &
SpacingProps<Theme> &
React.ComponentProps<typeof TouchableOpacity>,
Theme
>([createVariant({ themeKey: "buttonVariants" }), spacing], TouchableOpacity);
type ButtonProps = React.ComponentProps<typeof BaseButton> & {
label: string;
};
export const Button = ({ label, ...rest }: ButtonProps) => {
const theme = useTheme<Theme>();
return (
<BaseButton {...rest}>
<Text
variant="buttonLabel"
color={theme.buttonVariants[rest.variant].color}
>
{label}
</Text>
</BaseButton>
);
};
Theme:
export const theme = createTheme({
...
buttonVariants: {
primary: {
backgroundColor: "primary",
borderColor: "primary",
color: "white",
},
outlined: {
borderColor: "primary",
color: "secondary",
},
},
...
That buttonVariants[rest.variant]
still throws a TS error about index types that I'm not sure how to fix though.
from restyle.
That
buttonVariants[rest.variant]
still throws a TS error about index types that I'm not sure how to fix though.
@vonkanehoffen
Have you tried to force with type with as
like
// not sure if it will work but something like that 😅
color={theme.buttonVariants[rest.variant].color as ColorProps<Theme>}
from restyle.
That
buttonVariants[rest.variant]
still throws a TS error about index types that I'm not sure how to fix though.@vonkanehoffen Have you tried to force with type with
as
like// not sure if it will work but something like that 😅 color={theme.buttonVariants[rest.variant].color as ColorProps<Theme>}
Even if we add as there is a typescript issue with color
Type 'ColorProps<{ breakpoints: { phone: number; tablet: number; desktop: number; }; spacing: { none: number; '3xs': number; xxs: number; xs: number; s: number; m: number; l: number; xl: number; xxl: number; '3xl': number; '4xl': number; '6xl': number; '8xl': number; }; ... 5 more ...; buttonVariants: { ...; }; }>' is not assignable to type 'ResponsiveValue<"dark" | "primaryLow" | "primary" | "primaryHigh" | "primaryTransparent" | "blue" | "green" | "orange" | "orangeLow" | "red" | "red2" | "red3" | "purple" | "redLow" | "yellow" | ... 26 more ... | "shadowEnd", { ...; }> | undefined'.
I have tried with another property (fontSize) and it works fine with it. It seems to be specific to color
from restyle.
Here is how I fix the TS issue
<Text variant="itemTitle" fontSize={theme.buttonVariants[variant as keyof Theme['buttonVariants']].fontSize} color={theme.buttonVariants[variant as keyof Theme['buttonVariants']].color as keyof Theme['colors']}> {children} </Text>
I had some trouble with the fontWeight
prop and solved like this:
fontWeight={
theme.buttonVariants[variant as keyof Theme['buttonVariants']]
.fontWeight as keyof TypographyProps<Theme>['fontWeight']
}
from restyle.
what do you think ?
from restyle.
Related Issues (20)
- Turning theme into regular values
- Meta: Turn on GitHub Discussions for repository HOT 1
- Let Text component support flex prop HOT 1
- React.Children.only expected to receive a single React element child.
- Export useDimensions hook? HOT 4
- Is this Library abandoned? HOT 5
- using createVariant throws: undefined is not a function HOT 1
- Flex gap support RN 0.71.X
- How to wrap KeyboardAvoidingView in Box? HOT 1
- Breaking Change in update from 2.1.0 to 2.2.0/2.3.0?
- Custom themed components are losing spacing props after upgrade from 2.3.0 to 2.4.0 HOT 4
- TS error when attempting to create multiple variants with different keys in the theme object HOT 4
- TS error: When I use position restyleFunctions HOT 5
- React Native 0.72 support HOT 2
- Theming is not working as expected HOT 1
- Error: Value '#0F0E0F' does not exist in theme['colors']
- undefined is not a function [buildStyle(@shopify/restyle/dist/composeRestyleFunctions)] HOT 1
- error in composeRestyleFunctions HOT 2
- composeRestyleFunctions not accepting `border` HOT 1
- Cannot make custom component HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from restyle.