UNPKG

@contentstack/live-preview-utils

Version:

Contentstack provides the Live Preview SDK to establish a communication channel between the various Contentstack SDKs and your website, transmitting live changes to the preview pane.

1 lines 8.73 kB
{"version":3,"sources":["../../../../src/visualBuilder/generators/generateHighlightedComment.tsx"],"sourcesContent":["import { h, VNode } from \"preact\"; // Explicitly import VNode from Preact\nimport { render } from \"preact\";\nimport HighlightedCommentIcon from \"../components/HighlightedCommentIcon\";\nimport { css } from \"goober\";\nimport React from \"preact/compat\";\nimport { IHighlightCommentData } from \"../eventManager/useHighlightCommentIcon\";\n\n/**\n * Inserts highlighted comment icons based on an array of paths.\n *\n * This function locates elements in the DOM based on the `fieldMetadata.cslpValue`,\n * and appends a comment icon near each matching element.\n *\n * @param payload - Array of comment data with field metadata, schema, absolutePath and discussion ID.\n */\nconst highlighCommentOffset = 25;\n\nexport function highlightCommentIconOnCanvas(\n payload: IHighlightCommentData[]\n): void {\n const uniquePaths: { [key: string]: boolean } = {}; // Using object for uniqueness\n\n payload.forEach((data) => {\n const cslpValue = data?.fieldMetadata?.cslpValue;\n\n // Check if the cslpValue is already in the Object\n if (!cslpValue || uniquePaths[cslpValue]) {\n return; // Skip if the value is not unique\n }\n\n uniquePaths[cslpValue] = true; // Mark it as processed\n\n const element = document.querySelector(`[data-cslp=\"${cslpValue}\"]`);\n if (element && element instanceof HTMLElement) {\n const { top, left } = element.getBoundingClientRect();\n\n const iconContainer = document.createElement(\"div\");\n iconContainer.setAttribute(\"field-path\", cslpValue);\n\n iconContainer.style.position = \"fixed\";\n iconContainer.style.top = `${top - highlighCommentOffset}px`;\n iconContainer.style.left = `${left - highlighCommentOffset}px`;\n iconContainer.style.zIndex = \"900\";\n iconContainer.style.cursor = \"pointer\";\n iconContainer.className = \"highlighted-comment collab-icon\";\n\n // Render the HighlightedCommentIcon using Preact's render method\n render(\n h(HighlightedCommentIcon, { data }), // Use h directly with Preact\n iconContainer\n );\n\n const visualBuilderContainer = document.querySelector(\n \".visual-builder__container\"\n );\n if (visualBuilderContainer) {\n let highlightCommentWrapper =\n visualBuilderContainer.querySelector(\n \".visual-builder__highlighted-comment-wrapper\"\n );\n if (!highlightCommentWrapper) {\n highlightCommentWrapper = document.createElement(\"div\");\n highlightCommentWrapper.className =\n \"visual-builder__highlighted-comment-wrapper\";\n visualBuilderContainer.appendChild(highlightCommentWrapper);\n }\n highlightCommentWrapper.appendChild(iconContainer);\n }\n }\n });\n}\n\n/**\n * Update Highlighted comment position , whenever scroll or resize happen.\n */\n\nexport function updateHighlightedCommentIconPosition() {\n // Query all elements with the .highlighted-comment class\n const icons = document.querySelectorAll(\".highlighted-comment\");\n\n icons.forEach((icon) => {\n if (icon && icon instanceof HTMLElement) {\n // Get the field-path attribute from the icon container\n const path = icon.getAttribute(\"field-path\");\n if (path) {\n // Query the target element using the path\n const targetElement = document.querySelector(\n `[data-cslp=\"${path}\"]`\n );\n if (targetElement && targetElement instanceof HTMLElement) {\n // Get the target element's position relative to the viewport\n const { top, left } = targetElement.getBoundingClientRect();\n\n // Update the position of the icon container\n icon.style.top = `${top - highlighCommentOffset}px`; // Adjust based on the target element's top\n icon.style.left = `${left - highlighCommentOffset}px`; // Adjust based on the target element's left\n }\n }\n }\n });\n}\n\n/**\n * Removes the first highlighted comment icon based on an array of paths.\n *\n * @param pathsToRemove - Array of field-paths to remove.\n */\nexport function removeHighlightedCommentIcon(pathToRemove: string): void {\n // Loop through each path in the array\n const iconToRemove = document.querySelectorAll(\n `.highlighted-comment[field-path=\"${pathToRemove}\"]`\n );\n iconToRemove?.forEach((icon) => icon?.remove());\n}\n\nexport function removeAllHighlightedCommentIcons(): void {\n const icons = document.querySelectorAll(\".highlighted-comment\");\n icons?.forEach((icon) => icon?.remove());\n}\n\n// Define a hidden class in goober\nconst hiddenClass = css`\n display: none;\n`;\n\n/**\n * Toggle display style of a specific highlighted comment icon.\n *\n * @param path - The data-cslp attribute of the element whose corresponding highlighted comment icon should be toggled.\n * @param shouldShow - Boolean value to determine whether to show or hide the icon.\n * If true, the icon will be displayed. If false, the icon will be hidden.\n */\nexport function toggleHighlightedCommentIconDisplay(\n path: string,\n shouldShow: boolean\n): void {\n const icons = document.querySelectorAll<HTMLElement>(\n `.highlighted-comment[field-path=\"${path}\"]`\n );\n\n icons.forEach((icon) => {\n if (shouldShow) {\n icon.classList.remove(hiddenClass); // Show the element\n } else {\n icon.classList.add(hiddenClass); // Hide the element using goober's hidden class\n }\n });\n}\n\n/**\n * Show all .highlighted-comment icons that have the hiddenClass applied.\n */\nexport function showAllHiddenHighlightedCommentIcons(): void {\n // Query all elements that have both .highlighted-comment and hiddenClass\n const hiddenIcons = document.querySelectorAll<HTMLElement>(\n `.highlighted-comment.${hiddenClass}`\n );\n\n // Loop through each hidden icon and remove the hiddenClass\n hiddenIcons.forEach((icon) => {\n icon.classList.remove(hiddenClass); // Remove the hiddenClass to show the icon\n });\n}\n"],"mappings":"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","names":["import_preact","HighlightedCommentIcon"]}