diff --git a/.changeset/chilled-sheep-promise.md b/.changeset/chilled-sheep-promise.md new file mode 100644 index 0000000000..305315c266 --- /dev/null +++ b/.changeset/chilled-sheep-promise.md @@ -0,0 +1,7 @@ +--- +"tinacms": patch +"@tinacms/app": patch +"@tinacms/cli": patch +--- + +Revert "✨ Visual element highlighting between iframe and form (#6211)" diff --git a/.changeset/witty-rings-wink.md b/.changeset/witty-rings-wink.md new file mode 100644 index 0000000000..e3cf7e547e --- /dev/null +++ b/.changeset/witty-rings-wink.md @@ -0,0 +1,5 @@ +--- +"tinacms": patch +--- + +Branch selector - added ability to filter based off PR number diff --git a/packages/@tinacms/app/src/lib/graphql-reducer.ts b/packages/@tinacms/app/src/lib/graphql-reducer.ts index 034f9dc623..c3cef43834 100644 --- a/packages/@tinacms/app/src/lib/graphql-reducer.ts +++ b/packages/@tinacms/app/src/lib/graphql-reducer.ts @@ -526,17 +526,9 @@ export const useGraphQLReducer = ( const [queryId, eventFieldName] = event.data.fieldName.split('---'); const result = results.find((res) => res.id === queryId); if (result?.data) { - const { formId, fieldName } = getFormAndFieldNameFromMetadata( - result.data, - eventFieldName - ); cms.dispatch({ type: 'forms:set-active-field-name', - value: { formId: formId, fieldName: fieldName }, - }); - cms.events.dispatch({ - ...event.data, - type: 'field:focus', + value: getFormAndFieldNameFromMetadata(result.data, eventFieldName), }); } cms.dispatch({ @@ -544,30 +536,6 @@ export const useGraphQLReducer = ( value: 'openOrFull', }); } - if (event.data.type === 'field:hovered') { - if (event.data.fieldName) { - const [queryId, eventFieldName] = event.data.fieldName.split('---'); - const result = results.find((res) => res.id === queryId); - if (result?.data) { - const fieldData = getFormAndFieldNameFromMetadata( - result.data, - eventFieldName - ); - cms.dispatch({ - type: 'forms:set-hovered-field-name', - value: fieldData, - }); - } - } else { - // Clear hover state when fieldName is null - cms.forms.all().forEach((form) => { - cms.dispatch({ - type: 'forms:set-hovered-field-name', - value: { formId: form.id, fieldName: null }, - }); - }); - } - } if (event.data.type === 'close') { const payloadSchema = z.object({ id: z.string() }); const { id } = payloadSchema.parse(event.data); @@ -630,33 +598,6 @@ export const useGraphQLReducer = ( }); }, [cms.state.sidebarDisplayState]); - // Compute the active field name to send to iframe - const activeFieldName = React.useMemo(() => { - const activeForm = cms.state.forms.find( - (form: any) => form.tinaForm.id === cms.state.activeFormId - ); - if (!activeForm) { - return null; - } - const fieldName = activeForm.activeFieldName; - if (fieldName === null) { - return null; - } - const queries = activeForm.tinaForm.queries; - if (queries && queries.length > 0) { - const queryId = queries[queries.length - 1]; - return `${queryId}---${fieldName}`; - } - return null; - }, [cms.state.forms, cms.state.activeFormId]); - - React.useEffect(() => { - iframe.current?.contentWindow?.postMessage({ - type: 'field:set-focused', - fieldName: activeFieldName, - }); - }, [activeFieldName, iframe]); - React.useEffect(() => { cms.dispatch({ type: 'set-edit-mode', value: 'visual' }); if (iframe) { diff --git a/packages/@tinacms/app/src/lib/types.ts b/packages/@tinacms/app/src/lib/types.ts index e7d09a8893..be4a844928 100644 --- a/packages/@tinacms/app/src/lib/types.ts +++ b/packages/@tinacms/app/src/lib/types.ts @@ -5,7 +5,6 @@ export type PostMessage = data: object; } | { type: 'field:selected'; fieldName: string } - | { type: 'field:hovered'; fieldName: string | null } | { type: 'quick-edit'; value: boolean } | { type: 'user-select-form'; formId: string } | { type: 'url-changed' }; diff --git a/packages/@tinacms/cli/src/next/vite/tailwind.ts b/packages/@tinacms/cli/src/next/vite/tailwind.ts index cf312ded79..25f596cedb 100644 --- a/packages/@tinacms/cli/src/next/vite/tailwind.ts +++ b/packages/@tinacms/cli/src/next/vite/tailwind.ts @@ -175,7 +175,7 @@ export const tinaTailwind = ( }, boxShadow: { xs: '0 0 0 1px rgba(0, 0, 0, 0.05)', - outline: '0 0 0 3px rgba(194, 65, 12, 0.2)', + outline: '0 0 0 3px rgba(66, 153, 225, 0.5)', }, colors: { blue: { @@ -232,7 +232,7 @@ export const tinaTailwind = ( 'accent-foreground': '#171717', destructive: '#FF3B3B', 'destructive-foreground': '#FAFAFA', - ring: '#C2410C', + ring: '#0A0A0A', }, fontFamily: { sans: ['Inter', ...defaultTheme.fontFamily.sans], diff --git a/packages/tinacms/src/react.tsx b/packages/tinacms/src/react.tsx index 04125db959..af65ea0af8 100644 --- a/packages/tinacms/src/react.tsx +++ b/packages/tinacms/src/react.tsx @@ -50,15 +50,6 @@ export function useTina(props: { outline: 2px solid rgba(34,150,254,1); cursor: pointer; } - [data-tina-field-focused] { - outline: 2px dashed #C2410C !important; - box-shadow: none !important; - } - [data-tina-field-focused]:hover { - box-shadow: inset 100vi 100vh rgba(194, 65, 12, 0.3) !important; - outline: 2px solid #C2410C !important; - cursor: pointer; - } [data-tina-field-overlay] { outline: 2px dashed rgba(34,150,254,0.5); position: relative; @@ -79,16 +70,10 @@ export function useTina(props: { [data-tina-field-overlay]:hover::after { opacity: 1; } - [data-tina-field-overlay][data-tina-field-focused]::after { - background-color: rgba(194, 65, 12, 0.3); - opacity: 1; - } `; document.head.appendChild(style); document.body.classList.add('__tina-quick-editing-enabled'); - let lastHoveredField: string | null = null; - function mouseDownHandler(e) { const attributeNames = e.target.getAttributeNames(); // If multiple attributes start with data-tina-field, only the first is used @@ -118,16 +103,6 @@ export function useTina(props: { } } if (fieldName) { - // Clear hover state on click - if (lastHoveredField !== null) { - lastHoveredField = null; - if (isInTinaIframe) { - parent.postMessage( - { type: 'field:hovered', fieldName: null }, - window.location.origin - ); - } - } if (isInTinaIframe) { parent.postMessage( { type: 'field:selected', fieldName: fieldName }, @@ -144,51 +119,10 @@ export function useTina(props: { } } } - - function mouseEnterHandler(e) { - if (!(e.target instanceof Element)) { - return; - } - const attributeNames = e.target.getAttributeNames(); - const tinaAttribute = attributeNames.find((name) => - name.startsWith('data-tina-field') - ); - - let fieldName; - if (tinaAttribute) { - fieldName = e.target.getAttribute(tinaAttribute); - } else { - const ancestor = e.target.closest( - '[data-tina-field], [data-tina-field-overlay]' - ); - if (ancestor) { - const attributeNames = ancestor.getAttributeNames(); - const tinaAttribute = attributeNames.find((name) => - name.startsWith('data-tina-field') - ); - if (tinaAttribute) { - fieldName = ancestor.getAttribute(tinaAttribute); - } - } - } - - if (fieldName && fieldName !== lastHoveredField) { - lastHoveredField = fieldName; - if (isInTinaIframe) { - parent.postMessage( - { type: 'field:hovered', fieldName: fieldName }, - window.location.origin - ); - } - } - } - document.addEventListener('click', mouseDownHandler, true); - document.addEventListener('mouseenter', mouseEnterHandler, true); return () => { document.removeEventListener('click', mouseDownHandler, true); - document.removeEventListener('mouseenter', mouseEnterHandler, true); document.body.classList.remove('__tina-quick-editing-enabled'); style.remove(); }; @@ -204,8 +138,6 @@ export function useTina(props: { } }, [id]); - const lastFocusedFieldRef = React.useRef(null); - React.useEffect(() => { const { experimental___selectFormByFormId, ...rest } = props; parent.postMessage({ type: 'open', ...rest, id }, window.location.origin); @@ -235,63 +167,6 @@ export function useTina(props: { ); } } - - // Handle field focus to add data attribute for orange styling - if (event.data.type === 'field:set-focused') { - const newFieldName = event.data.fieldName; - - // Only process if the focused field has actually changed - if (newFieldName === lastFocusedFieldRef.current) { - return; - } - - lastFocusedFieldRef.current = newFieldName; - - // Remove focused attribute from all elements - const allTinaFields = document.querySelectorAll('[data-tina-field]'); - allTinaFields.forEach((el) => { - el.removeAttribute('data-tina-field-focused'); - }); - - // Add focused attribute to the clicked field - if (newFieldName) { - // Try exact match first - let targetElement = document.querySelector( - `[data-tina-field="${newFieldName}"]` - ); - - // If not found, try to find by searching for elements whose data-tina-field ends with this value - if (!targetElement) { - const allFields = Array.from(allTinaFields); - targetElement = allFields.find((el) => { - const fieldValue = el.getAttribute('data-tina-field'); - // Match if the field value ends with the fieldName we're looking for - return ( - fieldValue && fieldValue.endsWith(newFieldName.split('---')[1]) - ); - }) as Element | undefined; - } - - if (targetElement) { - targetElement.setAttribute('data-tina-field-focused', 'true'); - - // Scroll the element into view if it's not visible - const rect = targetElement.getBoundingClientRect(); - const isInViewport = - rect.top >= 0 && - rect.left >= 0 && - rect.bottom <= window.innerHeight && - rect.right <= window.innerWidth; - - if (!isInViewport) { - targetElement.scrollIntoView({ - behavior: 'smooth', - block: 'center', - }); - } - } - } - } }; window.addEventListener('message', handleMessage); diff --git a/packages/tinacms/src/toolkit/components/active-field-indicator.tsx b/packages/tinacms/src/toolkit/components/active-field-indicator.tsx index 2c473e799c..0391073c70 100644 --- a/packages/tinacms/src/toolkit/components/active-field-indicator.tsx +++ b/packages/tinacms/src/toolkit/components/active-field-indicator.tsx @@ -46,12 +46,10 @@ const BelowViewportIndicator = () => { ); }; -const useScrollToFocusedField = (enabled: boolean) => { +const useScrollToFocusedField = () => { const { subscribe } = useEvent('field:focus'); - React.useEffect(() => { - if (!enabled) return; - - return subscribe(({ fieldName }) => { + React.useEffect(() => + subscribe(({ fieldName }) => { const ele = document.querySelector( `[data-tinafield="${fieldName}"]` ); @@ -99,55 +97,18 @@ const useScrollToFocusedField = (enabled: boolean) => { }); } } - }); - }, [enabled, subscribe]); -}; - -type FieldIndicatorProps = { - eventType: 'field:focus' | 'field:hover'; - checkFocusedAttribute?: boolean; - scrollToField?: boolean; + }) + ); }; -const FieldIndicator = ({ - eventType, - checkFocusedAttribute = false, - scrollToField = false, -}: FieldIndicatorProps) => { - const [fieldName, setFieldName] = React.useState(null); +export const ActiveFieldIndicator = () => { + const [activeFieldName, setActiveFieldName] = React.useState( + null + ); const [display, setDisplay] = React.useState(false); const [position, setPosition] = React.useState(false); const [iframePosition, setIframePosition] = React.useState({ left: 0 }); - const [isFocused, setIsFocused] = React.useState(false); - const activeEle = useFieldReference(fieldName); - - const { subscribe: subscribeFocus } = - useEvent('field:focus'); - const { subscribe: subscribeHover } = - useEvent('field:hover'); - - React.useEffect(() => { - const subscribe = - eventType === 'field:focus' ? subscribeFocus : subscribeHover; - return subscribe(({ fieldName: eventFieldName, id }) => { - setFieldName(`${id}#${eventFieldName}`); - if (eventType === 'field:focus' && checkFocusedAttribute) { - setIsFocused(true); - } - }); - }, [eventType, subscribeFocus, subscribeHover, checkFocusedAttribute]); - - // Check if the active element has the focused attribute and update state - React.useEffect(() => { - if (!checkFocusedAttribute) return; - - if (activeEle) { - const hasFocusedAttr = activeEle.hasAttribute('data-tina-field-focused'); - setIsFocused(hasFocusedAttr); - } else { - setIsFocused(false); - } - }, [activeEle, fieldName, checkFocusedAttribute]); + const activeEle = useFieldReference(activeFieldName); React.useEffect(() => { let displayTimeout; @@ -181,7 +142,15 @@ const FieldIndicator = ({ }; }, []); - useScrollToFocusedField(scrollToField); + const { subscribe } = useEvent('field:hover'); + + React.useEffect(() => + subscribe(({ fieldName, id }) => { + setActiveFieldName(`${id}#${fieldName}`); + }) + ); + + useScrollToFocusedField(); if (!display) return null; @@ -191,18 +160,15 @@ const FieldIndicator = ({ const viewportBottomY = window.innerHeight + window.scrollY; if (eleTopY > viewportBottomY) { + // element is below the viewport return ; } if (eleBottomY < viewportTopY) { + // element is above the viewport return ; } - const outlineColor = - checkFocusedAttribute && isFocused - ? '2px dashed #C2410C' - : '2px dashed var(--tina-color-indicator)'; - return (
); }; - -export const ActiveFieldIndicator = () => ( - -); - -export const HoveredFieldIndicator = () => ( - -); diff --git a/packages/tinacms/src/toolkit/components/tina-ui.tsx b/packages/tinacms/src/toolkit/components/tina-ui.tsx index 1c5fafd6a0..e09aa4bad7 100644 --- a/packages/tinacms/src/toolkit/components/tina-ui.tsx +++ b/packages/tinacms/src/toolkit/components/tina-ui.tsx @@ -10,10 +10,7 @@ import { SidebarProvider, SidebarPosition } from '@toolkit/react-sidebar'; import { useCMS } from '../react-tinacms/use-cms'; import { Alerts } from '@toolkit/react-alerts'; import { MediaManager } from './media'; -import { - ActiveFieldIndicator, - HoveredFieldIndicator, -} from './active-field-indicator'; +import { ActiveFieldIndicator } from './active-field-indicator'; import { MutationSignalProvider } from './mutation-signal'; export interface TinaUIProps { @@ -40,7 +37,6 @@ export const TinaUI: React.FC = ({ children, position }) => { /> )} - {/* Dragging across the iframe causes mouse events to stop propagating so there's a laggy feeling without this */}
{children} diff --git a/packages/tinacms/src/toolkit/fields/components/checkbox-group.tsx b/packages/tinacms/src/toolkit/fields/components/checkbox-group.tsx index 46a71ab591..ab55a1840d 100644 --- a/packages/tinacms/src/toolkit/fields/components/checkbox-group.tsx +++ b/packages/tinacms/src/toolkit/fields/components/checkbox-group.tsx @@ -83,7 +83,7 @@ export const CheckboxGroup: React.FC = ({ diff --git a/packages/tinacms/src/toolkit/fields/components/image-upload/image-upload.tsx b/packages/tinacms/src/toolkit/fields/components/image-upload/image-upload.tsx index d75fd46bb0..ab5497abef 100644 --- a/packages/tinacms/src/toolkit/fields/components/image-upload/image-upload.tsx +++ b/packages/tinacms/src/toolkit/fields/components/image-upload/image-upload.tsx @@ -77,7 +77,7 @@ export const ImageUpload = React.forwardRef< }`} >