Skip to content

Commit 901d644

Browse files
committed
[WIP] usePopover
1 parent 53e4a9d commit 901d644

4 files changed

Lines changed: 49 additions & 1 deletion

File tree

apps/react-tools-demo/src/components/hooks/usePrevious/UsePrevious.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ function UsePrevious() {
1515
const [count, setCount] = useState(0);
1616
const [previous, toggleTrack] = usePrevious(count);
1717

18+
1819
return (<>
1920
<button onClick={() => setCount((count) => {
2021
const val = count + 1;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { useCallback } from "react";
2+
import { useId } from "..";
3+
import { UsePopoverProps } from "../models";
4+
5+
function usePopover<T extends HTMLElement>({ refBtn, refPopover, mode, buttonTrigger }: { refBtn: UsePopoverProps<T>["refBtn"], refPopover: UsePopoverProps<T>["refPopover"], mode: UsePopoverProps<T>["mode"], buttonTrigger: "on/off" }): { open: () => void, close: () => void };
6+
function usePopover<T extends HTMLElement>({ refBtn, refPopover, mode, buttonTrigger }: { refBtn: UsePopoverProps<T>["refBtn"], refPopover: UsePopoverProps<T>["refPopover"], mode: UsePopoverProps<T>["mode"], buttonTrigger: "toggle" }): { toggle: (isOpen: boolean) => void };
7+
function usePopover<T extends HTMLElement>({ refBtn, refPopover, mode, buttonTrigger }: UsePopoverProps<T>): { open: () => void, close: () => void } | { toggle: (isOpen: boolean) => void } {
8+
const isSupported = refPopover.current ? "showPopover" in refPopover.current : false;
9+
const id = useId();
10+
if (refPopover.current) {
11+
if (isSupported) {
12+
refPopover.current.setAttribute("popover", mode);
13+
!refPopover.current.id && (refPopover.current.id = id);
14+
}
15+
}
16+
if (refBtn.current) {
17+
if (isSupported) {
18+
refBtn.current.setAttribute("popovertarget", refPopover.current?.id || "");
19+
refBtn.current.setAttribute("popovertargetaction", buttonTrigger);
20+
}
21+
}
22+
23+
const open = useCallback(() => refPopover.current && "showPopover" in refPopover.current && refPopover.current.showPopover(), [refPopover]);
24+
const close = useCallback(() => refPopover.current && "showPopover" in refPopover.current && refPopover.current.hidePopover(), [refPopover]);
25+
const toggle = useCallback(() => refPopover.current && "showPopover" in refPopover.current && refPopover.current.togglePopover(), [refPopover]);
26+
27+
if (buttonTrigger === "on/off") {
28+
return {
29+
open,
30+
close
31+
}
32+
}
33+
return {
34+
toggle
35+
}
36+
}
37+
38+
export { usePopover };

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ export type { SpeechSynthesisSpeakParam, UseSpeechSynthesis, UseSpeechSynthesisP
1414
export type { UseFPSProps, UseFPSResult } from './useFPS.model';
1515
export type { UsePointerLockProps, UsePointerLockResult } from './usePointerLock.model';
1616
export type { UsePIPProps, UsePIPResult } from './usePIP.model';
17-
export type { DocumentPictureInPictureEvent, DocumentPIPOptions, UseDocumentPIPProps, UseDocumentPIPResult } from './useDocumentPIP.model';
17+
export type { DocumentPictureInPictureEvent, DocumentPIPOptions, UseDocumentPIPProps, UseDocumentPIPResult } from './useDocumentPIP.model';
18+
export type { UsePopoverProps } from './usePopover.model';
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { RefObject } from "react"
2+
3+
export interface UsePopoverProps<T extends HTMLElement> {
4+
refBtn: RefObject<HTMLButtonElement>;
5+
refPopover: RefObject<T>;
6+
mode: "auto" | "manual",
7+
buttonTrigger: "on/off" | "toggle"
8+
}

0 commit comments

Comments
 (0)