useFullscreen.tsx 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import {RefObject, useCallback} from 'react';
  2. import screenfull from 'screenfull';
  3. interface Props<Element extends HTMLElement> {
  4. /**
  5. * The element that this instance of `enter()` will use to go fullscreen.
  6. * Calling `useFullscreen()` a second time will create a different instance of
  7. * `ref` and `enter.
  8. */
  9. elementRef: RefObject<Element>;
  10. }
  11. interface Return {
  12. /**
  13. * Render, in fullscreen, the `ref` that this instance relates to. If `ref`
  14. * is unset, then `<html>` will be used.
  15. *
  16. * FullscreenOptions: https://developer.mozilla.org/en-US/docs/web/api/element/requestfullscreen#options_2
  17. */
  18. enter: (options?: FullscreenOptions) => void;
  19. /**
  20. * Bring the browser out of fullscreen, regardless of which DOM element is
  21. * currently active.
  22. */
  23. exit: () => void;
  24. /**
  25. * Toggle fullscreen mode on and off, for the `ref` that this instance
  26. * relates to.
  27. */
  28. toggle: () => void;
  29. }
  30. /**
  31. * Enable/Disable/Toggle fullscreen mode for a specified element.
  32. */
  33. export default function useFullscreen<Element extends HTMLElement>({
  34. elementRef,
  35. }: Props<Element>): Return {
  36. const enter = useCallback(
  37. async (opts: FullscreenOptions = {navigationUI: 'auto'}) => {
  38. if (screenfull.isEnabled && elementRef.current) {
  39. await screenfull.request(elementRef.current, opts);
  40. }
  41. },
  42. [elementRef]
  43. );
  44. const exit = useCallback(async () => {
  45. if (screenfull.isEnabled) {
  46. await screenfull.exit();
  47. }
  48. }, []);
  49. const toggle = useCallback(
  50. () => (screenfull.isFullscreen ? exit() : enter()),
  51. [enter, exit]
  52. );
  53. return {
  54. enter,
  55. exit,
  56. toggle,
  57. };
  58. }