Skip to content

Commit 3ea9779

Browse files
committed
feat: release of the first alpha version of the smart hooks library for React
1 parent 526d006 commit 3ea9779

File tree

328 files changed

+34875
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

328 files changed

+34875
-0
lines changed

.commitlintrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": ["@commitlint/config-conventional"]
3+
}

.editorconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
indent_size = 2
7+
indent_style = space
8+
insert_final_newline = true

.github/workflows/ci.yml

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
name: Build and publish package
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
push:
8+
branches:
9+
- main
10+
- next
11+
12+
env:
13+
NODE_VERSION: 22
14+
PNPM_VERSION: 10
15+
16+
jobs:
17+
commitlint:
18+
name: Commit Lint
19+
runs-on: ubuntu-latest
20+
steps:
21+
- uses: actions/checkout@v5
22+
- uses: wagoid/commitlint-github-action@v6
23+
with:
24+
configFile: .commitlintrc.json
25+
lint:
26+
name: Lint
27+
runs-on: ubuntu-latest
28+
steps:
29+
- name: Check out repository
30+
uses: actions/checkout@v5
31+
32+
- name: Install pnpm
33+
uses: pnpm/action-setup@v4
34+
with:
35+
version: ${{ env.PNPM_VERSION }}
36+
37+
- name: Setup node ${{ env.NODE_VERSION }}
38+
uses: actions/setup-node@v5
39+
with:
40+
node-version: ${{ env.NODE_VERSION }}
41+
cache: 'pnpm'
42+
43+
- name: Install dependencies
44+
run: pnpm install
45+
46+
- name: Run lint with ESLint
47+
run: pnpm run lint
48+
49+
- name: Run lint with TypeScript
50+
run: pnpm run lint:types
51+
52+
test:
53+
name: Test
54+
needs: [ commitlint, lint ]
55+
runs-on: ubuntu-latest
56+
steps:
57+
- name: Check out repository
58+
uses: actions/checkout@v5
59+
60+
- name: Install pnpm
61+
uses: pnpm/action-setup@v4
62+
with:
63+
version: ${{ env.PNPM_VERSION }}
64+
65+
- name: Setup node ${{ env.NODE_VERSION }}
66+
uses: actions/setup-node@v5
67+
with:
68+
node-version: ${{ env.NODE_VERSION }}
69+
cache: 'pnpm'
70+
71+
- name: Install dependencies
72+
run: pnpm install
73+
74+
- name: Run tests
75+
run: pnpm run test
76+
77+
publish:
78+
name: Build and publish
79+
if: |
80+
github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/next')
81+
needs: [ commitlint, lint, test ]
82+
runs-on: ubuntu-latest
83+
permissions:
84+
contents: write
85+
id-token: write
86+
issues: write
87+
pull-requests: write
88+
steps:
89+
- name: Check out repository
90+
uses: actions/checkout@v5
91+
92+
- name: Install pnpm
93+
uses: pnpm/action-setup@v4
94+
with:
95+
version: ${{ env.PNPM_VERSION }}
96+
97+
- name: Setup node ${{ env.NODE_VERSION }}
98+
uses: actions/setup-node@v5
99+
with:
100+
node-version: ${{ env.NODE_VERSION }}
101+
cache: 'pnpm'
102+
103+
- name: Install dependencies
104+
run: pnpm install
105+
106+
- name: Run build
107+
run: pnpm build
108+
109+
- name: Release
110+
run: pnpm release
111+
env:
112+
GH_TOKEN: ${{ secrets.WEBEACH_GITHUB_RELEASE_TOKEN }}
113+
NPM_TOKEN: ${{ secrets.WEBEACH_NPM_PUBLISH_TOKEN }}

.husky/commit-msg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
commitlint --edit

.husky/pre-commit

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lint-staged
2+
pnpm run lint:types

.husky/pre-push

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pnpm run test

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
22.2.0

.releaserc.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"branches": [
3+
"main",
4+
{
5+
"name": "next",
6+
"prerelease": "rc"
7+
}
8+
],
9+
"plugins": [
10+
["@semantic-release/commit-analyzer", {
11+
"preset": "conventionalcommits",
12+
"presetConfig": {
13+
"preMajor": true
14+
}
15+
}],
16+
"@semantic-release/release-notes-generator",
17+
"@semantic-release/changelog",
18+
"@semantic-release/npm",
19+
"@semantic-release/git",
20+
"@semantic-release/github"
21+
]
22+
}

README.md

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
<div align="center">
2+
<img alt="react-hooks" src="./assets/logo.svg" height="96">
3+
<br><br><br>
4+
<p>
5+
<a href="https://www.npmjs.com/package/@webeach/react-hooks">
6+
<img src="https://img.shields.io/npm/v/@webeach/react-hooks.svg?color=646fe1&labelColor=9B7AEF" alt="npm package" />
7+
</a>
8+
<a href="https://github.com/webeach/react-hooks/actions/workflows/ci.yml">
9+
<img src="https://img.shields.io/github/actions/workflow/status/webeach/react-hooks/ci.yml?color=646fe1&labelColor=9B7AEF" alt="build" />
10+
</a>
11+
<a href="https://www.npmjs.com/package/@webeach/react-hooks">
12+
<img src="https://img.shields.io/npm/dm/@webeach/react-hooks.svg?color=646fe1&labelColor=9B7AEF" alt="npm downloads" />
13+
</a>
14+
</p>
15+
<p><a href="./README.md">🇺🇸 English version</a> | <a href="./README.ru.md">🇷🇺 Русская версия</a></p>
16+
<p>A set of smart React hooks for performant UIs (React 18+)</p>
17+
</div>
18+
19+
---
20+
21+
## 💎 Highlights
22+
23+
- **Fewer re-renders.** Hooks update state only when needed: lazy flags, stable handlers and refs.
24+
- **Hybrid return.** Many hooks can be used as a **tuple** or as an **object** — pick the shape you prefer.
25+
- **Clean effects.** Subscriptions and cleanup are sensible by default; behavior is predictable.
26+
- **SSR-ready.** Browser APIs are touched strictly inside effects.
27+
28+
---
29+
30+
## 📦 Installation
31+
32+
```bash
33+
npm install @webeach/react-hooks
34+
```
35+
36+
or
37+
38+
```bash
39+
pnpm install @webeach/react-hooks
40+
```
41+
42+
or
43+
44+
```bash
45+
yarn add @webeach/react-hooks
46+
```
47+
48+
---
49+
50+
## 📥 Import
51+
52+
**ES Modules**
53+
54+
```ts
55+
import { useBoolean } from '@webeach/react-hooks/useBoolean';
56+
import { useEffectCompare } from '@webeach/react-hooks/useEffectCompare';
57+
import { useWindowEvent } from '@webeach/react-hooks/useWindowEvent';
58+
59+
// or
60+
import { useBoolean, useEffectCompare, useWindowEvent } from '@webeach/react-hooks';
61+
```
62+
63+
**CommonJS**
64+
65+
```ts
66+
const { useBoolean } = require('@webeach/react-hooks/useBoolean');
67+
const { useEffectCompare } = require('@webeach/react-hooks/useEffectCompare');
68+
const { useWindowEvent } = require('@webeach/react-hooks/useWindowEvent');
69+
70+
// or
71+
const { useBoolean, useEffectCompare, useWindowEvent } = require('@webeach/react-hooks');
72+
```
73+
74+
### 🌿 Tree‑shaking
75+
- Every hook is available as an **individual module path** (`@webeach/react-hooks/useX`). Importing this way pulls **only the code you need** — the most predictable and compact option for any bundler (ESM and CJS).
76+
- Named import from the package root (`@webeach/react-hooks`) supports tree‑shaking in bundlers that optimize **ES modules** (Vite/Rollup/esbuild/Webpack 5 in production). Unused exports will be removed at build time.
77+
- For **CommonJS** projects, we recommend per‑module imports (`require('@webeach/react-hooks/useX')`) to avoid pulling extra code through the index.
78+
79+
---
80+
81+
## 🛠 Hooks
82+
83+
### Alphabetical
84+
85+
+ [useAsyncCallback](./docs/en/useAsyncCallback.md)
86+
+ [useAsyncHandler](./docs/en/useAsyncHandler.md)
87+
+ [useBoolean](./docs/en/useBoolean.md)
88+
+ [useCallbackCompare](./docs/en/useCallbackCompare.md)
89+
+ [useCollection](./docs/en/useCollection.md)
90+
+ [useControlled](./docs/en/useControlled.md)
91+
+ [useDebounceCallback](./docs/en/useDebounceCallback.md)
92+
+ [useDebounceState](./docs/en/useDebounceState.md)
93+
+ [useDemandStructure](./docs/en/useDemandStructure.md)
94+
+ [useDeps](./docs/en/useDeps.md)
95+
+ [useDOMEvent](./docs/en/useDOMEvent.md)
96+
+ [useEffectCompare](./docs/en/useEffectCompare.md)
97+
+ [useForceUpdate](./docs/en/useForceUpdate.md)
98+
+ [useFrame](./docs/en/useFrame.md)
99+
+ [useFrameExtended](./docs/en/useFrameExtended.md)
100+
+ [useImageLoader](./docs/en/useImageLoader.md)
101+
+ [useIntersectionObserver](./docs/en/useIntersectionObserver.md)
102+
+ [useIsomorphicLayoutEffect](./docs/en/useIsomorphicLayoutEffect.md)
103+
+ [useLayoutEffectCompare](./docs/en/useLayoutEffectCompare.md)
104+
+ [useLiveRef](./docs/en/useLiveRef.md)
105+
+ [useLocalStorage](./docs/en/useLocalStorage.md)
106+
+ [useLoop](./docs/en/useLoop.md)
107+
+ [useMap](./docs/en/useMap.md)
108+
+ [useMemoCompare](./docs/en/useMemoCompare.md)
109+
+ [useNumber](./docs/en/useNumber.md)
110+
+ [useOutsideEvent](./docs/en/useOutsideEvent.md)
111+
+ [usePageTitle](./docs/en/usePageTitle.md)
112+
+ [usePageVisibility](./docs/en/usePageVisibility.md)
113+
+ [usePatchDeepState](./docs/en/usePatchDeepState.md)
114+
+ [usePatchState](./docs/en/usePatchState.md)
115+
+ [useRefEffect](./docs/en/useRefEffect.md)
116+
+ [useRefState](./docs/en/useRefState.md)
117+
+ [useResizeObserver](./docs/en/useResizeObserver.md)
118+
+ [useSessionStorage](./docs/en/useSessionStorage.md)
119+
+ [useSet](./docs/en/useSet.md)
120+
+ [useStatus](./docs/en/useStatus.md)
121+
+ [useThrottleCallback](./docs/en/useThrottleCallback.md)
122+
+ [useThrottleState](./docs/en/useThrottleState.md)
123+
+ [useTimeout](./docs/en/useTimeout.md)
124+
+ [useTimeoutExtended](./docs/en/useTimeoutExtended.md)
125+
+ [useToggle](./docs/en/useToggle.md)
126+
+ [useUnmount](./docs/en/useUnmount.md)
127+
+ [useWindowEvent](./docs/en/useWindowEvent.md)
128+
129+
### By category
130+
131+
#### State — simple primitives
132+
- [useControlled](./docs/en/useControlled.md)
133+
- [useBoolean](./docs/en/useBoolean.md)
134+
- [useNumber](./docs/en/useNumber.md)
135+
- [useToggle](./docs/en/useToggle.md)
136+
- [useStatus](./docs/en/useStatus.md)
137+
138+
#### State — object patterns
139+
- [usePatchDeepState](./docs/en/usePatchDeepState.md)
140+
- [usePatchState](./docs/en/usePatchState.md)
141+
142+
#### State — collections
143+
- [useCollection](./docs/en/useCollection.md)
144+
- [useMap](./docs/en/useMap.md)
145+
- [useSet](./docs/en/useSet.md)
146+
147+
#### State — storage (persistence)
148+
- [useLocalStorage](./docs/en/useLocalStorage.md)
149+
- [useSessionStorage](./docs/en/useSessionStorage.md)
150+
151+
#### Timers, loops & frames
152+
- [useFrame](./docs/en/useFrame.md)
153+
- [useFrameExtended](./docs/en/useFrameExtended.md)
154+
- [useLoop](./docs/en/useLoop.md)
155+
- [useTimeout](./docs/en/useTimeout.md)
156+
- [useTimeoutExtended](./docs/en/useTimeoutExtended.md)
157+
158+
#### Rate limiting (throttle/debounce)
159+
- [useDebounceCallback](./docs/en/useDebounceCallback.md)
160+
- [useDebounceState](./docs/en/useDebounceState.md)
161+
- [useThrottleCallback](./docs/en/useThrottleCallback.md)
162+
- [useThrottleState](./docs/en/useThrottleState.md)
163+
164+
#### Async operations
165+
- [useAsyncCallback](./docs/en/useAsyncCallback.md)
166+
- [useAsyncHandler](./docs/en/useAsyncHandler.md)
167+
- [useImageLoader](./docs/en/useImageLoader.md)
168+
169+
#### Dependency optimization
170+
- [useDeps](./docs/en/useDeps.md)
171+
- [useCallbackCompare](./docs/en/useCallbackCompare.md)
172+
- [useEffectCompare](./docs/en/useEffectCompare.md)
173+
- [useLayoutEffectCompare](./docs/en/useLayoutEffectCompare.md)
174+
- [useMemoCompare](./docs/en/useMemoCompare.md)
175+
- [useIsomorphicLayoutEffect](./docs/en/useIsomorphicLayoutEffect.md)
176+
177+
#### Lifecycle
178+
- [useEffectCompare](./docs/en/useEffectCompare.md)
179+
- [useLayoutEffectCompare](./docs/en/useLayoutEffectCompare.md)
180+
- [useUnmount](./docs/en/useUnmount.md)
181+
182+
#### Refs
183+
- [useLiveRef](./docs/en/useLiveRef.md)
184+
- [useRefEffect](./docs/en/useRefEffect.md)
185+
186+
#### Events
187+
- [useDOMEvent](./docs/en/useDOMEvent.md)
188+
- [useWindowEvent](./docs/en/useWindowEvent.md)
189+
- [useOutsideEvent](./docs/en/useOutsideEvent.md)
190+
191+
#### Observers
192+
- [useIntersectionObserver](./docs/en/useIntersectionObserver.md)
193+
- [useResizeObserver](./docs/en/useResizeObserver.md)
194+
195+
#### Page & document
196+
- [usePageTitle](./docs/en/usePageTitle.md)
197+
- [usePageVisibility](./docs/en/usePageVisibility.md)
198+
199+
#### Utilities
200+
- [useDemandStructure](./docs/en/useDemandStructure.md)
201+
- [useForceUpdate](./docs/en/useForceUpdate.md)
202+
- [useRefState](./docs/en/useRefState.md)
203+
204+
---
205+
206+
## 🧩 Dependencies
207+
208+
This package has **a single external dependency**[@webeach/collection](https://github.com/webeach/collection).
209+
210+
- It is used **only** by the [`useCollection`](./docs/en/useCollection.md) hook.
211+
- Other hooks do not import or require `collection`.
212+
213+
---
214+
215+
## 🔖 Releasing
216+
217+
Releases are automated with `semantic-release`.
218+
219+
Before publishing a new version, make sure that:
220+
221+
1. All changes are committed and pushed to `main`.
222+
2. Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/):
223+
- `feat: ...` — new features
224+
- `fix: ...` — bug fixes
225+
- `chore: ...`, `refactor: ...`, etc. — as needed
226+
3. The next version (`patch`, `minor`, `major`) is derived automatically from the commit types.
227+
228+
---
229+
230+
## 👤 Author
231+
232+
Developed and maintained by [Ruslan Martynov](https://github.com/ruslan-mart).
233+
234+
Have an idea or found a bug? Open an issue or send a pull request.
235+
236+
---
237+
238+
## 📄 License
239+
240+
This package is distributed under the [MIT License](./LICENSE).

0 commit comments

Comments
 (0)