Skip to content

Commit 6effeea

Browse files
committed
main 🧊 add use cookies, add cli page
1 parent 96d2fe5 commit 6effeea

File tree

9 files changed

+221
-36
lines changed

9 files changed

+221
-36
lines changed
Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
11
import { useEffect, useState } from 'react';
2-
import { clearCookies, getCookies, removeCookie, setCookie } from '../useCookie/helpers';
3-
import { COOKIE_EVENT, dispatchCookieEvent } from '../useCookie/useCookie';
2+
import { COOKIE_EVENT, dispatchCookieEvent, removeCookie, setCookie } from '../useCookie/useCookie';
3+
export const getParsedCookies = () => Object.fromEntries(document.cookie.split('; ').map((cookie) => {
4+
const [key, ...value] = cookie.split('=');
5+
const decodedValue = decodeURIComponent(value.join('='));
6+
try {
7+
return [key, JSON.parse(decodedValue)];
8+
}
9+
catch {
10+
return [key, decodedValue];
11+
}
12+
}));
13+
export const clearCookies = () => {
14+
document.cookie.split('; ').forEach((cookie) => {
15+
const [name] = cookie.split('=');
16+
removeCookie(name);
17+
});
18+
};
419
const setCookieItem = (key, value, options) => {
5-
setCookie(key, value, options);
6-
dispatchCookieEvent();
20+
setCookie(key, value, options);
21+
dispatchCookieEvent();
722
};
823
const removeCookieItem = (key, options) => {
9-
removeCookie(key, options);
10-
dispatchCookieEvent();
24+
removeCookie(key, options);
25+
dispatchCookieEvent();
1126
};
1227
const clearCookieItems = () => {
13-
clearCookies();
14-
dispatchCookieEvent();
28+
clearCookies();
29+
dispatchCookieEvent();
1530
};
1631
/**
1732
* @name useCookies
@@ -27,20 +42,21 @@ const clearCookieItems = () => {
2742
* const { value, set, remove, getAll, clear } = useCookies();
2843
*/
2944
export const useCookies = () => {
30-
const [value, setValue] = useState(typeof window !== 'undefined' ? getCookies(true) : {});
31-
useEffect(() => {
32-
const onChange = () => setValue(getCookies(true));
33-
window.addEventListener(COOKIE_EVENT, onChange);
34-
return () => {
35-
window.removeEventListener(COOKIE_EVENT, onChange);
45+
const [value, setValue] = useState(typeof window !== 'undefined' ? getParsedCookies() : {});
46+
useEffect(() => {
47+
const onChange = () => setValue(getParsedCookies());
48+
window.addEventListener(COOKIE_EVENT, onChange);
49+
return () => {
50+
window.removeEventListener(COOKIE_EVENT, onChange);
51+
};
52+
}, []);
53+
const set = (key, value, options) => {
54+
if (value === null)
55+
return removeCookieItem(key);
56+
setCookieItem(key, value, options);
3657
};
37-
}, []);
38-
const set = (key, value, options) => {
39-
if (value === null) return removeCookieItem(key);
40-
setCookieItem(key, value, options);
41-
};
42-
const remove = (key, options) => removeCookieItem(key, options);
43-
const getAll = () => getCookies(true);
44-
const clear = () => clearCookieItems();
45-
return { value, set, remove, getAll, clear };
58+
const remove = (key, options) => removeCookieItem(key, options);
59+
const getAll = () => getParsedCookies();
60+
const clear = () => clearCookieItems();
61+
return { value, set, remove, getAll, clear };
4662
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { useCookie } from '../useCookie/useCookie';
2+
import { useCookies } from './useCookies';
3+
4+
const POKEMONS = [
5+
{ name: 'Pikachu', index: 25 },
6+
{ name: 'Bulbasaur', index: 1 },
7+
{ name: 'Charmander', index: 4 },
8+
{ name: 'Squirtle', index: 7 },
9+
{ name: 'Jigglypuff', index: 39 },
10+
{ name: 'Gengar', index: 94 },
11+
{ name: 'Mewtwo', index: 150 },
12+
{ name: 'Mew', index: 151 },
13+
{ name: 'Charizard', index: 6 },
14+
{ name: 'Blastoise', index: 9 },
15+
{ name: 'Venusaur', index: 3 },
16+
];
17+
18+
const Demo = () => {
19+
const pokemonsCookie = useCookie('pokemon', POKEMONS[0]);
20+
const cookies = useCookies<{ name: string, id: number }>();
21+
22+
return (
23+
<div>
24+
<div>Cookies</div>
25+
<pre>{JSON.stringify(cookies.value, null, 2)}</pre>
26+
27+
<button onClick={() => pokemonsCookie.set(POKEMONS[Math.floor(Math.random() * POKEMONS.length)])}>
28+
Change user
29+
</button>
30+
<button onClick={cookies.clear}>
31+
Clear
32+
</button>
33+
</div>
34+
);
35+
};
36+
37+
export default Demo;
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { useEffect, useState } from 'react';
2+
3+
import type { RemoveCookieParams, SetCookieParams } from '../useCookie/useCookie';
4+
5+
import { COOKIE_EVENT, dispatchCookieEvent, removeCookie, setCookie } from '../useCookie/useCookie';
6+
7+
export const getParsedCookies = () =>
8+
Object.fromEntries(
9+
document.cookie.split('; ').map((cookie) => {
10+
const [key, ...value] = cookie.split('=');
11+
const decodedValue = decodeURIComponent(value.join('='));
12+
try {
13+
return [key, JSON.parse(decodedValue)];
14+
} catch {
15+
return [key, decodedValue];
16+
}
17+
})
18+
);
19+
20+
export const clearCookies = () => {
21+
document.cookie.split('; ').forEach((cookie) => {
22+
const [name] = cookie.split('=');
23+
removeCookie(name);
24+
});
25+
};
26+
27+
const setCookieItem = (key: string, value: any, options?: SetCookieParams) => {
28+
setCookie(key, value, options);
29+
dispatchCookieEvent();
30+
};
31+
32+
const removeCookieItem = (key: string, options?: RemoveCookieParams) => {
33+
removeCookie(key, options);
34+
dispatchCookieEvent();
35+
};
36+
37+
const clearCookieItems = () => {
38+
clearCookies();
39+
dispatchCookieEvent();
40+
};
41+
42+
/**
43+
* @name useCookies
44+
* @description - Hook that manages cookie values
45+
* @category Browser
46+
*
47+
* @overload
48+
* @template {object} Value The type of the cookie values
49+
* @param {string} key The key of the cookie
50+
* @returns {UseCookieReturn<Value>} The value and the set function
51+
*
52+
* @example
53+
* const { value, set, remove, getAll, clear } = useCookies();
54+
*/
55+
export const useCookies = <Value>() => {
56+
const [value, setValue] = useState<Value>(
57+
typeof window !== 'undefined' ? (getParsedCookies() as Value) : ({} as Value)
58+
);
59+
60+
useEffect(() => {
61+
const onChange = () => setValue(getParsedCookies() as Value);
62+
63+
window.addEventListener(COOKIE_EVENT, onChange);
64+
return () => {
65+
window.removeEventListener(COOKIE_EVENT, onChange);
66+
};
67+
}, []);
68+
69+
const set = (key: string, value: Value, options?: SetCookieParams) => {
70+
if (value === null) return removeCookieItem(key);
71+
setCookieItem(key, value, options);
72+
};
73+
74+
const remove = (key: string, options?: RemoveCookieParams) => removeCookieItem(key, options);
75+
const getAll = () => getParsedCookies();
76+
const clear = () => clearCookieItems();
77+
78+
return { value, set, remove, getAll, clear };
79+
};

β€Žpackages/docs/app/.vitepress/config.mtsβ€Ž

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export default async () => {
8989
{
9090
text: 'Functions',
9191
items: [
92-
{ text: 'Get Started', link: '/getting-started' },
92+
{ text: 'Get Started', link: '/introduction' },
9393
{ text: 'Installation', link: '/installation' },
9494
{ text: 'Hooks', link: '/functions/hooks/useAsync.html' }
9595
]
@@ -98,15 +98,12 @@ export default async () => {
9898
sidebar: [
9999
{
100100
text: 'Getting started',
101-
link: '/getting-started'
102-
},
103-
{
104-
text: 'Installation',
105-
link: '/installation'
106-
},
107-
{
108-
text: 'Cli',
109-
link: '/cli'
101+
items: [
102+
{ text: 'Introduction', link: '/introduction' },
103+
{ text: 'Installation', link: '/installation' },
104+
{ text: 'Config', link: '/config' },
105+
{ text: 'CLI', link: '/cli' }
106+
]
110107
},
111108
{
112109
text: 'Installation',

β€Žpackages/docs/app/cli.mdβ€Ž

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,56 @@
1-
# 🚧 In progress
1+
# CLI
2+
3+
Use the CLI to add hooks to your project with [useverse](https://www.npmjs.com/package/useverse).
4+
5+
## init
6+
7+
Use the `init` command to initialize configuration and dependencies for a new project.
8+
9+
The `init` command installs dependencies, adds configures [`reactuse.json`](./config.html).
10+
11+
```bash
12+
npx useverse@latest init
13+
```
14+
15+
## add
16+
17+
Use the `add` command to add hooks and dependencies to your project.
18+
19+
```bash
20+
npx useverse@latest add [hook]
21+
```
22+
23+
You will be presented with a list of hooks to choose from:
24+
25+
```bash
26+
Which components would you like to add? β€Ί Space to select. A to toggle all.
27+
Enter to submit.
28+
29+
β—― useActiveElement
30+
β—― useAsync
31+
β—― useBattery
32+
β—― useBluetooth
33+
β—― useBoolean
34+
β—― useBreakpoints
35+
β—― useBrowserLanguage
36+
β—― useClickOutside
37+
β—― useClipboard
38+
β—― useConst
39+
```
40+
41+
### Options
42+
43+
```bash
44+
Usage: useverse add [options] [hooks...]
45+
46+
add a hook to your project
47+
48+
Arguments:
49+
components the components to add or a url to the component.
50+
51+
Options:
52+
-o, --overwrite overwrite existing files. (default: false)
53+
-c, --cwd the working directory. defaults to the current directory.
54+
-a, --all add all available hooks. (default: false)
55+
-h, --help display help for command
56+
```

β€Žpackages/docs/app/config.mdβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# 🚧 In progress

β€Žpackages/docs/app/index.mdβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ hero:
99
actions:
1010
- theme: brand
1111
text: Get Started
12-
link: /getting-started
12+
link: /introduction
1313
- theme: alt
1414
text: View on GitHub
1515
link: https://github.com/siberiacancode/reactuse

β€Žpackages/docs/app/installation.mdβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ bun add @siberiacancode/reactuse
3030

3131
## Inject code to your framework
3232

33-
How to install dependencies and structure your app with [useverse](https://www.npmjs.com/package/useverse).
33+
How to install dependencies and structure your app with [cli](./cli.md) and [useverse](https://www.npmjs.com/package/useverse).
3434

3535
<div class="flex flex-col gap-4 md:flex-row">
3636
<a href="./frameworks/vite" target="_blank" class="w-full !no-underline">

0 commit comments

Comments
Β (0)