# Styled System

> This section explains the structure of the styled system, detailing its components and illustrating how they integrate with design tokens.

## Introduction

All components are designed to be styled using props.

Hopper embraces a **Styled System-inspired** approach to styling components, allowing developers to define styles directly via props rather than writing CSS. This method provides a **type-safe and intuitive API**, making it easier to build consistent, on-brand interfaces without dealing with complex class names or global styles. With built-in **intellisense and static analysis**, developers can confidently apply design tokens without memorizing them, ensuring efficiency and reducing errors.

### Style Props

Style props are the most fundamental way to style your components in Hopper. They are basically css styles as props. [Learn more about style props](/styled-system/concepts/styling.md)

### Do's and Don'ts

These guidelines help ensure consistency, maintainability, and design system compliance when using the styled system.

**Rule 1**

* ✅ Do:

  ```tsx
  import { Stack } from "@hopper-ui/components";

  <Stack gap="inline-lg" />;
  ```

  Use styled system props to apply design tokens directly to components

* 🚫 Don't:

  ```tsx
  import { Stack } from "@hopper-ui/components";

  <Stack style={{ gap: "24px" }} />;
  ```

  Use the standard React 'style' prop

**Rule 2**

* ✅ Do:

  Use styled system props to apply design tokens directly to components

* 🚫 Don't:

  Use external CSS files or CSS-in-JS solutions alongside styled system components

**Rule 3**

* ✅ Do:

  ```tsx
  import { Stack } from "@hopper-ui/components";

  <Stack UNSAFE_width="100px" />;
  ```

  Use the UNSAFE\_ prefix when you use a value that is not a token

* 🚫 Don't:

  ```tsx
  import { Stack } from "@hopper-ui/components";

  <Stack style={{ width: "100px" }} />;
  ```

  Use the standard React style prop

### Key Concepts

Follow these links to learn key concepts about the Styled System:

* [Responsive Styles](/styled-system/concepts/responsive-styles.md)
* [Using Style Props on HTML Elements](/styled-system/concepts/html-elements.md)
* [Using Style Props on custom components](/styled-system/concepts/custom-components.md)

## Style Props

This page describes how styling works in Hopper, including how to customize spacing, sizing, and positioning, and how to create your own custom components using Hopper styles.

Hopper components are designed to be consistent across all Workleap applications. They include built-in styling that has been considered carefully, and extensively tested. In general, customizing Hopper is discouraged, but most components do offer control over layout and other aspects. In addition, you can use Hopper's tokens to ensure your application conforms to design requirements, and is adaptive across color schemes.

### Style props

A Hopper style property is a mapping of a CSS property to a component property. With style props, Hopper let you easily set style values for a curated set of CSS properties like font-size, margin, padding, width and many more.

All of the available style props are listed in the ["Properties List"](#properties-list) section below.

#### Usage

To use a style prop on a Hopper component, pass the prop as a camelCased string to the component. By default, only tokens are accepted as values for style props. They help promote consistency and maintainability across your application.

If you need to pass a custom value, you can use the `UNSAFE_` prefix to bypass the token system. You can refer to the ["Escape hatches"](#escape-hatches) section for more information.

```tsx
import { Div } from "@hopper-ui/components";

export default function Example() {
    return (
        <Div
            fontSize="body-lg"
            fontWeight="body-lg"
            paddingTop="inset-md"
            paddingBottom="inset-md"
            marginBottom="stack-lg"
            color="neutral"
            borderRadius="rounded-md"
            backgroundColor="primary"
        >
            Style properties are fun.
        </Div>
    );
}
```

#### Shorthands

Props like border and paddingX are also provided to help you save keystrokes. An exhaustive list of all the supported props is available in the ["Properties List"](#properties-list) section.

```tsx
import { Div } from "@hopper-ui/components";

export default function Example() {
    return (
        <Div paddingY="inset-md" border="primary">
            Shorthands.
        </Div>
    );
}
```

#### Responsive styles

All style props support responsive values. You can pass an object with breakpoints as keys and values as values to a style prop to set different values for different breakpoints. More information is available in the [Responsive Styles article](./responsive-styles.md).

#### Escape hatches

**CRITICAL: NOT ALL PROPS SUPPORT THE `UNSAFE_` PREFIX.** Only a specific set of props (listed in the [escape-hatches guide](/styled-system/escape-hatches.md)) have `UNSAFE_` versions available.

For these whitelisted props, you can bypass the token system by prefixing the prop name with `UNSAFE_`:

```tsx
  <Div
      position="absolute"           // ✅ position is NOT in the whitelist, use position directly
      top="10px"                    // ✅ top is NOT in the whitelist, use top directly
      top="core_640"                // ❌ Do NOT use tokens for top
      overflow="hidden"             // ✅ overflow is NOT in the whitelist, use overflow directly
      flex="1"                      // ✅ flex is NOT in the whitelist, use flex directly
      UNSAFE_fontSize="1.5rem"      // ✅ fontSize is in the whitelist
      UNSAFE_width="100px"          // ✅ width is in the whitelist
  >
```

Critical Rules:

1. Check the [escape-hatches guide](/styled-system/escape-hatches.md) FIRST - it contains the complete whitelist.
2. If a prop is in the whitelist → use UNSAFE\_propName for custom values
3. If a prop is not in the whitelist:

* Use propName directly (no `UNSAFE_` prefix)
* NEVER use tokens for it (`top="core_640"` or `left="core_0"` are invalid)

5. Props with "Tokens Category" of "none" (like `overflow`, `flex`, `position`) are used directly

While we encourage teams to utilize Hopper styles as it is, we do realize that sometimes product specific customizations may be needed. In these cases, we encourage you or your designers to talk to us. We may be able to suggest an alternative implementation strategy, or perhaps your design can help inform future Hopper additions.

While the traditional className and style props are always supported in Hopper components, we also provide an escape hatch for passing custom values to style props. This is done by prefixing the prop name with `UNSAFE_`.

The `UNSAFE_` prefix might look scary, but it's there to remind you that you're bypassing the token system. It's a way to ensure that you're aware that you're doing something that might not be automatically updated when tokens change. It will also help you to search for these usages when you want to update them, or help us to provide missing tokens.

```tsx
import { Div } from "@hopper-ui/components";

export default function Example() {
    return (
        <Div
            UNSAFE_fontSize="1.5rem"
            UNSAFE_fontWeight="500"
            UNSAFE_paddingTop="14px"
            UNSAFE_paddingBottom="15rem"
            UNSAFE_marginBottom="12px"
            UNSAFE_color="#FFFFFF"
            UNSAFE_borderRadius="12px"
            UNSAFE_backgroundColor="#000000"
        >
            Style properties are fun.
        </Div>
    );
}
```

#### Pseudo-classes

Style props doesn't support every CSS pseudo-classes. [Location pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes#location_pseudo-classes), [input pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes#the_input_pseudo-classes), [tree-structural pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes#tree-structural_pseudo-classes), ::before and ::after are not supported and will most likely never be.

When a CSS pseudo-class is not supported by Hopper style props, we recommend using a CSS class.

Since the following user action pseudo-classes are often used, some style props support them. These behaves like their pseudo CSS counterparts.

| Suffix | Pseudo state |
| ------ | ------------ |
| active | :active      |
| hover  | :hover       |
| focus  | :focus       |

Not all style props support user action pseudo-classes. Find out which props support user action pseudo-classes in the ["Properties List"](#properties-list) section.

### Properties List

The following tables provide a list of all available style props by category.

#### Space

```tsx
<Div padding="inset-md">
    Hopper
</Div>
```

| Property Name | CSS Property                 | Tokens Category                                                       | UNSAFE\_ | Supports    |
| ------------- | ---------------------------- | --------------------------------------------------------------------- | -------- | ----------- |
| margin        | margin                       | [Semantic > Spacing > Margin](/tokens/semantic/space.md#tokens-margin)   | ✓        | breakpoints |
| marginTop     | margin-top                   | [Semantic > Spacing > Margin](/tokens/semantic/space.md#tokens-margin)   | ✓        | breakpoints |
| marginBottom  | margin-bottom                | [Semantic > Spacing > Margin](/tokens/semantic/space.md#tokens-margin)   | ✓        | breakpoints |
| marginRight   | margin-right                 | [Semantic > Spacing > Margin](/tokens/semantic/space.md#tokens-margin)   | ✓        | breakpoints |
| marginLeft    | margin-left                  | [Semantic > Spacing > Margin](/tokens/semantic/space.md#tokens-margin)   | ✓        | breakpoints |
| marginX       | margin-left & margin-right   | [Semantic > Spacing > Margin](/tokens/semantic/space.md#tokens-margin)   | ✓        | breakpoints |
| marginY       | margin-top & margin-bottom   | [Semantic > Spacing > Margin](/tokens/semantic/space.md#tokens-margin)   | ✓        | breakpoints |
| padding       | padding                      | [Semantic > Spacing > Padding](/tokens/semantic/space.md#tokens-padding) | ✓        | breakpoints |
| paddingTop    | padding-top                  | [Semantic > Spacing > Padding](/tokens/semantic/space.md#tokens-padding) | ✓        | breakpoints |
| paddingBottom | padding-bottom               | [Semantic > Spacing > Padding](/tokens/semantic/space.md#tokens-padding) | ✓        | breakpoints |
| paddingRight  | padding-right                | [Semantic > Spacing > Padding](/tokens/semantic/space.md#tokens-padding) | ✓        | breakpoints |
| paddingLeft   | padding-left                 | [Semantic > Spacing > Padding](/tokens/semantic/space.md#tokens-padding) | ✓        | breakpoints |
| paddingX      | padding-left & padding-right | [Semantic > Spacing > Padding](/tokens/semantic/space.md#tokens-padding) | ✓        | breakpoints |
| paddingY      | padding-top & padding-bottom | [Semantic > Spacing > Padding](/tokens/semantic/space.md#tokens-padding) | ✓        | breakpoints |
| whiteSpace    | white-space                  | none                                                                  | ✗        | breakpoints |

#### Color

```tsx
<Div backgroundColor="primary-weak" color="neutral">
    Hopper
</Div>
```

| Property Name   | CSS Property     | Tokens Category                             | UNSAFE\_ | Supports                         |
| --------------- | ---------------- | ------------------------------------------- | -------- | -------------------------------- |
| color           | color            | [Semantic > Colors](/tokens/semantic/color.md) | ✓        | breakpoints & focus/hover/active |
| backgroundColor | background-color | [Semantic > Colors](/tokens/semantic/color.md) | ✓        | breakpoints & focus/hover/active |
| opacity         | opacity          | none                                        | ✗        | breakpoints & focus/hover/active |
| fill            | fill             | [Semantic > Colors](/tokens/semantic/color.md) | ✓        | breakpoints & focus/hover        |
| stroke          | stroke           | [Semantic > Colors](/tokens/semantic/color.md) | ✓        | breakpoints                      |
| filter          | filter           | none                                        | ✗        | breakpoints                      |

#### Typography

```tsx
<Header letterSpacing="0.3rem">Hopper</Header>
```

| Property Name  | CSS Property    | Tokens Category                                      | UNSAFE\_ | Supports    |
| -------------- | --------------- | ---------------------------------------------------- | -------- | ----------- |
| fontFamily     | font-family     | [Semantic > Typography](/tokens/semantic/typography.md) | ✓        | breakpoints |
| fontSize       | font-size       | [Semantic > Typography](/tokens/semantic/typography.md) | ✓        | breakpoints |
| fontWeight     | font-weight     | [Semantic > Typography](/tokens/semantic/typography.md) | ✓        | breakpoints |
| lineHeight     | line-height     | [Semantic > Typography](/tokens/semantic/typography.md) | ✓        | breakpoints |
| letterSpacing  | letter-spacing  | [Core > Letter Spacing](/tokens/core/letter-spacing.md) | ✓        | breakpoints |
| textAlign      | text-align      | none                                                 | ✗        | breakpoints |
| textTransform  | text-transform  | none                                                 | ✗        | breakpoints |
| textDecoration | text-decoration | none                                                 | ✗        | breakpoints |
| textOverflow   | text-overflow   | none                                                 | ✗        | breakpoints |
| wordBreak      | word-break      | none                                                 | ✗        | breakpoints |
| fontStyle      | font-style      | none                                                 | ✗        | breakpoints |

#### Layout

```tsx
<Div UNSAFE_width="30rem">
    Hopper
</Div>
```

| Property Name     | CSS Property       | Tokens Category                                                     | UNSAFE\_ | Supports    |
| ----------------- | ------------------ | ------------------------------------------------------------------- | -------- | ----------- |
| width             | width              | [Core > Dimensions](/tokens/core/dimensions.md)                        | ✓        | breakpoints |
| height            | height             | [Core > Dimensions](/tokens/core/dimensions.md)                        | ✓        | breakpoints |
| minWidth          | min-width          | [Core > Dimensions](/tokens/core/dimensions.md)                        | ✓        | breakpoints |
| maxWidth          | max-width          | [Core > Dimensions](/tokens/core/dimensions.md)                        | ✓        | breakpoints |
| minHeight         | min-height         | [Core > Dimensions](/tokens/core/dimensions.md)                        | ✓        | breakpoints |
| maxHeight         | max-height         | [Core > Dimensions](/tokens/core/dimensions.md)                        | ✓        | breakpoints |
| display           | display            | none                                                                | ✗        | breakpoints |
| verticalAlign     | vertical-align     | none                                                                | ✗        | breakpoints |
| overflow          | overflow           | none                                                                | ✗        | breakpoints |
| overflowX         | overflow-x         | none                                                                | ✗        | breakpoints |
| overflowY         | overflow-y         | none                                                                | ✗        | breakpoints |
| gap               | gap                | [Semantic > Spacing > Margin](/tokens/semantic/space.md#tokens-margin) | ✓        | breakpoints |
| alignSelf         | align-self         | none                                                                | ✗        | breakpoints |
| aspectRatio       | aspect-ratio       | none                                                                | ✗        | breakpoints |
| justifyContent    | justify-content    | none                                                                | ✗        | breakpoints |
| justifyItems      | justify-items      | none                                                                | ✗        | breakpoints |
| justifySelf       | justify-self       | none                                                                | ✗        | breakpoints |
| contentVisibility | content-visibility | none                                                                | ✗        | breakpoints |
| transform         | transform          | none                                                                | ✗        | breakpoints |
| transformOrigin   | transform-origin   | none                                                                | ✗        | breakpoints |
| transformStyle    | transform-style    | none                                                                | ✗        | breakpoints |

#### Flex Layout

```tsx
<Div alignItems="center">
    <Text>Tree frog</Text>
    <Text>Pond frog</Text>
</Div>
```

| Property Name | CSS Property     | Tokens Category | UNSAFE\_ | Supports    |
| ------------- | ---------------- | --------------- | -------- | ----------- |
| alignItems    | align-items      | none            | ✗        | breakpoints |
| alignContent  | align-content    | none            | ✗        | breakpoints |
| flex          | flex (shorthand) | none            | ✗        | breakpoints |
| flexBasis     | flex-basis       | none            | ✗        | breakpoints |
| flexDirection | flex-direction   | none            | ✗        | breakpoints |
| flexFlow      | flex-flow        | none            | ✗        | breakpoints |
| flexGrow      | flex-grow        | none            | ✗        | breakpoints |
| flexShrink    | flex-shrink      | none            | ✗        | breakpoints |
| flexWrap      | flex-wrap        | none            | ✗        | breakpoints |
| order         | order            | none            | ✗        | breakpoints |

#### Grid Layout

```tsx
<Div gridAutoFlow="row dense">
    <Text>Tree frog</Text>
    <Text>Pond frog</Text>
</Div>
```

| Property Name       | CSS Property          | Tokens Category                                                     | UNSAFE\_ | Supports    |
| ------------------- | --------------------- | ------------------------------------------------------------------- | -------- | ----------- |
| grid                | grid (shorthand)      | none                                                                | ✗        | breakpoints |
| gridArea            | grid-area             | none                                                                | ✗        | breakpoints |
| gridAutoColumns     | grid-auto-columns     | [Core > Dimensions](/tokens/core/dimensions.md)                        | ✓        | breakpoints |
| gridAutoFlow        | grid-auto-flow        | none                                                                | ✗        | breakpoints |
| gridAutoRows        | grid-auto-rows        | [Core > Dimensions](/tokens/core/dimensions.md)                        | ✓        | breakpoints |
| gridColumn          | grid-column           | none                                                                | ✗        | breakpoints |
| gridColumnEnd       | grid-column-end       | none                                                                | ✗        | breakpoints |
| gridColumnSpan      | grid-column-span      | none                                                                | ✗        | breakpoints |
| gridColumnStart     | grid-column-start     | none                                                                | ✗        | breakpoints |
| gridRow             | grid-row              | none                                                                | ✗        | breakpoints |
| gridRowEnd          | grid-row-end          | none                                                                | ✗        | breakpoints |
| gridRowSpan         | grid-row-span         | none                                                                | ✗        | breakpoints |
| gridRowStart        | grid-row-start        | none                                                                | ✗        | breakpoints |
| gridTemplate        | grid-template         | none                                                                | ✗        | breakpoints |
| gridTemplateAreas   | grid-template-areas   | none                                                                | ✗        | breakpoints |
| gridTemplateColumns | grid-template-columns | [Core > Dimensions](/tokens/core/dimensions.md)                        | ✓        | breakpoints |
| gridTemplateRows    | grid-template-rows    | [Core > Dimensions](/tokens/core/dimensions.md)                        | ✓        | breakpoints |
| columnGap           | column-gap            | [Semantic > Spacing > Margin](/tokens/semantic/space.md#tokens-margin) | ✓        | breakpoints |
| rowGap              | row-gap               | [Semantic > Spacing > Margin](/tokens/semantic/space.md#tokens-margin) | ✓        | breakpoints |

#### Background

```tsx
<Div
  backgroundImage="url('/images/dog.png')"
  backgroundPosition="center"
  backgroundRepeat="no-repeat"
/>
```

| Property Name      | CSS Property        | Tokens Category | UNSAFE\_ | Supports    |
| ------------------ | ------------------- | --------------- | -------- | ----------- |
| backgroundImage    | background-image    | none            | ✗        | breakpoints |
| backgroundPosition | background-position | none            | ✗        | breakpoints |
| backgroundRepeat   | background-repeat   | none            | ✗        | breakpoints |
| backgroundSize     | background-size     | none            | ✗        | breakpoints |

#### Border

```tsx
<Div
    border="primary"
    borderRadius="rounded-md"
>
    Tree frog
</Div>
```

Border props (border, borderBottom, borderTop, borderRight, borderLeft) uses an implicit style (solid) and width(1px). These properties only accepts colors for value.

| Property Name           | CSS Property               | Tokens Category                             | UNSAFE\_ | Supports                         |
| ----------------------- | -------------------------- | ------------------------------------------- | -------- | -------------------------------- |
| border                  | border-color               | [Semantic > Colors](/tokens/semantic/color.md) | ✓        | breakpoints & focus/hover/active |
| borderBottom            | border-bottom-color        | [Semantic > Colors](/tokens/semantic/color.md) | ✓        | breakpoints & focus/hover/active |
| borderTop               | border-top-color           | [Semantic > Colors](/tokens/semantic/color.md) | ✓        | breakpoints & focus/hover/active |
| borderLeft              | border-left-color          | [Semantic > Colors](/tokens/semantic/color.md) | ✓        | breakpoints & focus/hover/active |
| borderRight             | border-right-color         | [Semantic > Colors](/tokens/semantic/color.md) | ✓        | breakpoints & focus/hover/active |
| borderRadius            | border-radius              | [Semantic > Shape](/tokens/semantic/shape.md)  | ✓        | breakpoints                      |
| borderTopLeftRadius     | border-top-left-radius     | [Semantic > Shape](/tokens/semantic/shape.md)  | ✓        | breakpoints                      |
| borderTopRightRadius    | border-top-right-radius    | [Semantic > Shape](/tokens/semantic/shape.md)  | ✓        | breakpoints                      |
| borderBottomLeftRadius  | border-bottom-left-radius  | [Semantic > Shape](/tokens/semantic/shape.md)  | ✓        | breakpoints                      |
| borderBottomRightRadius | border-bottom-right-radius | [Semantic > Shape](/tokens/semantic/shape.md)  | ✓        | breakpoints                      |
| outline                 | outline                    | [Semantic > Colors](/tokens/semantic/color.md) | ✓        | breakpoints & focus              |

#### Position

```tsx
<Div
    top="12px"
    position="absolute"
/>
```

| Property Name  | CSS Property    | Tokens Category | UNSAFE\_ | Supports    |
| -------------- | --------------- | --------------- | -------- | ----------- |
| position       | position        | none            | ✗        | breakpoints |
| top            | top             | none            | ✗        | breakpoints |
| bottom         | bottom          | none            | ✗        | breakpoints |
| right          | right           | none            | ✗        | breakpoints |
| left           | left            | none            | ✗        | breakpoints |
| zIndex         | z-index         | none            | ✗        | breakpoints |
| objectFit      | object-fit      | none            | ✗        | breakpoints |
| objectPosition | object-position | none            | ✗        | breakpoints |

#### Shadow

```tsx
<Div
    boxShadow="lifted"
/>
```

| Property Name | CSS Property | Tokens Category                                    | UNSAFE\_ | Supports                         |
| ------------- | ------------ | -------------------------------------------------- | -------- | -------------------------------- |
| boxShadow     | box-shadow   | [Semantic > Elevation](/tokens/semantic/elevation.md) | ✓        | breakpoints & focus/hover/active |

#### Miscellaneous

| Property Name | CSS Property   | Tokens Category | UNSAFE\_ | Supports           |
| ------------- | -------------- | --------------- | -------- | ------------------ |
| content       | content        | none            | ✗        | breakpoint         |
| cursor        | cursor         | none            | ✗        | breakpoint & hover |
| pointerEvents | pointer-events | none            | ✗        | breakpoint         |
| resize        | resize         | none            | ✗        | breakpoint         |
| willChange    | will-change    | none            | ✗        | breakpoint         |

## Responsive Styles

Hopper style props accept a specialized syntax to support responsive breakpoints. These responsive properties help build adaptive user interfaces.

### Introduction

In addition to static values, all style props support object syntax to specify different values for the prop depending on a responsive breakpoint. Breakpoints are named following t-shirt sizing, and correspond to common device resolutions.

#### Example

A `Div` with a default background color overridden at each breakpoint. Resize your browser window to see this in action.

```tsx
import { Div, Text } from "@hopper-ui/components";

export default function Example() {
    return (
        <Div
            backgroundColor={{
                base: "core_moss-200",
                xs: "core_sapphire-200",
                sm: "core_moss-200",
                md: "core_sapphire-200",
                lg: "core_rock-200",
                xl: "core_sunken-treasure-200"
            }}
            UNSAFE_width="30rem"
            maxWidth="100%"
            padding="inset-md"
        >
            <Text>Resize the window to see the background color change!</Text>
        </Div>
    );
}
```

### Breakpoints

In addition to the base, there are five breakpoints inspired by typical device resolutions.

| Name | Media query       |
| ---- | ----------------- |
| base | min-width: 0px    |
| xs   | min-width: 640px  |
| sm   | min-width: 768px  |
| md   | min-width: 1024px |
| lg   | min-width: 1280px |
| xl   | min-width: 1440px |

### Mobile-first

Hopper uses a mobile-first breakpoint system, similar to those in frameworks like Bootstrap and Tailwind.

> **error**Don't use `sm:` to target mobile devices

```tsx

import { Div, Text } from "@hopper-ui/components";

export default function Example() {
    return (
        <Div
            // This will only center text on screens 768px and wider, not on small screens
            backgroundColor="primary"
            textAlign={{ sm: "center" }}
            UNSAFE_width="30rem"
            maxWidth="100%"
            padding="inset-md"
        >
            <Text>Text Content</Text>
        </Div>
    );
}
```

> **success**Use `base` to target mobile devices

```tsx

import { Div, Text } from "@hopper-ui/components";

export default function Example() {
    return (
        <Div
            // This will center text on mobile, and left align it on screens 768px and wider
            backgroundColor="primary"
            textAlign={{ base: "center", sm: "left" }}
            UNSAFE_width="30rem"
            maxWidth="100%"
            padding="inset-md"
        >
            <Text>Text Content</Text>
        </Div>
    );
}
```

It's often best to start with the mobile first layout for a design, then add styles as the screen size increases, moving from small to larger screens.

### Utility Methods

#### useResponsiveValue

To resolve a responsive value within a React component, Hopper provides a `useResponsiveValue` hook.

```tsx

import { Div, useResponsiveValue } from "@hopper-ui/components";

export default function Example() {
    const isFluidValue = useResponsiveValue({ base: true, lg: false });

    return (
        <Div
            UNSAFE_width={isFluidValue ? "100%" : "30rem"}
            backgroundColor="core_moss-200"
            maxWidth="100%"
            padding="inset-md"
        >
            Content
        </Div>
    );
}
```

## HTML Elements

Using Hopper style props on HTML elements.

Hopper provides a set of HTML element components already configured with Hopper styled system. You should choose these components over native HTML elements.

`<A>`, `<Address>`, `<Article>`, `<Aside>`, `<HtmlButton>`, `<Div>`, `<HtmlFooter>`, `<HtmlHeader>`, `<Img>`, `<HtmlInput>`, `<List>`, `<Main>`, `<Nav>`, `<HtmlSection>`, `<Span>`, `<Table>`, `<THead>`, `<TBody>`, `<TFoot>`, `<TR>`, `<TD>`, `<TH>`, `<UL>`, `<OL>`, `<LI>`, `<HtmlLabel>`.

For text elements, prefer a `<Text>` or `<Paragraph>` component rather than `<Span>` or a `<Div>`.

### Create missing HTML elements

Hopper only re-export the most used HTML elements. If you need to use a less common HTML element, you can create a custom component using the `htmlElement` function.

```tsx
import { htmlElement } from "@hopper-ui/components";

const HtmlUnderline = htmlElement("u");
```

## Custom Components

Using Hopper style props on custom components.

Sometimes, you may find yourself needing to build a component that doesn't exist in Hopper, but this component would benefit from using Hopper's style props.

There are 2 ways to build a custom component with Hopper style properties, as seen below:

#### HTML Element

Instead of using a native HTML element to create your component, you can use one of the Hopper HTML Element components. This way, you can simply forward the style props to the component.

This is an example using a `Div`, but you can use any of the HTML Element components.

```tsx
import { Div, type DivProps } from "@hopper-ui/components";

interface MyCustomComponentProps extends Omit<DivProps, "children"> {
    // your custom props here
}

function MyCustomComponent(props: MyCustomComponentProps) {
    return (
        <Div {...props} >
            My Custom component
        </Div>
    );
}

export default function Example() {
    return (
        <MyCustomComponent
            paddingY="inset-md"
        />
    );
}
```

#### useStyledSystem

If you need to build a more complex component, you can use the `useStyledSystem` function. This function allows you to create a custom component with Hopper style props.

The `useStyledSystem` function returns a `stylingProps` object containing a resulting style object and a className. You can then spread the `stylingProps` object on your component, or merge them with your existing className and style properties.

We don't automatically merge the `className` and `style` props because most of the className and style props in Hopper also accept a function.

```tsx
import { useStyledSystem } from "@hopper-ui/components";
import type { StyledComponentProps } from "@hopper-ui/styled-system";
import { Button as RACButton, ButtonProps as RACButtonProps } from "react-aria-components";

interface MyCustomButtonProps extends StyledComponentProps<RACButtonProps> {
    // your custom props here
}

function MyCustomButton(props: MyCustomButtonProps) {
    const { stylingProps, children, className, style, ...otherProps } = useStyledSystem(props);

    // append or use "classnames" or "clsx" to merge classes
    const classNames = `${stylingProps.className ?? ""} ${className ?? ""}`;
    const mergedStyles = { ...stylingProps.style, ...style };

    return (
        <RACButton style={mergedStyles} className={classNames} {...otherProps}>
            {children}
        </RACButton>
    );
}

export default function Example() {
    return (
        <MyCustomButton
            paddingY="inset-md"
        >
            My Styled Button
        </MyCustomButton>
    );
}
```

