# or
yarn add @zag-js/presence @zag-js/solid
```

## Usage

First, import the presence package into your project

```jsx
import * as presence from "@zag-js/presence"
```

The presence package exports two key functions:

- `machine` â The state machine logic for the presence.
- `connect` â The function that translates the machine's state to JSX attributes
  and event handlers.

Next, import the required hooks and functions for your framework and use the
presence machine in your project ð¥

```tsx
import * as presence from "@zag-js/presence"
import { useMachine, normalizeProps } from "@zag-js/solid"
import { createMemo, createUniqueId, JSX } from "solid-js"

interface PresenceProps {
  present: boolean
  unmountOnExit?: boolean
  onExitComplete?: () => void
  children: JSX.Element
}

function Presence(props: PresenceProps) {
  const [machineProps, localProps] = splitProps(props, [
    "present",
    "unmountOnExit",
    "onExitComplete",
  ])

  const service = useMachine(presence.machine, machineProps)

  const api = createMemo(() => presence.connect(service, normalizeProps))
  const unmount = createMemo(() => !api().present && localProps.unmountOnExit)

  return (
    <Show when={!unmount()}>
      <div
        hidden={!api().present}
        data-state={api().skip ? undefined : present ? "open" : "closed"}
        ref={api().setNode}
        {...localProps}
      />
    </Show>
  )
}
```

## Styling guide

To style any entry and exit animations, set up the `@keyframes` and apply the
animations.

```css
@keyframes enter {
  from {
    scale: 0.9;
    opacity: 0;
  }

  to {
    opacity: 1;
    scale: 1;
  }
}

@keyframes exit {
  to {
    opacity: 0;
    scale: 0.9;
  }
}

[data-state="open"] {
  animation: enter 0.15s ease-out;
}

[data-state="closed"] {
  animation: exit 0.1s ease-in;
}
```

You can then use the `Presence` component in your project.

```jsx
function Example() {
  const [open, setOpen] = React.useState(true)
  return (
    <>
      <button onClick={() => setOpen((c) => !c)}>Toggle</button>
      <Presence present={open} unmountOnExit>
        <div>Content</div>
      </Presence>
    </>
  )
}
```

## Methods and Properties

### Machine Context

The presence machine exposes the following context properties:

**`present`**
Type: `boolean`
Description: Whether the node is present (controlled by the user)

**`onExitComplete`**
Type: `VoidFunction`
Description: Function called when the animation ends in the closed state

**`immediate`**
Type: `boolean`
Description: Whether to synchronize the present change immediately or defer it to the next frame

### Machine API

The presence `api` exposes the following methods:

**`skip`**
Type: `boolean`
Description: Whether the animation should be skipped.

**`present`**
Type: `boolean`
Description: Whether the node is present in the DOM.

**`setNode`**
Type: `(node: HTMLElement) => void`
Description: Function to set the node (as early as possible)

**`unmount`**
Type: `VoidFunction`
Description: Function to programmatically unmount the node
Linear progress is a simple progress bar that can be used to show the progress
of a task such as downloading a file, uploading an image, etc.

## Resources


[Latest version: v1.33.1](https://www.npmjs.com/package/@zag-js/progress)
[Logic Visualizer](https://zag-visualizer.vercel.app/progress)
[Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/progress)



**Features**

- Support for minimum and maximum values
- Support for indeterminate progress bars

## Installation

To use the progress machine in your project, run the following command in your
command line:

```bash
npm install @zag-js/progress @zag-js/solid