@spelyco/react-lib 0.0.1-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -0
- package/dist/index.d.mts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +27 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# @spelyco/react-lib
|
|
2
|
+
|
|
3
|
+
Shared React hooks and utilities for Spelyco UI packages. Framework-agnostic — works with both `@spelyco/react` and `@spelyco/react-native`.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @spelyco/react-lib
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Hooks
|
|
12
|
+
|
|
13
|
+
### useBoolean
|
|
14
|
+
|
|
15
|
+
Manages a boolean state with stable action callbacks.
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { useBoolean } from "@spelyco/react-lib";
|
|
19
|
+
|
|
20
|
+
function Modal() {
|
|
21
|
+
const { value: isOpen, setTrue: open, setFalse: close, toggle } = useBoolean(false);
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
<button onClick={open}>Open</button>
|
|
26
|
+
{isOpen && <dialog onClose={close}>...</dialog>}
|
|
27
|
+
</>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**API**
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
function useBoolean(initialValue?: boolean): {
|
|
36
|
+
value: boolean;
|
|
37
|
+
setTrue: () => void;
|
|
38
|
+
setFalse: () => void;
|
|
39
|
+
toggle: () => void;
|
|
40
|
+
setValue: (value: boolean) => void;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
### useDebounce
|
|
47
|
+
|
|
48
|
+
Delays updating a value until after a specified wait period. Useful for search inputs and API calls.
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { useDebounce } from "@spelyco/react-lib";
|
|
52
|
+
|
|
53
|
+
function Search() {
|
|
54
|
+
const [query, setQuery] = useState("");
|
|
55
|
+
const debouncedQuery = useDebounce(query, 400);
|
|
56
|
+
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (debouncedQuery) fetchResults(debouncedQuery);
|
|
59
|
+
}, [debouncedQuery]);
|
|
60
|
+
|
|
61
|
+
return <input onChange={(e) => setQuery(e.target.value)} />;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**API**
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
function useDebounce<T>(value: T, delay?: number): T
|
|
69
|
+
// delay defaults to 300ms
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Utils
|
|
73
|
+
|
|
74
|
+
### cn
|
|
75
|
+
|
|
76
|
+
Merges class names, filtering out falsy values. Lightweight alternative to `clsx`.
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
import { cn } from "@spelyco/react-lib";
|
|
80
|
+
|
|
81
|
+
cn("btn", isActive && "btn--active", undefined, "btn--lg");
|
|
82
|
+
// → "btn btn--active btn--lg"
|
|
83
|
+
|
|
84
|
+
cn(["base", ["nested", "classes"]]);
|
|
85
|
+
// → "base nested classes"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**API**
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
function cn(...inputs: ClassValue[]): string
|
|
92
|
+
// ClassValue = string | undefined | null | false | ClassValue[]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Peer Dependencies
|
|
96
|
+
|
|
97
|
+
| Package | Version |
|
|
98
|
+
|---|---|
|
|
99
|
+
| `react` | `>=18` |
|
|
100
|
+
|
|
101
|
+
## License
|
|
102
|
+
|
|
103
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
interface UseBooleanReturn {
|
|
2
|
+
value: boolean;
|
|
3
|
+
setTrue: () => void;
|
|
4
|
+
setFalse: () => void;
|
|
5
|
+
toggle: () => void;
|
|
6
|
+
setValue: (value: boolean) => void;
|
|
7
|
+
}
|
|
8
|
+
declare function useBoolean(initialValue?: boolean): UseBooleanReturn;
|
|
9
|
+
|
|
10
|
+
declare function useDebounce<T>(value: T, delay?: number): T;
|
|
11
|
+
|
|
12
|
+
type ClassValue = string | undefined | null | false | ClassValue[];
|
|
13
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
14
|
+
|
|
15
|
+
export { cn, useBoolean, useDebounce };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
interface UseBooleanReturn {
|
|
2
|
+
value: boolean;
|
|
3
|
+
setTrue: () => void;
|
|
4
|
+
setFalse: () => void;
|
|
5
|
+
toggle: () => void;
|
|
6
|
+
setValue: (value: boolean) => void;
|
|
7
|
+
}
|
|
8
|
+
declare function useBoolean(initialValue?: boolean): UseBooleanReturn;
|
|
9
|
+
|
|
10
|
+
declare function useDebounce<T>(value: T, delay?: number): T;
|
|
11
|
+
|
|
12
|
+
type ClassValue = string | undefined | null | false | ClassValue[];
|
|
13
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
14
|
+
|
|
15
|
+
export { cn, useBoolean, useDebounce };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
|
|
5
|
+
// src/hooks/useBoolean.ts
|
|
6
|
+
function useBoolean(initialValue = false) {
|
|
7
|
+
const [value, setValue] = react.useState(initialValue);
|
|
8
|
+
const setTrue = react.useCallback(() => setValue(true), []);
|
|
9
|
+
const setFalse = react.useCallback(() => setValue(false), []);
|
|
10
|
+
const toggle = react.useCallback(() => setValue((v) => !v), []);
|
|
11
|
+
return { value, setTrue, setFalse, toggle, setValue };
|
|
12
|
+
}
|
|
13
|
+
function useDebounce(value, delay = 300) {
|
|
14
|
+
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
15
|
+
react.useEffect(() => {
|
|
16
|
+
const timer = setTimeout(() => setDebouncedValue(value), delay);
|
|
17
|
+
return () => clearTimeout(timer);
|
|
18
|
+
}, [value, delay]);
|
|
19
|
+
return debouncedValue;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// src/utils/cn.ts
|
|
23
|
+
function cn(...inputs) {
|
|
24
|
+
return inputs.flat(Infinity).filter(Boolean).join(" ");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
exports.cn = cn;
|
|
28
|
+
exports.useBoolean = useBoolean;
|
|
29
|
+
exports.useDebounce = useDebounce;
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useBoolean.ts","../src/hooks/useDebounce.ts","../src/utils/cn.ts"],"names":["useState","useCallback","useEffect"],"mappings":";;;;;AAUO,SAAS,UAAA,CAAW,eAAe,KAAA,EAAyB;AACjE,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAS,YAAY,CAAA;AAE/C,EAAA,MAAM,UAAUC,iBAAA,CAAY,MAAM,SAAS,IAAI,CAAA,EAAG,EAAE,CAAA;AACpD,EAAA,MAAM,WAAWA,iBAAA,CAAY,MAAM,SAAS,KAAK,CAAA,EAAG,EAAE,CAAA;AACtD,EAAA,MAAM,MAAA,GAASA,iBAAA,CAAY,MAAM,QAAA,CAAS,CAAC,MAAM,CAAC,CAAC,CAAA,EAAG,EAAE,CAAA;AAExD,EAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,QAAA,EAAU,QAAQ,QAAA,EAAS;AACtD;AChBO,SAAS,WAAA,CAAe,KAAA,EAAU,KAAA,GAAQ,GAAA,EAAQ;AACvD,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAID,eAAY,KAAK,CAAA;AAE7D,EAAAE,eAAA,CAAU,MAAM;AACd,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,iBAAA,CAAkB,KAAK,GAAG,KAAK,CAAA;AAC9D,IAAA,OAAO,MAAM,aAAa,KAAK,CAAA;AAAA,EACjC,CAAA,EAAG,CAAC,KAAA,EAAO,KAAK,CAAC,CAAA;AAEjB,EAAA,OAAO,cAAA;AACT;;;ACTO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAO,MAAA,CACJ,KAAK,QAAa,CAAA,CAClB,OAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AACb","file":"index.js","sourcesContent":["import { useCallback, useState } from \"react\";\n\nexport interface UseBooleanReturn {\n value: boolean;\n setTrue: () => void;\n setFalse: () => void;\n toggle: () => void;\n setValue: (value: boolean) => void;\n}\n\nexport function useBoolean(initialValue = false): UseBooleanReturn {\n const [value, setValue] = useState(initialValue);\n\n const setTrue = useCallback(() => setValue(true), []);\n const setFalse = useCallback(() => setValue(false), []);\n const toggle = useCallback(() => setValue((v) => !v), []);\n\n return { value, setTrue, setFalse, toggle, setValue };\n}\n","import { useEffect, useState } from \"react\";\n\nexport function useDebounce<T>(value: T, delay = 300): T {\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n const timer = setTimeout(() => setDebouncedValue(value), delay);\n return () => clearTimeout(timer);\n }, [value, delay]);\n\n return debouncedValue;\n}\n","type ClassValue = string | undefined | null | false | ClassValue[];\n\nexport function cn(...inputs: ClassValue[]): string {\n return inputs\n .flat(Infinity as 1)\n .filter(Boolean)\n .join(\" \");\n}\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
// src/hooks/useBoolean.ts
|
|
4
|
+
function useBoolean(initialValue = false) {
|
|
5
|
+
const [value, setValue] = useState(initialValue);
|
|
6
|
+
const setTrue = useCallback(() => setValue(true), []);
|
|
7
|
+
const setFalse = useCallback(() => setValue(false), []);
|
|
8
|
+
const toggle = useCallback(() => setValue((v) => !v), []);
|
|
9
|
+
return { value, setTrue, setFalse, toggle, setValue };
|
|
10
|
+
}
|
|
11
|
+
function useDebounce(value, delay = 300) {
|
|
12
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const timer = setTimeout(() => setDebouncedValue(value), delay);
|
|
15
|
+
return () => clearTimeout(timer);
|
|
16
|
+
}, [value, delay]);
|
|
17
|
+
return debouncedValue;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// src/utils/cn.ts
|
|
21
|
+
function cn(...inputs) {
|
|
22
|
+
return inputs.flat(Infinity).filter(Boolean).join(" ");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { cn, useBoolean, useDebounce };
|
|
26
|
+
//# sourceMappingURL=index.mjs.map
|
|
27
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useBoolean.ts","../src/hooks/useDebounce.ts","../src/utils/cn.ts"],"names":["useState"],"mappings":";;;AAUO,SAAS,UAAA,CAAW,eAAe,KAAA,EAAyB;AACjE,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,YAAY,CAAA;AAE/C,EAAA,MAAM,UAAU,WAAA,CAAY,MAAM,SAAS,IAAI,CAAA,EAAG,EAAE,CAAA;AACpD,EAAA,MAAM,WAAW,WAAA,CAAY,MAAM,SAAS,KAAK,CAAA,EAAG,EAAE,CAAA;AACtD,EAAA,MAAM,MAAA,GAAS,WAAA,CAAY,MAAM,QAAA,CAAS,CAAC,MAAM,CAAC,CAAC,CAAA,EAAG,EAAE,CAAA;AAExD,EAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,QAAA,EAAU,QAAQ,QAAA,EAAS;AACtD;AChBO,SAAS,WAAA,CAAe,KAAA,EAAU,KAAA,GAAQ,GAAA,EAAQ;AACvD,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAIA,SAAY,KAAK,CAAA;AAE7D,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,iBAAA,CAAkB,KAAK,GAAG,KAAK,CAAA;AAC9D,IAAA,OAAO,MAAM,aAAa,KAAK,CAAA;AAAA,EACjC,CAAA,EAAG,CAAC,KAAA,EAAO,KAAK,CAAC,CAAA;AAEjB,EAAA,OAAO,cAAA;AACT;;;ACTO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAO,MAAA,CACJ,KAAK,QAAa,CAAA,CAClB,OAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AACb","file":"index.mjs","sourcesContent":["import { useCallback, useState } from \"react\";\n\nexport interface UseBooleanReturn {\n value: boolean;\n setTrue: () => void;\n setFalse: () => void;\n toggle: () => void;\n setValue: (value: boolean) => void;\n}\n\nexport function useBoolean(initialValue = false): UseBooleanReturn {\n const [value, setValue] = useState(initialValue);\n\n const setTrue = useCallback(() => setValue(true), []);\n const setFalse = useCallback(() => setValue(false), []);\n const toggle = useCallback(() => setValue((v) => !v), []);\n\n return { value, setTrue, setFalse, toggle, setValue };\n}\n","import { useEffect, useState } from \"react\";\n\nexport function useDebounce<T>(value: T, delay = 300): T {\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n const timer = setTimeout(() => setDebouncedValue(value), delay);\n return () => clearTimeout(timer);\n }, [value, delay]);\n\n return debouncedValue;\n}\n","type ClassValue = string | undefined | null | false | ClassValue[];\n\nexport function cn(...inputs: ClassValue[]): string {\n return inputs\n .flat(Infinity as 1)\n .filter(Boolean)\n .join(\" \");\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@spelyco/react-lib",
|
|
3
|
+
"version": "0.0.1-alpha",
|
|
4
|
+
"description": "Shared React hooks and utilities for Spelyco UI packages",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"react",
|
|
7
|
+
"hooks",
|
|
8
|
+
"utilities",
|
|
9
|
+
"spelyco"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"main": "./dist/index.js",
|
|
13
|
+
"module": "./dist/index.mjs",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.mjs",
|
|
19
|
+
"require": "./dist/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup",
|
|
27
|
+
"dev": "tsup --watch",
|
|
28
|
+
"lint": "biome check src/",
|
|
29
|
+
"lint:fix": "biome check --write src/",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"test:watch": "vitest",
|
|
32
|
+
"clean": "rm -rf dist"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"react": ">=18"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@spelyco/tsconfig": "*",
|
|
39
|
+
"@testing-library/react": "^16.1.0",
|
|
40
|
+
"@types/react": "^19.2.14",
|
|
41
|
+
"jsdom": "^29.0.1",
|
|
42
|
+
"react": "^19.2.4",
|
|
43
|
+
"react-dom": "^19.2.4",
|
|
44
|
+
"tsup": "^8.3.5",
|
|
45
|
+
"vitest": "^4.1.1"
|
|
46
|
+
}
|
|
47
|
+
}
|