Skip to content

Commit

Permalink
Merge pull request #296 from contentstack/VC-115/live-editor-support
Browse files Browse the repository at this point in the history
feat: v3.0.1
  • Loading branch information
srinad007 authored Nov 15, 2024
2 parents 57d4c43 + 372b865 commit a4bb83e
Show file tree
Hide file tree
Showing 14 changed files with 244 additions and 113 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Alternatively, if you want to include the package directly in your website HTML

```html
<script type='module' integrity='sha384-9M4o9H23Ax5ZTzsMRLgdlFBYk2hy+ub6XDiZhHWJjfebQ+MZ9iZw+GNep9ac0uFV' crossorigin="anonymous">
import ContentstackLivePreview from 'https://esm.sh/@contentstack/[email protected].0';
import ContentstackLivePreview from 'https://esm.sh/@contentstack/[email protected].1';
ContentstackLivePreview.init({
stackDetails: {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentstack/live-preview-utils",
"version": "3.0.0",
"version": "3.0.1",
"description": "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.",
"type": "module",
"types": "dist/legacy/index.d.ts",
Expand Down
1 change: 0 additions & 1 deletion src/livePreview/editButton/editButton.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export function cslpTagStyles() {
return {
"cslp-edit-mode": css`
outline: 1px dashed #6c5ce7 !important;
position: relative !important;
`,
"cslp-tooltip": css`
padding: 0;
Expand Down
9 changes: 9 additions & 0 deletions src/visualBuilder/components/FieldToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const TOOLTIP_TOP_EDGE_BUFFER = 96;

interface MultipleFieldToolbarProps {
eventDetails: VisualBuilderCslpEventDetails;
hideOverlay: () => void;
};

function handleReplaceAsset(fieldMetadata: CslpData) {
Expand Down Expand Up @@ -309,6 +310,14 @@ function FieldToolbarComponent(
fetchFieldSchema();
}, [fieldMetadata]);

useEffect(() => {
visualBuilderPostMessage?.on(VisualBuilderPostMessageEvents.DELETE_INSTANCE, (args: { data: { path: string } }) => {
if(args.data?.path === fieldMetadata.instance.fieldPathWithIndex){
props.hideOverlay()
}
})
}, [])

const multipleFieldToolbarButtonClasses = classNames(
"visual-builder__button visual-builder__button--secondary",
visualBuilderStyles()["visual-builder__button"],
Expand Down
26 changes: 6 additions & 20 deletions src/visualBuilder/components/pseudoEditableField.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import classNames from "classnames";
import getCamelCaseStyles from "../utils/getCamelCaseStyles";
import getStyleOfAnElement from "../utils/getStyleOfAnElement";
import React from "preact/compat";
import { visualBuilderStyles } from "../visualBuilder.style";
import { getPsuedoEditableElementStyles } from "../utils/getPsuedoEditableStylesElement";

interface PseudoEditableFieldProps {
editableElement: HTMLElement;
Expand All @@ -12,27 +11,14 @@ interface PseudoEditableFieldProps {
function PseudoEditableFieldComponent(
props: PseudoEditableFieldProps
): JSX.Element {
const styles = getCamelCaseStyles(
getStyleOfAnElement(props.editableElement)
);
// Get the offsetTop and offsetLeft of the editable element and set the position of the pseudo editable element
// The pseudo editable element is positioned absolutely at the same location as the editable element
const rect = props.editableElement.getBoundingClientRect();

styles.position = "absolute";
styles.top = `${rect.top + window.scrollY}px`;
styles.left = `${rect.left + window.scrollX}px`;
// setting height to auto so that the element can grow based on the content
// and the resize observer can detect the change in height
styles.height = "auto";
styles.whiteSpace = "pre-line"
styles.textTransform = "none"
const styles = getPsuedoEditableElementStyles(props.editableElement, true);

return (
<div
className={
classNames("visual-builder__pseudo-editable-element", visualBuilderStyles()["visual-builder__pseudo-editable-element"])
}
className={classNames(
"visual-builder__pseudo-editable-element",
visualBuilderStyles()["visual-builder__pseudo-editable-element"]
)}
data-testid="visual-builder__pseudo-editable-element"
style={styles}
>
Expand Down
42 changes: 29 additions & 13 deletions src/visualBuilder/eventManager/useVariantsPostMessageEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ interface VariantFieldsEvent {
};
};
}
interface RemoveVariantFieldsEvent {
data: {
onlyHighlighted?: boolean;
};
}

interface AudienceEvent {
data: {
Expand Down Expand Up @@ -51,18 +56,29 @@ function addVariantFieldClass(
});
}

function removeVariantFieldClass(): void {
const variantAndBaseFieldElements = document.querySelectorAll(
".visual-builder__disabled-variant-field, .visual-builder__variant-field, .visual-builder__base-field"
);
variantAndBaseFieldElements.forEach((element) => {
element.classList.remove(
"visual-builder__disabled-variant-field",
"visual-builder__variant-field",
visualBuilderStyles()["visual-builder__variant-field"],
"visual-builder__base-field"
function removeVariantFieldClass(onlyHighlighted: boolean = false): void {
if (onlyHighlighted) {
const variantElements = document.querySelectorAll(
`.${visualBuilderStyles()["visual-builder__variant-field"]}`
);
});
variantElements.forEach((element) => {
element.classList.remove(
visualBuilderStyles()["visual-builder__variant-field"]
);
});
} else {
const variantAndBaseFieldElements = document.querySelectorAll(
".visual-builder__disabled-variant-field, .visual-builder__variant-field, .visual-builder__base-field"
);
variantAndBaseFieldElements.forEach((element) => {
element.classList.remove(
"visual-builder__disabled-variant-field",
"visual-builder__variant-field",
visualBuilderStyles()["visual-builder__variant-field"],
"visual-builder__base-field"
);
});
}
}

function setAudienceMode(mode: boolean): void {
Expand Down Expand Up @@ -106,8 +122,8 @@ export function useVariantFieldsPostMessageEvent(): void {
);
visualBuilderPostMessage?.on(
VisualBuilderPostMessageEvents.REMOVE_VARIANT_FIELDS,
() => {
removeVariantFieldClass();
(event: RemoveVariantFieldsEvent) => {
removeVariantFieldClass(event?.data?.onlyHighlighted);
}
);
}
9 changes: 6 additions & 3 deletions src/visualBuilder/generators/generateToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@ import FieldLabelWrapperComponent from "../components/fieldLabelWrapper";

export function appendFocusedToolbar(
eventDetails: VisualBuilderCslpEventDetails,
focusedToolbarElement: HTMLDivElement
focusedToolbarElement: HTMLDivElement,
hideOverlay: () => void
): void {
appendFieldPathDropdown(eventDetails, focusedToolbarElement);
appendFieldToolbar(eventDetails, focusedToolbarElement);
appendFieldToolbar(eventDetails, focusedToolbarElement, hideOverlay);
}

export function appendFieldToolbar(
eventDetails: VisualBuilderCslpEventDetails,
focusedToolbarElement: HTMLDivElement
focusedToolbarElement: HTMLDivElement,
hideOverlay: () => void
): void {
if (
focusedToolbarElement.querySelector(
Expand All @@ -35,6 +37,7 @@ export function appendFieldToolbar(
render(
<FieldToolbarComponent
eventDetails={eventDetails}
hideOverlay={hideOverlay}
/>,
wrapper
);
Expand Down
3 changes: 2 additions & 1 deletion src/visualBuilder/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ export class VisualBuilder {
updateFocussedStateOnMutation(
this.overlayWrapper,
this.focusedToolbar,
this.visualBuilderContainer
this.visualBuilderContainer,
this.resizeObserver
);
const emptyBlockParents = Array.from(
document.querySelectorAll(
Expand Down
12 changes: 10 additions & 2 deletions src/visualBuilder/listeners/mouseClick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type AddFocusOverlayParams = Pick<
type AddFocusedToolbarParams = Pick<
EventListenerHandlerParams,
"eventDetails" | "focusedToolbar"
>;
> & { hideOverlay: () => void };

function addOverlay(params: AddFocusOverlayParams) {
if (!params.overlayWrapper || !params.editableElement) return;
Expand All @@ -53,7 +53,7 @@ export function addFocusedToolbar(params: AddFocusedToolbarParams): void {

if (!editableElement || !params.focusedToolbar) return;

appendFocusedToolbar(params.eventDetails, params.focusedToolbar);
appendFocusedToolbar(params.eventDetails, params.focusedToolbar, params.hideOverlay);
}

async function handleBuilderInteraction(
Expand Down Expand Up @@ -143,6 +143,14 @@ async function handleBuilderInteraction(
addFocusedToolbar({
eventDetails: eventDetails,
focusedToolbar: params.focusedToolbar,
hideOverlay: () => {
hideOverlay({
visualBuilderContainer: params.visualBuilderContainer,
visualBuilderOverlayWrapper: params.overlayWrapper,
focusedToolbar: params.focusedToolbar,
resizeObserver: params.resizeObserver,
});
}
});

const { content_type_uid, fieldPath, cslpValue } = fieldMetadata;
Expand Down
26 changes: 26 additions & 0 deletions src/visualBuilder/utils/getPsuedoEditableStylesElement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import getCamelCaseStyles from "./getCamelCaseStyles";
import getStyleOfAnElement from "./getStyleOfAnElement";

export function getPsuedoEditableElementStyles(
psuedoEditableElement: HTMLElement,
camelCase?: boolean
): { [key: string]: string } {
let styles = getStyleOfAnElement(psuedoEditableElement);
if (camelCase) {
styles = getCamelCaseStyles(styles);
}
// Get the offsetTop and offsetLeft of the editable element and set the position of the pseudo editable element
// The pseudo editable element is positioned absolutely at the same location as the editable element
const rect = psuedoEditableElement.getBoundingClientRect();

styles.position = "absolute";
styles.top = `${rect.top + window.scrollY}px`;
styles.left = `${rect.left + window.scrollX}px`;
// setting height to auto so that the element can grow based on the content
// and the resize observer can detect the change in height
styles.height = "auto";
styles.whiteSpace = "pre-line";
styles.textTransform = "none";

return styles;
}
2 changes: 2 additions & 0 deletions src/visualBuilder/utils/getStyleOfAnElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export default function getStyleOfAnElement(element: HTMLElement): {
"right",
"bottom",
"text-overflow",
// allows seeing the text from CMS field as-is
"text-transform",
"margin",
"margin-block-end",
"margin-block-start",
Expand Down
2 changes: 1 addition & 1 deletion src/visualBuilder/utils/handleIndividualFields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ export async function handleIndividualFields(
editableElement: actualEditableField,
visualBuilderContainer,
overlayWrapper,
resizeObserver,
focusedToolbar,
resizeObserver,
});
}, 200);
actualEditableField.addEventListener(
Expand Down
Loading

0 comments on commit a4bb83e

Please sign in to comment.