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", {// ...baseStylevariants: {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", {// ...baseStylevariants: {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;}
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 variantscompoundVariants: [{variants: {variant: "solid",colorScheme: "primary",},style: {// style when both `variant="solid"` and `colorScheme="primary"` props are passed},},],});
jsx
const StyledButton = hope("button", {// ...baseStyle and variantscompoundVariants: [{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 compoundVariantsdefaultVariants: {variant: "solid",colorScheme: "primary",size: "md",},});
jsx
const StyledButton = hope("button", {// ...baseStyle, variants and compoundVariantsdefaultVariants: {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}));