From 49be9d210f2ea6d61afd218a0dbf0a6e98e896f8 Mon Sep 17 00:00:00 2001 From: DJ Date: Thu, 11 Feb 2021 17:55:01 -0500 Subject: [PATCH] feat(react-tinacms-inline): add useFieldRef hook --- .../@tinacms/rbie/src/hooks/use-field-ref.ts | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 packages/@tinacms/rbie/src/hooks/use-field-ref.ts diff --git a/packages/@tinacms/rbie/src/hooks/use-field-ref.ts b/packages/@tinacms/rbie/src/hooks/use-field-ref.ts new file mode 100644 index 0000000000..2c066f3e81 --- /dev/null +++ b/packages/@tinacms/rbie/src/hooks/use-field-ref.ts @@ -0,0 +1,66 @@ +import * as React from 'react' +import { useCMS } from 'tinacms' + +export const useFieldRef = (formId: string, fieldName: string) => { + const [node, setNode] = React.useState(null) as any + + const cms = useCMS() // this is one instance where we need an "anywhere event bus" https://github.com/tinacms/rfcs/blob/ddb360eec21f91f1331ee18f49fc64cc4a69a2e7/0013-tina-anywhere.md#event-bus-as-the-primary-thing-doer + + const handleClick = React.useCallback( + (e: React.MouseEvent) => { + e.preventDefault() + e.stopPropagation() + cms.events.dispatch({ + type: `form:${formId}:fields:${fieldName}:focus`, + form: formId, + field: fieldName, + }) + }, + [cms.events, formId, fieldName] + ) + + const handleHoverStart = React.useCallback( + (e: React.MouseEvent) => { + e.preventDefault() + e.stopPropagation() + cms.events.dispatch({ + type: `form:${formId}:fields:${fieldName}:attentionStart`, + form: formId, + field: fieldName, + }) + }, + [cms.events, formId, fieldName] + ) + + const handleHoverEnd = React.useCallback( + (e: React.MouseEvent) => { + e.preventDefault() + e.stopPropagation() + cms.events.dispatch({ + type: `form:${formId}:fields:${fieldName}:attentionEnd`, + form: formId, + field: fieldName, + }) + }, + [cms.events, formId, fieldName] + ) + + React.useEffect(() => { + if (!node) return + + if (cms.enabled) { + node.addEventListener('click', handleClick) + node.addEventListener('mouseover', handleHoverStart) + node.addEventListener('mouseout', handleHoverEnd) + } + return () => { + node.removeEventListener('click', handleClick) + node.removeEventListener('mouseover', handleHoverStart) + node.removeEventListener('mouseout', handleHoverEnd) + } + }, [node, cms.enabled, handleClick, handleHoverStart, handleHoverEnd]) + + return React.useCallback((newNode: HTMLElement | null) => { + setNode(newNode) + }, []) +}