---
title: State based styling | gluestack-style
description: This allows you to create dynamic and interactive styles that change based on user interactions or other events.
---

import { Canvas, Meta, Story, Source } from '@storybook/addon-docs';

<Meta title="api/State Based Styles" />

import { styled, StyledProvider } from '@gluestack-style/react';
import { Pressable, Text } from 'react-native';
import { AppProvider, CodePreview } from '@gluestack/design-system';
import { config } from './config';
import { useState } from 'react';

# State Based Styles

This includes the ability to define styles based on the component's state. This allows you to create dynamic and interactive styles that change based on user interactions or other events.

The extended component accept a **`states`** prop, which is an object containing the state of the component. This prop can contain any number of state keys and values, for example **`{hover: true, active: true}`**. The library then uses this prop to apply the corresponding state styles to the component.

The **`states`** prop allows developers to easily control the state of the component and its styles. For example, it can be used to apply hover styles to a button when the mouse is over the button, or to apply active styles to a button when it is clicked. The library utilizes the **`states`** prop to look up the state styles in the global style map and apply them to the component.

It is important to note that the **`states`** prop is optional and will be used only if passed, otherwise the component will use the default styles.

Here is an example of using the **`states`** prop can be used:

<AppProvider>
  <CodePreview
    showArgsController={false}
    metaData={{
      scope: {
        styled,
        Text,
        Pressable,
        Provider: StyledProvider,
        config,
        useState,
      },
      code: `
          function Button() {
            const StyledButton = styled(Pressable, {
              'p': '$2',
              'borderRadius': '$md',
              'bg': '$blue500',
              ':hover': {
                bg: '$blue600',
              },
              ':active': {
                bg: '$blue700',
              },
            });
            const StyledButtonText = styled(
              Text,
              {
                color: '$textDark50',
              },
            );
            const [isHovered, setIsHovered] = useState(false);
            const [isActive, setIsActive] = useState(false);
            return (
              <Provider config={config}>
                <StyledButton
                  states={{ hover: isHovered, active: isActive }}
                  onMouseEnter={() => setIsHovered(true)}
                  onMouseLeave={() => setIsHovered(false)}
                  onMouseDown={() => setIsActive(true)}
                  onMouseUp={() => setIsActive(false)}
                >
                  <StyledButtonText>Click Me</StyledButtonText>
                </StyledButton>
              </Provider>
            );
          }
      `,
    }}
  />
</AppProvider>

In the example above, we create a functional **`Button`** component that wraps a **`StyledButton`** component, which is the component returned by the **`styled`** function. The **`Button`** component uses **`useState`** hooks to track whether the button is currently being hovered over or pressed (active). It then passes the current state to the **`StyledButton`** component via the **`states`** prop.

When the button is hovered over, the **`isHovered`** state is set to **`true`**, which causes the **`StyledButton`** component to apply the **`hover`** styles to itself. When the button is pressed, the **`isActive`** state is set to **`true`**, which causes the **`StyledButton`** component to apply the **`active`** styles to itself.

This allows the developer to easily control the component's state and styles using the **`states`** prop.

### Supported States

- `indeterminate`
- `checked`
- `readOnly`
- `required`
- `invalid`
- `focus`
- `focusVisible`
- `hover`
- `pressed`
- `active`
- `loading`
- `disabled`

### State Specificity Map

```bash
indeterminate: 1,
checked: 1,
readOnly: 1,

required: 2,
invalid: 2,

focus: 3,
focusVisible: 4,
hover: 5,
pressed: 6,
active: 6,
loading: 7,

disabled: 10,
```

**State specificity**

State props are resolved based on the above state precedence

For instance, if we pass both hover style and invalid style to a component, the hover style will be applied to the component.

**Nested specificity**

Nested declared state props are more specific
