Skip to content

Commit 8d1eb4e

Browse files
committed
main 🧊 add new demo
1 parent 7f2cb38 commit 8d1eb4e

34 files changed

Lines changed: 2588 additions & 81 deletions

‎packages/core/src/hooks/useBatchedCallback/useBatchedCallback.demo.tsx‎

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,10 @@ const Demo = () => {
5959
</div>
6060

6161
<div className='flex flex-col gap-6 px-6 md:flex-row'>
62-
<p className='text-muted-foreground text-left text-xs'>
62+
<p className='text-muted-foreground text-center text-left text-xs'>
6363
We batch analytics events for economy of scale. So far we tracked{' '}
6464
<code>{totalEvents}</code> events and sent <code>{requestsSent}</code> requests.
6565
</p>
66-
67-
<button disabled={!tags.length} type='button'>
68-
Continue
69-
</button>
7066
</div>
7167
</section>
7268
);

‎packages/core/src/hooks/useControllableState/useControllableState.demo.tsx‎

Lines changed: 129 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,146 @@
1-
import { useControllableState, useDisclosure } from '@siberiacancode/reactuse';
2-
3-
interface CollapseProps {
4-
children: React.ReactNode;
5-
defaultOpen?: boolean;
6-
isOpen?: boolean;
7-
title: string;
8-
onToggle?: (isOpen: boolean) => void;
1+
import type { ComponentProps } from 'react';
2+
3+
import { useControllableState } from '@siberiacancode/reactuse';
4+
import { useState } from 'react';
5+
6+
interface SwitchProps extends Omit<ComponentProps<'input'>, 'onChange' | 'value'> {
7+
initialValue?: boolean;
8+
value?: boolean;
9+
onChange?: (value: boolean) => void;
910
}
1011

11-
const Collapse = ({ title, children, isOpen, defaultOpen = false, onToggle }: CollapseProps) => {
12-
const [isOpenState, setIsOpenState] = useControllableState({
13-
value: isOpen,
14-
initialValue: defaultOpen,
15-
onChange: onToggle
12+
const Switch = ({ value, initialValue, onChange, ...props }: SwitchProps) => {
13+
const [checked, setChecked] = useControllableState({
14+
value,
15+
initialValue: initialValue ?? false,
16+
onChange
1617
});
1718

1819
return (
19-
<div
20-
className='cursor-pointer rounded border border-2 border-dashed border-[var(--vp-c-brand-2)] transition-colors duration-300 hover:border-[var(--vp-c-brand-1)]'
21-
onClick={() => setIsOpenState(!isOpenState)}
22-
>
23-
<div className='flex items-center justify-between p-3'>
24-
<div className='font-semibold'>{title}</div>
25-
<div>{isOpenState ? '-' : '+'}</div>
26-
</div>
27-
28-
{isOpenState && <div className='p-3'>{children}</div>}
29-
</div>
20+
<input
21+
{...props}
22+
checked={checked ?? false}
23+
role='switch'
24+
type='checkbox'
25+
onChange={(event) => setChecked(event.target.checked)}
26+
/>
3027
);
3128
};
3229

30+
interface Preferences {
31+
analytics: boolean;
32+
autoSave: boolean;
33+
darkMode: boolean;
34+
marketing: boolean;
35+
notifications: boolean;
36+
}
37+
38+
const SETTINGS = [
39+
{
40+
key: 'notifications',
41+
label: 'Notifications',
42+
description: 'Get notified about important updates'
43+
},
44+
{
45+
key: 'darkMode',
46+
label: 'Dark mode',
47+
description: 'Use dark theme across the app'
48+
},
49+
{
50+
key: 'autoSave',
51+
label: 'Auto-save',
52+
description: 'Save changes automatically as you type'
53+
},
54+
{
55+
key: 'analytics',
56+
label: 'Analytics',
57+
description: 'Help us improve by sharing usage data'
58+
},
59+
{
60+
key: 'marketing',
61+
label: 'Marketing emails',
62+
description: 'Receive product news and offers'
63+
}
64+
] as const;
65+
66+
const ALL_OFF = {
67+
notifications: false,
68+
darkMode: false,
69+
autoSave: false,
70+
analytics: false,
71+
marketing: false
72+
} as const;
73+
74+
const ALL_ON: Preferences = {
75+
notifications: true,
76+
darkMode: true,
77+
autoSave: true,
78+
analytics: true,
79+
marketing: true
80+
};
81+
82+
const RECOMMENDED: Preferences = {
83+
notifications: true,
84+
darkMode: true,
85+
autoSave: true,
86+
analytics: true,
87+
marketing: false
88+
};
89+
3390
const Demo = () => {
34-
const controlledCollapse = useDisclosure(false);
91+
const [preferences, setPreferences] = useState<Preferences>(ALL_OFF);
3592

3693
return (
37-
<>
38-
<Collapse defaultOpen={true} title='Uncontrolled Collapse'>
39-
<p>
40-
<code>Uncontrolled</code> - component manages its own state internally. You provide
41-
initial value via defaultOpen prop.
42-
</p>
43-
</Collapse>
44-
45-
<br />
46-
47-
<Collapse
48-
isOpen={controlledCollapse.opened}
49-
title='Controlled Collapse'
50-
onToggle={controlledCollapse.toggle}
51-
>
52-
<p>
53-
<code>Controlled</code> - parent component controls the state via isOpen prop and receives
54-
updates through onToggle callback.
55-
</p>
56-
</Collapse>
57-
58-
<div className='mt-4 flex flex-wrap gap-1'>
59-
<button type='button' onClick={() => controlledCollapse.toggle()}>
60-
{controlledCollapse.opened ? 'Close' : 'Open'}
61-
</button>
94+
<section className='flex min-w-sm flex-col gap-6 md:min-w-md'>
95+
<div className='flex flex-col gap-2'>
96+
<h3>Preferences</h3>
97+
<p className='text-muted-foreground'>Manage how the app behaves.</p>
98+
</div>
6299

63-
<button type='button' onClick={() => controlledCollapse.toggle()}>
64-
Toggle
100+
<div className='flex flex-wrap items-center gap-2'>
101+
<button data-variant='outline' type='button' onClick={() => setPreferences(ALL_ON)}>
102+
All on
103+
</button>
104+
<button data-variant='outline' type='button' onClick={() => setPreferences(ALL_OFF)}>
105+
All off
106+
</button>
107+
<button data-variant='outline' type='button' onClick={() => setPreferences(RECOMMENDED)}>
108+
Recommended
65109
</button>
66110
</div>
67-
</>
111+
112+
<div className='flex flex-col'>
113+
{SETTINGS.map((setting) => (
114+
<div key={setting.key} className='flex items-center justify-between gap-4 py-3'>
115+
<div className='flex flex-col gap-1'>
116+
<label htmlFor={setting.key}>{setting.label}</label>
117+
<p className='text-muted-foreground text-xs'>{setting.description}</p>
118+
</div>
119+
120+
<Switch
121+
id={setting.key}
122+
value={preferences[setting.key]}
123+
onChange={(value) =>
124+
setPreferences((current) => ({ ...current, [setting.key]: value }))
125+
}
126+
/>
127+
</div>
128+
))}
129+
130+
<div className='border-border mt-2 border-t pt-2'>
131+
<div className='flex items-center justify-between gap-4 py-3'>
132+
<div className='flex flex-col gap-1'>
133+
<label htmlFor='beta'>Beta features</label>
134+
<p className='text-muted-foreground text-xs'>
135+
Independent toggle — managed inside the component
136+
</p>
137+
</div>
138+
139+
<Switch id='beta' initialValue={false} />
140+
</div>
141+
</div>
142+
</div>
143+
</section>
68144
);
69145
};
70146

‎packages/newdocs/content/docs/(root)/functions.mdx‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,12 @@ A quick list of available functions.
1818
- [useBoolean](/functions/hooks/useBoolean): Hook provides opportunity to manage boolean state
1919
- [useBreakpoints](/functions/hooks/useBreakpoints): Hook that manages breakpoints
2020
- [useBroadcastChannel](/functions/hooks/useBroadcastChannel): that provides cross-tab/window communication
21-
- [useBrowserLanguage](/functions/hooks/useBrowserLanguage): Hook that returns the current browser language
21+
- [useBrowserLanguage](/functions/hooks/useBrowserLanguage): Hook that returns the current browser language
22+
- [useBrowserLocation](/functions/hooks/useBrowserLocation): Hook that returns reactive browser location state with navigation controls
23+
- [useClickOutside](/functions/hooks/useClickOutside): Hook to handle click events outside the specified target element(s)
24+
- [useClipboard](/functions/hooks/useClipboard): Hook that manages a copy to clipboard
25+
- [useConst](/functions/hooks/useConst): Hook that returns the constant value
26+
- [useControllableState](/functions/hooks/useControllableState): Hook that manages both controlled and uncontrolled state patterns
27+
- [useCookie](/functions/hooks/useCookie): Hook that manages cookie value
28+
- [useCookies](/functions/hooks/useCookies): Hook that manages cookie values
29+
- [useCopy](/functions/hooks/useCopy): Hook that manages copying text with status reset

‎packages/newdocs/content/functions/hooks/meta.json‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"pages": [
33

44
"---elements---",
5-
"useActiveElement","useAutoScroll",
5+
"useActiveElement","useAutoScroll","useClickOutside",
66

77
"---async---",
88
"useAsync",
@@ -11,13 +11,13 @@
1111
"useAsyncEffect",
1212

1313
"---browser---",
14-
"useAudio","useBattery","useBluetooth","useBreakpoints","useBroadcastChannel",
14+
"useAudio","useBattery","useBluetooth","useBreakpoints","useBroadcastChannel","useBrowserLocation","useClipboard","useCopy",
1515

1616
"---utilities---",
17-
"useBatchedCallback",
17+
"useBatchedCallback","useConst",
1818

1919
"---state---",
20-
"useBoolean",
20+
"useBoolean","useControllableState","useCookie","useCookies",
2121

2222
"---user---",
2323
"useBrowserLanguage"

‎packages/newdocs/content/functions/hooks/useBatchedCallback.meta.json‎

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
title: useBrowserLocation
3+
description: Hook that returns reactive browser location state with navigation controls
4+
category: browser
5+
usage: medium
6+
type: hook
7+
isTest: true
8+
isDemo: true
9+
lastModifiedTime: 1775744706000
10+
---
11+
12+
import metadata from './useBrowserLocation.meta.json';
13+
14+
<FunctionBanner browserapi={metadata.browserapi} code={metadata.demo} type={metadata.type} name={metadata.name} language="tsx" />
15+
16+
## Installation
17+
18+
<FunctionTabs>
19+
<TabsList>
20+
<TabsTrigger value='library'>Library</TabsTrigger>
21+
<TabsTrigger value='cli'>CLI</TabsTrigger>
22+
<TabsTrigger value='manual'>Manual</TabsTrigger>
23+
</TabsList>
24+
<TabsContent value='library'>
25+
```packages-install
26+
npm install @siberiacancode/reactuse
27+
```
28+
</TabsContent>
29+
<TabsContent value='cli'>
30+
```packages-install
31+
npx useverse@latest add useBrowserLocation
32+
```
33+
</TabsContent>
34+
<TabsContent value='manual'>
35+
<Steps>
36+
<Step>
37+
Copy and paste the following code into your project.
38+
</Step>
39+
<FunctionCode code={metadata.code} language="tsx" />
40+
<Step>
41+
Update the import paths to match your project setup.
42+
</Step>
43+
</Steps>
44+
</TabsContent>
45+
</FunctionTabs>
46+
47+
## Usage
48+
49+
```tsx
50+
const { value, push, back, forward, go } = useBrowserLocation();
51+
```
52+
53+
## Type Declarations
54+
55+
<FunctionCode code={metadata.typeDeclarations} language="tsx" />
56+
<FunctionApi apiParameters={metadata.apiParameters} />
57+
58+
## Contributors
59+
60+
<FunctionContributors contributors={metadata.contributors} />

‎packages/newdocs/content/functions/hooks/useBrowserLocation.meta.json‎

Lines changed: 104 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
title: useClickOutside
3+
description: Hook to handle click events outside the specified target element(s)
4+
category: elements
5+
usage: necessary
6+
type: hook
7+
isTest: true
8+
isDemo: true
9+
lastModifiedTime: 1775645190000
10+
---
11+
12+
import metadata from './useClickOutside.meta.json';
13+
14+
<FunctionBanner browserapi={metadata.browserapi} code={metadata.demo} type={metadata.type} name={metadata.name} language="tsx" />
15+
16+
## Installation
17+
18+
<FunctionTabs>
19+
<TabsList>
20+
<TabsTrigger value='library'>Library</TabsTrigger>
21+
<TabsTrigger value='cli'>CLI</TabsTrigger>
22+
<TabsTrigger value='manual'>Manual</TabsTrigger>
23+
</TabsList>
24+
<TabsContent value='library'>
25+
```packages-install
26+
npm install @siberiacancode/reactuse
27+
```
28+
</TabsContent>
29+
<TabsContent value='cli'>
30+
```packages-install
31+
npx useverse@latest add useClickOutside
32+
```
33+
</TabsContent>
34+
<TabsContent value='manual'>
35+
<Steps>
36+
<Step>
37+
Copy and paste the following code into your project.
38+
</Step>
39+
<FunctionCode code={metadata.code} language="tsx" />
40+
<Step>
41+
Update the import paths to match your project setup.
42+
</Step>
43+
</Steps>
44+
</TabsContent>
45+
</FunctionTabs>
46+
47+
## Usage
48+
49+
```tsx
50+
useClickOutside(ref, () => console.log('click outside'));
51+
// or
52+
const ref = useClickOutside<HTMLDivElement>(() => console.log('click outside'));
53+
```
54+
55+
## Type Declarations
56+
57+
<FunctionCode code={metadata.typeDeclarations} language="tsx" />
58+
<FunctionApi apiParameters={metadata.apiParameters} />
59+
60+
## Contributors
61+
62+
<FunctionContributors contributors={metadata.contributors} />

‎packages/newdocs/content/functions/hooks/useClickOutside.meta.json‎

Lines changed: 275 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)