Skip to content

Commit 2889496

Browse files
committed
[IMPL] useDocumentPIP hook
1 parent 76f259e commit 2889496

17 files changed

Lines changed: 352 additions & 52 deletions

File tree

apps/react-tools-demo/scripts/generateMarkdown.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import path from "node:path";
2+
import { existsSync } from 'node:fs';
23
import fs from 'node:fs/promises';
34
import {URL} from 'url';
45
import process from "node:process";
@@ -406,7 +407,8 @@ async function generateComponentsMarkDown() {
406407
if(file.split(".")[0].toLowerCase() === dir.toLowerCase()) {
407408
const extension = componentFileName.endsWith(".tsx") ? ".tsx" : ".md";
408409
let componentFile = await fs.readFile(path.join(pathComponentDir, "hooks", dir, componentFileName), {encoding: "utf8"});
409-
const hookFileName = (componentFileName.charAt(0).toLowerCase()+componentFileName.substring(1)).replace(extension, ".ts");
410+
let hookFileName = (componentFileName.charAt(0).toLowerCase() + componentFileName.substring(1)).replace(extension, ".ts");
411+
!existsSync(path.join(pathHooksDir, hookFileName)) && (hookFileName = (componentFileName.charAt(0).toLowerCase() + componentFileName.substring(1)).replace(extension, ".tsx"));
410412
let hookFile = await fs.readFile(path.join(pathHooksDir, hookFileName), {encoding: "utf8"});
411413
componentFile = removeImportLine(componentFile);
412414
hookFile = removeImportLine(hookFile);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { useCallback, useState } from "react";
2+
import { useDocumentPIP } from "../../../../../../packages/react-tools/src";
3+
4+
/**
5+
The component uses _useDocumentPIP_ hook to show in a separate window the counter showed renderes by the component.
6+
*/
7+
export const UseDocumentPIP = () => {
8+
const [show, setShow] = useState(true);
9+
const [c, setC] = useState(0);
10+
const { isSupported, openPIP, PipWindow, closePIP } = useDocumentPIP({
11+
onOpened: useCallback(() => setShow(false), []),
12+
onClose: useCallback(() => setShow(true), [])
13+
});
14+
15+
return <div>
16+
<p>Window Counter</p>
17+
<button onClick={() => setC(c => c + 1)}>{c}</button>
18+
<p>Supported: {isSupported ? 'Yes' : 'No'}</p>
19+
{
20+
show &&
21+
<>
22+
<div>
23+
<button
24+
onClick={() => openPIP({
25+
inheritCSS: true
26+
})}
27+
>
28+
Open PIP
29+
</button>
30+
</div>
31+
</>
32+
}
33+
<PipWindow>
34+
<div style={{display: 'flex', flexDirection: "column", alignItems: "center", width: "100%", gap: 20}}>
35+
<h4 style={{textAlign: "center"}}>PIP Window Counter</h4>
36+
<button onClick={() => setC(c => c + 1)}>{c}</button>
37+
<button onClick={closePIP}>Close</button>
38+
</div>
39+
</PipWindow>
40+
</div>
41+
}

apps/react-tools-demo/src/components/hooks/useIdle/UseIdle.tsx renamed to apps/react-tools-demo/src/components/hooks/useIdleCallback/UseIdleCallback.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import { useState } from "react"
2-
import { useIdle } from "../../../../../../packages/react-tools/src";
2+
import { useIdleCallback } from "../../../../../../packages/react-tools/src";
33

44

55
/**
66
The component has:
77
- a __iterations__ variable of type string.
88
- a __log__ variable of type string.
9-
- a function __invoke__ returned from _useIdle_ hook, initialized with a cb that update __log__ variable with message _"RequestIdleCallback executed"_.
9+
- a function __invoke__ returned from _useIdleCallback_ hook, initialized with a cb that update __log__ variable with message _"RequestIdleCallback executed"_.
1010
- a button start that when clicked executes __start__ function that executes __invoke__ function and updates __iterations__ variable inside a loop with iteration index.
1111
*/
12-
export const UseIdle = () => {
12+
export const UseIdleCallback = () => {
1313
const [iterations, setIterations] = useState(0);
1414
const [log, setLog] = useState("");
15-
const [invoke] = useIdle(() => setLog("RequestIdleCallback executed"));
15+
const [invoke] = useIdleCallback(() => setLog("RequestIdleCallback executed"));
1616

1717
const start = async() => {
1818
invoke();

apps/react-tools-demo/src/components/hooks/usePIP/UsePIP.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ export const UsePIP = () => {
1010
const [show, setShow] = useState(true);
1111
const { isSupported, openPIP } = usePIP({
1212
target: videoRef,
13-
onOpened: () => setShow(false),
14-
onClosed: () => setShow(true)
13+
onOpen: () => setShow(false),
14+
onClose: () => setShow(true)
1515
});
1616

1717
return <div>

apps/react-tools-demo/src/constants/components.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export const COMPONENTS = [
8787
"useColorScheme",
8888
"useReducedMotion",
8989
"useTitle",
90-
"useIdle",
90+
"useIdleCallback",
9191
"useFullscreen",
9292
"useBattery",
9393
"useGeolocation",
@@ -102,7 +102,8 @@ export const COMPONENTS = [
102102
"useSpeechRecognition",
103103
"useSpeechSynthesis",
104104
"useFPS",
105-
"usePIP"
105+
"usePIP",
106+
"useDocumentPIP"
106107
]
107108
],
108109
//UTILS
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# useDocumentPIP
2+
Hook to use Document PIP [(Document-Picture-in-Picture API)](https://developer.mozilla.org/en-US/docs/Web/API/Document_Picture-in-Picture_API).
3+
4+
## Usage
5+
6+
```tsx
7+
export const UseDocumentPIP = () => {
8+
const [show, setShow] = useState(true);
9+
const [c, setC] = useState(0);
10+
const { isSupported, openPIP, PipWindow, closePIP } = useDocumentPIP({
11+
onOpened: useCallback(() => setShow(false), []),
12+
onClose: useCallback(() => setShow(true), [])
13+
});
14+
15+
return <div>
16+
<p>Window Counter</p>
17+
<button onClick={() => setC(c => c + 1)}>{c}</button>
18+
<p>Supported: {isSupported ? 'Yes' : 'No'}</p>
19+
{
20+
show &&
21+
<>
22+
<div>
23+
<button
24+
onClick={() => openPIP({
25+
inheritCSS: true
26+
})}
27+
>
28+
Open PIP
29+
</button>
30+
</div>
31+
</>
32+
}
33+
<PipWindow>
34+
<div style={{display: 'flex', flexDirection: "column", alignItems: "center", width: "100%", gap: 20}}>
35+
<h4 style={{textAlign: "center"}}>PIP Window Counter</h4>
36+
<button onClick={() => setC(c => c + 1)}>{c}</button>
37+
<button onClick={closePIP}>Close</button>
38+
</div>
39+
</PipWindow>
40+
</div>
41+
}
42+
```
43+
44+
> The component uses _useDocumentPIP_ hook to show in a separate window the counter showed renderes by the component.
45+
46+
47+
## API
48+
49+
```tsx
50+
useDocumentPIP({ options: { inheritCSS, window: wind } = { window: { height: 300, width: 450 } }, onOpen, onOpened, onClose, onError }: UseDocumentPIPProps): UseDocumentPIPResult
51+
```
52+
53+
> ### Params
54+
>
55+
> - __param__: _UseDocumentPIPProps_
56+
object
57+
> - __param.options?__: _DocumentPIPOptions_
58+
object
59+
> - __param.options.inheritCSS?__: _boolean_
60+
boolean that indicates if PIP window will inherit CSS from main window.
61+
> - __param.options.window?__: _Object_
62+
object
63+
> - __param.options.width=450?__: _number_
64+
number that indicates PIP window width. Default value is 450.
65+
> - __param.options.height=300?__: _number_
66+
number that indicates PIP window height. Default value is 300.
67+
> - __param.onOpen?__: _()=>void_
68+
function that will be executed on PIP opening.
69+
> - __param.onOpened?__: _(evt: DocumentPictureInPictureEvent)=>void_
70+
function that will be executed when PIP is opened.
71+
> - __param.onClose?__: _(evt: PageTransitionEvent)=>void_
72+
function that will be executed on PIP closing.
73+
> - __param.onError?__: _(err: unknown)=>void_
74+
function that will be executed when error is throwing.
75+
>
76+
77+
> ### Returns
78+
>
79+
> __result__: _UseDocumentPIPResult_
80+
> Object with four properties:
81+
> - __isSupported__: boolean that indicates if PIP is supported or not.
82+
> - __openPIP__: function to open PIP.
83+
> - __closePIP__: function to close PIP.
84+
> - __PipWindow__: Component that wraps the element to render in Document Picture in Picture.
85+
>

apps/react-tools-demo/src/markdown/useIdle.md renamed to apps/react-tools-demo/src/markdown/useIdleCallback.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
# useIdle
1+
# useIdleCallback
22
Hook to invoke a callback when the browser is idle. Refer to [requestIdleCallback](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback) in React. The __options__ parameter differs from _IdleRequestOptions_ type: it adds the possibility to pass another property __unsupportedBehavior__ to specify what do if requestIdleCallback is not supported.
33

44
## Usage
55

66
```tsx
7-
export const UseIdle = () => {
7+
export const UseIdleCallback = () => {
88
const [iterations, setIterations] = useState(0);
99
const [log, setLog] = useState("");
10-
const [invoke] = useIdle(() => setLog("RequestIdleCallback executed"));
10+
const [invoke] = useIdleCallback(() => setLog("RequestIdleCallback executed"));
1111

1212
const start = async() => {
1313
invoke();
@@ -31,14 +31,14 @@ export const UseIdle = () => {
3131
> The component has:
3232
> - a __iterations__ variable of type string.
3333
> - a __log__ variable of type string.
34-
> - a function __invoke__ returned from _useIdle_ hook, initialized with a cb that update __log__ variable with message _"RequestIdleCallback executed"_.
34+
> - a function __invoke__ returned from _useIdleCallback_ hook, initialized with a cb that update __log__ variable with message _"RequestIdleCallback executed"_.
3535
> - a button start that when clicked executes __start__ function that executes __invoke__ function and updates __iterations__ variable inside a loop with iteration index.
3636
3737

3838
## API
3939

4040
```tsx
41-
useIdle(cb: (deadline?: IdleDeadline | DOMHighResTimeStamp | void) => void, opts?: {timeout: number , unsupportedBehavior?: "animationFrame" | "timeout" | "immediatly" }): [() => void, () => void]
41+
useIdleCallback(cb: (deadline?: IdleDeadline | DOMHighResTimeStamp | void) => void, opts?: {timeout: number , unsupportedBehavior?: "animationFrame" | "timeout" | "immediatly" }): [() => void, () => void]
4242
```
4343

4444
> ### Params

apps/react-tools-demo/src/markdown/usePIP.md

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,32 @@
1-
#
2-
Hook to use PIP [(Picture-in-Picture API)](https://developer.mozilla.org/en-US/docs/Web/API/Picture-in-Picture_API)
1+
# usePIP
2+
Hook to use PIP [(Picture-in-Picture API)](https://developer.mozilla.org/en-US/docs/Web/API/Picture-in-Picture_API).
33

44
## Usage
55

66
```tsx
77
export const UsePIP = () => {
88
const videoRef = useRef<HTMLVideoElement>(null);
99
const [show, setShow] = useState(true);
10-
const { openPIP } = usePIP({target: videoRef})
10+
const { isSupported, openPIP } = usePIP({
11+
target: videoRef,
12+
onOpen: () => setShow(false),
13+
onClose: () => setShow(true)
14+
});
1115

1216
return <div>
13-
<video ref={videoRef} width="400" controls>
14-
<source src={video} type="video/mp4"/>
15-
Your browser does not support HTML video.
16-
</video>
17-
<div>
18-
<button onClick={openPIP}>Open PIP</button>
19-
</div>
17+
<p>Supported: {isSupported ? 'Yes' : 'No'}</p>
18+
{
19+
show &&
20+
<>
21+
<video ref={videoRef} width="400" controls>
22+
<source src={video} type="video/mp4" />
23+
Your browser does not support HTML video.
24+
</video>
25+
<div>
26+
<button onClick={openPIP}>Open PIP</button>
27+
</div>
28+
</>
29+
}
2030
</div>
2131
}
2232
```
@@ -27,7 +37,7 @@ export const UsePIP = () => {
2737
## API
2838

2939
```tsx
30-
usePIP = ({ onOpen, onOpened, onClose, onError, target }: UsePIPProps): UsePIPResult
40+
usePIP({ onOpen, onOpened, onClose, onError, target }: UsePIPProps): UsePIPResult
3141
```
3242

3343
> ### Params
@@ -37,11 +47,11 @@ object
3747
> - __param.target__: _RefObject<HTMLVideoElement>|HTMLVideoElement_
3848
element to PIP.
3949
> - __param.onOpen?__: _()=>void_
40-
function that will be executed before open PIP.
50+
function that will be executed on PIP opening.
4151
> - __param.onOpened?__: _(pip: PictureInPictureWindow)=>void_
4252
function that will be executed when PIP is opened.
43-
> - __param.onClose?__: _()=>void_
44-
function that will be executed when PIP is closed.
53+
> - __param.onClose?__: _(evt: PictureInPictureEvent)=>void_
54+
function that will be executed on PIP closing.
4555
> - __param.onError?__: _(err: unknown)=>void_
4656
function that will be executed when error is throwing.
4757
>

packages/react-tools/README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
- [x] useColorScheme
9090
- [x] useReducedMotion
9191
- [x] useTitle
92-
- [x] useIdle
92+
- [x] useIdleCallback
9393
- [x] useFullscreen
9494
- [x] useBattery
9595
- [x] useGeolocation
@@ -104,8 +104,8 @@
104104
- [x] useSpeechRecognition
105105
- [x] useSpeechSynthesis
106106
- [x] useFPS
107-
- [ ] useDocumentPIP (https://developer.mozilla.org/en-US/docs/Web/API/Document_Picture-in-Picture_API)
108107
- [x] usePIP
108+
- [x] useDocumentPIP
109109
- [ ] useIdleDetection (https://developer.mozilla.org/en-US/docs/Web/API/Idle_Detection_API)
110110
- [ ] usePopover (https://developer.mozilla.org/en-US/docs/Web/API/Popover_API)
111111
- [ ] useRemotePlayback (https://developer.mozilla.org/en-US/docs/Web/API/Remote_Playback_API)
@@ -126,8 +126,7 @@
126126
- [ ] useMediaDevices
127127
- [ ] useMediaStream
128128
- [ ] useObservable — tracks latest value of an Observable
129-
- [ ] usePointerLock (https://vueuse.org/core/usePointerLock/)
130-
- [ ] usePointerTouchSwipe (https://vueuse.org/core/usePointerSwipe/ https://vueuse.org/core/useSwipe/)
129+
- [ ] usePointerTouchSwipe (https://vueuse.org/core/usePointerSwipe/ https://vueuse.org/core/useSwipe/)
131130
- [ ] useLock - (https://developer.mozilla.org/en-US/docs/Web/API/LockManager/request)
132131
- [ ] useIndexedDB
133132
- [ ] useWebWorker (https://vueuse.org/core/useWebWorker/)

packages/react-tools/src/hooks/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export { useIsOnline } from './useIsOnline';
5151
export { useResizeObserver } from './useResizeObserver';
5252
export { useIntersectionObserver } from './useIntersectionObserver';
5353
export { useMutationObserver } from './useMutationObserver';
54-
export { useIdle } from './useIdle';
54+
export { useIdleCallback } from './useIdleCallback';
5555
export { useRaf } from './useRaf';
5656
export { useMeasure } from './useMeasure';
5757
export { useFullscreen } from './useFullscreen';
@@ -82,4 +82,5 @@ export { useSpeechRecognition } from './useSpeechRecognition';
8282
export { useSpeechSynthesis } from './useSpeechSynthesis';
8383
export { useFPS } from './useFPS';
8484
export { usePointerLock } from './usePointerLock';
85-
export { usePIP } from './usePIP';
85+
export { usePIP } from './usePIP';
86+
export { useDocumentPIP } from './useDocumentPIP';

0 commit comments

Comments
 (0)