# useCardOpening

`useCardOpening` is a card opening without a look. Give it the cards, which of them are opened, and what to do when one is. It keeps the queue, tracks the card that is up, and turns presses into decisions: turn it now, send it home, stop the run.

> Live preview: see it play at https://bettertyped.github.io/react-cards-opening/docs/core/use-card-opening/
>
> The hook with a plain div and CSS. No ui package on this one.

## Usage

```tsx
import { useCardOpening, useOpenedCards } from "@react-cards-opening/core";

const { opened, open } = useOpenedCards("deal:ada:2026");
const hunt = useCardOpening({ cards, opened, onOpen: open });

hunt.start(); // open every unopened card, one after another
hunt.start(["ash-phoenix"]); // or only these
hunt.replay(); // go over all of them again, opening nothing
hunt.openAll(); // skip the show
```

## Options

| Option | Type | What it is |
| --- | --- | --- |
| `cards` | `readonly C[]` | Every card in the deal, opened or not. A card is at least `{ id, rarity }`. |
| `opened` | `readonly string[]` | Ids already opened. Keep it in any state you like. |
| `onOpen` | `(id: string) => void` | A card was turned face up for the first time. |
| `onRunChange?` | `(running: boolean) => void` | A run started or came to rest. |

## What it returns

| Field | Type | What it is |
| --- | --- | --- |
| `opening` | `Opening` | The rules themselves. Hand it to whatever draws the reveal. |
| `current` | `C \| null` | The card that is up, in a run or a peek. |
| `pending` | `readonly C[]` | Cards nobody has opened yet. |
| `run` | `OpeningRun \| null` | The queue being opened: `{ id, queue, replay }`. |
| `step` | `number` | Which card of the queue is up. |
| `left` | `number` | How many come after the one that is up. |
| `running` | `boolean` | A run is on. |
| `allOpened` | `boolean` | Nothing is left to open. |
| `peeking` | `OpeningPeek \| null` | An opened card being looked at again. |
| `start(queue?)` | `=> boolean` | Opens unopened cards. False when there is nothing to open. |
| `replay()` | `=> boolean` | Goes over every card again. `onOpen` stays quiet. |
| `openAll()` | `=> void` | Takes the show down and opens everything at once. |
| `peek(id, origin)` | `=> void` | Brings an opened card up out of what was pressed. |
| `close()` | `=> void` | Puts a peeked card back. |
| `pressCard()` | `=> void` | A press on the card. See the rules below. |
| `pressBackdrop()` | `=> void` | A press beside the card. |

## The rules of a press

| When | A press on the card | A press beside it |
| --- | --- | --- |
| Face down | Turns it over now. | Stops the run. The card goes back unopened. |
| Turning or face up | Sends it home now. | Stops the run. This card still lands, nothing else opens. |
| On its way home | Nothing. | Nothing. |
| Peeking | Puts it back. | Puts it back. |

A card counts as opened the moment it is face up, not when it lands. That way whatever your page does about it (a list growing by one, a request to a server) happens while the viewer is reading, and the card can leave the instant they press.

## The phase

The phase changes several times a card, so it has its own hook. Only the component that shows it re-renders.

```tsx
import { useOpeningPhase } from "@react-cards-opening/core";

const phase = useOpeningPhase(hunt.opening);
// "idle" | "lead" | "flight" | "hum" | "turn" | "hold" | "land" | "peek"
```

## Without React

The hook is a thin wrapper over the `Opening` class, which has no React in it. Use the class directly in a store, a test or a game loop.

```ts
import { Opening } from "@react-cards-opening/core";

const opening = new Opening();
opening.sync({ cards, opened, onOpen });
opening.subscribe(() => render(opening.getState()));
opening.start();
```

## Related

- [Your own UI on core](https://bettertyped.github.io/react-cards-opening/docs/guides/own-ui-on-core/)
- [useOpenedCards](https://bettertyped.github.io/react-cards-opening/docs/core/use-opened-cards/)
- [CardOpening](https://bettertyped.github.io/react-cards-opening/docs/components/card-opening/)
- [Show plan](https://bettertyped.github.io/react-cards-opening/docs/core/show-plan/)

Source: https://bettertyped.github.io/react-cards-opening/docs/core/use-card-opening/
