You are looking at the documentation of the work in progress Hope UI 1.0, examples and information may be broken or outdated.

Styles

Styled components

Create custom components with multi-variant style support.

Import

tsx
import { hope } from "@hope-ui/core";
tsx
import { hope } from "@hope-ui/core";

Usage

You can create so-called "styled components" by passing a style configuration as the second argument of the hope() factory function. This uses an API inspired by Vanilla Extract Recipes.

Base style

Let's say you want to create a custom Button component. First, define the base style of the component which will always be applied.

You can use theme tokens, shorthand properties, and responsive syntax to define this style.

jsx
const StyledButton = hope("button", {
baseStyle: {
appearance: "none",
position: "relative",
display: "inline-flex",
justifyContent: "center",
alignItems: "center",
border: "1px solid transparent",
borderRadius: "md",
fontFamily: "inherit",
fontSize: "100%",
fontWeight: "medium",
lineHeight: "none",
},
});
jsx
const StyledButton = hope("button", {
baseStyle: {
appearance: "none",
position: "relative",
display: "inline-flex",
justifyContent: "center",
alignItems: "center",
border: "1px solid transparent",
borderRadius: "md",
fontFamily: "inherit",
fontSize: "100%",
fontWeight: "medium",
lineHeight: "none",
},
});

Variants

Styled components don't use prop interpolation to define conditional style. Instead, it uses the concept of Variants, popularized by Stitches.

Under the hood, Hope UI will convert all variants to component props and apply the related style when the props are passed.

To define variants, use the variants keyword:

jsx
const StyledButton = hope("button", {
// ...baseStyle
variants: {
variant: {
solid: {
// style when the `variant="solid"` prop is passed
},
outlined: {},
plain: {},
},
colorScheme: {
primary: {
// style when the `colorScheme="primary"` prop is passed
},
danger: {},
neutral: {},
},
size: {
sm: {
// style when the `size="sm"` prop is passed
},
md: {},
lg: {},
},
isFullWidth: {
true: {
// style when the `isFullWidth={true}` prop is passed
},
false: {},
},
},
});
jsx
const StyledButton = hope("button", {
// ...baseStyle
variants: {
variant: {
solid: {
// style when the `variant="solid"` prop is passed
},
outlined: {},
plain: {},
},
colorScheme: {
primary: {
// style when the `colorScheme="primary"` prop is passed
},
danger: {},
neutral: {},
},
size: {
sm: {
// style when the `size="sm"` prop is passed
},
md: {},
lg: {},
},
isFullWidth: {
true: {
// style when the `isFullWidth={true}` prop is passed
},
false: {},
},
},
});

If you don't have the style for a variant, you still need to define it with an empty object as value (like above) to make it available in the corresponding prop.

With the example above, the resulting component props type will look like this:

tsx
interface StyledButtonProps {
variant?: "solid" | "outlined" | "plain";
colorScheme?: "primary" | "danger" | "neutral";
size?: "sm" | "md" | "lg";
isFullWidth?: boolean;
}
tsx
interface StyledButtonProps {
variant?: "solid" | "outlined" | "plain";
colorScheme?: "primary" | "danger" | "neutral";
size?: "sm" | "md" | "lg";
isFullWidth?: boolean;
}
true/false variants become a prop with boolean type.

Compound variants

In the case of needing to set styles based on a combination of variants, you can use the compoundVariants keyword.

jsx
const StyledButton = hope("button", {
// ...baseStyle and variants
compoundVariants: [
{
variants: {
variant: "solid",
colorScheme: "primary",
},
style: {
// style when both `variant="solid"` and `colorScheme="primary"` props are passed
},
},
],
});
jsx
const StyledButton = hope("button", {
// ...baseStyle and variants
compoundVariants: [
{
variants: {
variant: "solid",
colorScheme: "primary",
},
style: {
// style when both `variant="solid"` and `colorScheme="primary"` props are passed
},
},
],
});

Default variants

You can use the defaultVariants keyword to set a variant by default. Think of it as the default component props.

jsx
const StyledButton = hope("button", {
// ...baseStyle, variants and compoundVariants
defaultVariants: {
variant: "solid",
colorScheme: "primary",
size: "md",
},
});
jsx
const StyledButton = hope("button", {
// ...baseStyle, variants and compoundVariants
defaultVariants: {
variant: "solid",
colorScheme: "primary",
size: "md",
},
});

Using style props, sx and the as prop

Like other Hope UI components, styled components support style props, sx and the as prop to change the rendered element.

jsx
<StyledButton as="a" href="#" mt={4}>
Back to home
</StyledButton>
jsx
<StyledButton as="a" href="#" mt={4}>
Back to home
</StyledButton>

Accessing the theme object

hope() can accept a function as parameter, which gives you access to the current theme.

jsx
const StyledButton = hope("button", theme => ({
baseStyle: {
border: `1px solid ${theme.vars.colors.neutral["300"]}`,
},
// ...variants, compoundVariants and defaultVariants
}));
jsx
const StyledButton = hope("button", theme => ({
baseStyle: {
border: `1px solid ${theme.vars.colors.neutral["300"]}`,
},
// ...variants, compoundVariants and defaultVariants
}));
Previous
Hope factory