Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @basmasking @petermasking
6 changes: 6 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Fixes #

Changes proposed in this pull request:
-
-
-
37 changes: 37 additions & 0 deletions .github/workflows/nodejsci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Node.js CI

on:
pull_request:
branches: [ main ]

permissions:
contents: read

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [lts/*]

steps:
- name: ⚙️ Checkout Repository
uses: actions/checkout@v6

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
cache: npm
cache-dependency-path: '**/package-lock.json'

- name: 📦 Install Dependencies
run: npm ci

- name: 🚀 Build Package
run: npm run build

- name: ✅ Lint Package
run: npm run lint
30 changes: 30 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
on:
push:
branches:
- main

permissions:
id-token: write
contents: read

jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: ⚙️ Checkout Repository
uses: actions/checkout@v6

- name: 🛠️ Set up Node.js
uses: actions/setup-node@v6
with:
node-version: '24.x'
registry-url: 'https://registry.npmjs.org/'

- name: 📦 Install Dependencies
run: npm ci

- name: 🚀 Publish Package
run: npm publish

- name: ✅ Publish Complete
run: echo "Package published successfully."
165 changes: 165 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# React Toolkit

A set of reusables for React mainly used by ourselves.

## Components

### ErrorBoundary

Catches errors and passes it to the provided element.

Usage:

```tsx
import { ErrorBoundary } from '@maskingtech/react-toolkit';

function ErrorHandler({ error }: { error: unknown })
{
return <>Oops...</>;
}

<ErrorBoundary element={ErrorHandler}>
{/* Content goes here */}
</ErrorBoundary>;
```

## Hooks

### useDebouncedValue

Delays value updates for a period of time.

Usage:

```tsx
import { useDebouncedValue } from '@maskingtech/react-toolkit';

function MyComponent()
{
const initialValue: number = 0; // required
const onChange = (debouncedValue: number) => { }; // optional
const delay = 300; // optional, default 500

const [debouncedValue, setValue] = useDebouncedValue(initialValue, onChange, delay);

return <p>
{debouncedValue}
<button onClick={() => setValue(debouncedValue + 1)}>Increase</button>
</p>;
}
```

### useFocusOnMount

Gives a form element focus after mount.

Usage:

```tsx
import { useFocusOnMount } from '@maskingtech/react-toolkit';

function MyComponent()
{
const ref = useFocusOnMount();

return <input type="text" ref={ref} />;
}
```

### useForm

Provides access to the data of a form after submitting.

Usage:

```tsx
import { useForm } from '@maskingtech/react-toolkit';

function MyComponent()
{
const submitHandler = (data: FormData) { console.log(data.get('name')); };

const [ref, state, handleSubmit] = useForm(submitHandler);

// states: 'pristine' | 'dirty' | 'submitting'

return <form ref={ref} onSubmit={handleSubmit}>
<input type="text" name="name" />
<input type="submit" value="Submit" disabled={state !== 'dirty'} />
</form>;
}
```

### useFormData

Provides access to the data of a form without submitting.

Usage:

```tsx
import { useFormData } from '@maskingtech/react-toolkit';

function MyComponent()
{
const dataHandler = (data: FormData) { console.log(data.get('name')); };

const [ref, state, handleData] = useFormData(dataHandler);

// states: 'idle' | 'working'

return <form ref={ref}>
<input type="text" name="name" />
<input type="button" value="Go!" disabled={state !== 'working'} />
</form>;
}
```

### useLoadData

Provides helpers for loading data.

Usage:

```tsx
import { useLoadData } from '@maskingtech/react-toolkit';

async function getData() { /* get data here */ }

function MyComponent()
{
const [data, isLoading, refresh, setData] = useLoadData(getData);

if (isLoading) return <>Loading...</>;

return <p>
{data}
<button onClick={() => refresh()}>Refresh</button>
</p>;
}
```

### usePagination

Provides helpers for loading paginated data.

Usage:

```tsx
import { useLoadData } from '@maskingtech/react-toolkit';

async function getPageData(page: number) { /* get data here */ }

function MyComponent()
{
const [data, isLoading, isFinished, next, previous, reset, setData] = useLoadData(useLoadData);

if (isLoading) return <>Loading...</>;

return <p>
{data}
<button onClick={() => previous()}>Previous</button>
<button onClick={() => next()}>Next</button>
<button onClick={() => reset()}>Reset</button>
</p>;
}
```
Loading