e30e75b5d4
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
70 lines
2.3 KiB
Markdown
70 lines
2.3 KiB
Markdown
# `@assistant-ui/tap`
|
|
|
|
[](https://www.npmjs.com/package/@assistant-ui/tap)
|
|
[](https://www.npmjs.com/package/@assistant-ui/tap)
|
|
[](https://bundlephobia.com/package/@assistant-ui/tap)
|
|
[](https://github.com/assistant-ui/assistant-ui)
|
|
|
|
React's hooks, headless. Write a **resource** the same way you write a component, with the same hooks (`useState`, `useEffect`, `useMemo`, ...) imported from `"react"` and the same rules, except a resource returns a plain value instead of JSX. It runs inside a React component, inside another resource, or standalone with no React tree at all.
|
|
|
|
`tap` powers the runtime layer of assistant-ui. Most users do not install it directly; reach for `@assistant-ui/react` instead.
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
npm install @assistant-ui/tap
|
|
```
|
|
|
|
## Usage
|
|
|
|
```typescript
|
|
import { resource, createTapRoot, useResource } from "@assistant-ui/tap";
|
|
import { useState, useEffect } from "react";
|
|
|
|
const useCounter = ({ incrementBy = 1 }: { incrementBy?: number }) => {
|
|
const [count, setCount] = useState(0);
|
|
|
|
useEffect(() => {
|
|
console.log("count:", count);
|
|
}, [count]);
|
|
|
|
return {
|
|
count,
|
|
increment: () => setCount((c) => c + incrementBy),
|
|
};
|
|
};
|
|
|
|
const Counter = resource(useCounter);
|
|
|
|
const counter = createTapRoot(function CounterRoot() {
|
|
return useResource(Counter({ incrementBy: 2 }));
|
|
});
|
|
|
|
const unsubscribe = counter.subscribe(() => {
|
|
console.log("counter updated:", counter.getValue().count);
|
|
});
|
|
|
|
counter.getValue().increment();
|
|
```
|
|
|
|
In React, host a resource with `useResource`:
|
|
|
|
```tsx
|
|
import { useResource } from "@assistant-ui/tap";
|
|
|
|
function CounterButton() {
|
|
const { count, increment } = useResource(Counter({ incrementBy: 1 }));
|
|
return <button onClick={increment}>{count}</button>;
|
|
}
|
|
```
|
|
|
|
## Hooks
|
|
|
|
Inside a resource you use React's hooks (`useState`, `useEffect`, `useMemo`, `useCallback`, `useRef`, `use`, ...) imported from `"react"`. tap adds `useResource` / `useResources` / `useTapRoot` for composition and `useContextProvider` for context.
|
|
|
|
Full API reference at [assistant-ui.com/tap/docs](https://www.assistant-ui.com/tap/docs).
|
|
|
|
## License
|
|
|
|
MIT
|