https://github.com/bearstudio/ui-state
A lightweight utility to handle dynamic UI display states like loading, error, or any custom-defined state — based on your app logic.
https://github.com/bearstudio/ui-state
pattern-matching react state-management ts typescript ui
Last synced: 5 months ago
JSON representation
A lightweight utility to handle dynamic UI display states like loading, error, or any custom-defined state — based on your app logic.
- Host: GitHub
- URL: https://github.com/bearstudio/ui-state
- Owner: BearStudio
- License: mit
- Created: 2025-05-21T11:26:54.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-07-02T10:32:25.000Z (12 months ago)
- Last Synced: 2025-10-19T20:41:58.502Z (8 months ago)
- Topics: pattern-matching, react, state-management, ts, typescript, ui
- Language: TypeScript
- Homepage:
- Size: 298 KB
- Stars: 6
- Watchers: 0
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# @bearstudio/ui-state
A lightweight utility to handle dynamic UI display states like `loading`, `error`, or any custom-defined state — based on your app logic.
## ✨ Features
- 🧠 Declarative and expressive API
- 🔁 Dynamic state evaluation with conditions
- ✅ Fully customizable states and payloads
---
## 📦 Installation
```bash
pnpm install @bearstudio/ui-state
npm install @bearstudio/ui-state
yarn add @bearstudio/ui-state
```
## 🚀 Basic Usage
```tsx
import { getUiState } from "@bearstudio/ui-state";
const ui = getUiState((set) => {
if (bookQuery.status === "pending") return set("pending");
if (bookQuery.status === "error") return set("error");
return set("default", { book: bookQuery.data });
});
```
Rendering in React
```tsx
ui.match("pending", () => <>Loading...>)
.match("error", () => <>Error>)
.match("default", ({ book }) => <>{book.title}>)
.exhaustive();
```
## 🪄 Fully customizable and type-safe
```tsx
const ui = getUiState((set) => {
if (booksToImport === null) return set("show-input");
if (booksToImport.length === 0) return set("empty");
return set("listing", { booksToImport });
});
ui.is("show-input"); // valid
ui.is("default"); // invalid
```
## 📖 APIs
#### `is`
```tsx
ui.is("pending"); // Return true if state is `pending`, false otherwise
```
#### `when`
```tsx
ui.when("pending", () => <>Loading...>); // Render only when state is `pending`
```
#### `match` + `exhaustive`
```tsx
ui
.match("pending", () => <>Loading...>); // Render when state is `pending`
.match("error", () => <>Error...>); // Render when state is `error`
.match("default", () => <>Error...>); // Render when state is `default`
.exhaustive(); // Ensures all possible states are matched and rendered
```
#### `match` + `nonExhaustive`
```tsx
ui
.match("pending", () => <>Loading...>); // Render when state is `pending`
.match("default", () => <>Error...>); // Render when state is `default`
.nonExhaustive(); // Allows rendering without matching all possible states
```
## 📃 License MIT
> Made with ❤️ by BearStudio Team