|
- import * as React from 'react';
- import { getFormValues } from '@theoryofnekomata/formxtra';
-
- export interface UseImageControlsOptions {
- actionFormKey?: string;
- forwardedRef?: React.Ref<HTMLImageElement>;
- }
-
- export const useImageControls = (options = {} as UseImageControlsOptions) => {
- const { actionFormKey = 'action' as const, forwardedRef } = options;
- const [fullScreen, setFullScreen] = React.useState(false);
- const defaultRef = React.useRef<HTMLImageElement>(null);
- const imageRef = forwardedRef ?? defaultRef;
- const filenameRef = React.useRef<HTMLElement>(null);
-
- React.useEffect(() => {
- if (fullScreen) {
- window.document.body.style.overflow = 'hidden';
- }
-
- if (!fullScreen) {
- window.document.body.style.overflow = '';
- }
- }, [fullScreen]);
-
- const toggleFullScreen = React.useCallback(() => {
- setFullScreen((b) => !b);
- }, []);
-
- const download = React.useCallback(() => {
- if (!(typeof imageRef === 'object' && imageRef?.current !== null)) {
- return;
- }
-
- if (!(typeof filenameRef === 'object' && filenameRef?.current !== null)) {
- return;
- }
-
- const downloadLink = window.document.createElement('a');
- downloadLink.download = filenameRef.current.textContent ?? 'image';
- downloadLink.href = imageRef.current.currentSrc;
- downloadLink.addEventListener('click', () => {
- downloadLink.remove();
- });
- downloadLink.click();
- }, [imageRef, filenameRef]);
-
- const actions = React.useMemo(() => ({
- toggleFullScreen,
- download,
- }), [toggleFullScreen, download]);
-
- const handleAction: React.FormEventHandler<HTMLFormElement> = React.useCallback((e) => {
- e.preventDefault();
- const nativeEvent = e.nativeEvent as unknown as { submitter: HTMLElement };
- const formData = getFormValues(
- e.currentTarget,
- {
- submitter: nativeEvent.submitter,
- }
- );
- const actionName = formData[actionFormKey] as keyof typeof actions;
- const { [actionName]: actionFunction } = actions;
- actionFunction?.();
- }, [actions, actionFormKey]);
-
- return React.useMemo(() => ({
- fullScreen,
- handleAction,
- imageRef,
- filenameRef,
- }), [fullScreen, handleAction, imageRef, filenameRef]);
- };
|