Astro+Directus(Visual-Editing)+Snipcart Test-Stack

This commit is contained in:
till committed 2026-06-21 06:27:52 +00:00
commit 1459e99cb0
10119 files changed
+1499318

No files matched your search

+89
View File
@@ -0,0 +1,89 @@
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`@reach/observe-rect`);c=s(c);var l=class e{static CSS_VAR_Z_INDEX=`--directus-visual-editing--overlay--z-index`;static CSS_VAR_BORDER_SPACING=`--directus-visual-editing--rect--border-spacing`;static CSS_VAR_BORDER_WIDTH=`--directus-visual-editing--rect--border-width`;static CSS_VAR_BORDER_COLOR=`--directus-visual-editing--rect--border-color`;static CSS_VAR_BORDER_RADIUS=`--directus-visual-editing--rect--border-radius`;static CSS_VAR_HOVER_OPACITY=`--directus-visual-editing--rect-hover--opacity`;static CSS_VAR_HIGHLIGHT_OPACITY=`--directus-visual-editing--rect-highlight--opacity`;static CSS_VAR_ACTIONS_GAP=`--directus-visual-editing--actions--gap`;static CSS_VAR_BUTTON_WIDTH=`--directus-visual-editing--edit-btn--width`;static CSS_VAR_BUTTON_HEIGHT=`--directus-visual-editing--edit-btn--height`;static CSS_VAR_BUTTON_RADIUS=`--directus-visual-editing--edit-btn--radius`;static CSS_VAR_EDIT_BUTTON_BG_COLOR=`--directus-visual-editing--edit-btn--bg-color`;static CSS_VAR_EDIT_BUTTON_ICON_BG_IMAGE=`--directus-visual-editing--edit-btn--icon-bg-image`;static CSS_VAR_EDIT_BUTTON_ICON_BG_SIZE=`--directus-visual-editing--edit-btn--icon-bg-size`;static CSS_VAR_AI_BUTTON_BG_COLOR=`--directus-visual-editing--ai-btn--bg-color`;static CSS_VAR_AI_BUTTON_ICON_BG_IMAGE=`--directus-visual-editing--ai-btn--icon-bg-image`;static CSS_VAR_AI_BUTTON_ICON_BG_SIZE=`--directus-visual-editing--ai-btn--icon-bg-size`;static ICON_EDIT=`url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="%23ffffff"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M14.06 9.02l.92.92L5.92 19H5v-.92l9.06-9.06M17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29zm-3.6 3.19L3 17.25V21h3.75L17.81 9.94l-3.75-3.75z"/></svg>')`;static ICON_AI=`url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"><path fill="%23ffffff" d="M10 14.175L11 12l2.175-1L11 10l-1-2.175L9 10l-2.175 1L9 12l1 2.175ZM10 19l-2.5-5.5L2 11l5.5-2.5L10 3l2.5 5.5L18 11l-5.5 2.5L10 19Zm8 2l-1.25-2.75L14 17l2.75-1.25L18 13l1.25 2.75L22 17l-2.75 1.25L18 21Zm-8-10Z"/></svg>')`;static OVERLAY_ID=`directus-visual-editing`;static STYLE_ID=`directus-visual-editing-style`;static CONTAINER_RECT_CLASS_NAME=`directus-visual-editing-overlay`;static RECT_CLASS_NAME=`directus-visual-editing-rect`;static RECT_HIGHLIGHT_CLASS_NAME=`directus-visual-editing-rect-highlight`;static RECT_HIGHLIGHT_ACTIVE_CLASS_NAME=`directus-visual-editing-rect-highlight-active`;static RECT_PARENT_HOVER_CLASS_NAME=`directus-visual-editing-rect-parent-hover`;static RECT_HOVER_CLASS_NAME=`directus-visual-editing-rect-hover`;static RECT_INNER_CLASS_NAME=`directus-visual-editing-rect-inner`;static RECT_BUTTON_CLASS_NAME=`directus-visual-editing-button`;static RECT_EDIT_BUTTON_CLASS_NAME=`directus-visual-editing-edit-button`;static RECT_AI_BUTTON_CLASS_NAME=`directus-visual-editing-ai-button`;static getGlobalOverlay(){let t=document.getElementById(e.OVERLAY_ID);if(t)return t;let n=document.createElement(`div`);return n.id=e.OVERLAY_ID,document.body.insertAdjacentElement(`afterend`,n),n}static addStyles(){if(document.getElementById(e.STYLE_ID))return;let t=document.createElement(`style`);t.id=e.STYLE_ID;let n=`var(${e.CSS_VAR_BUTTON_WIDTH}, 28px)`,r=`var(${e.CSS_VAR_EDIT_BUTTON_BG_COLOR}, #6644ff)`,i=`var(${e.CSS_VAR_AI_BUTTON_BG_COLOR}, ${r})`,a=`#2e3C43 25%`,o=`var(${e.CSS_VAR_BORDER_SPACING}, 9px)`,s=`var(${e.CSS_VAR_BORDER_WIDTH}, 2px)`;t.appendChild(document.createTextNode(`
#${e.OVERLAY_ID} {
display: contents;
}
.${e.CONTAINER_RECT_CLASS_NAME} {
pointer-events: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: var(${e.CSS_VAR_Z_INDEX}, 999999999);
}
.${e.RECT_CLASS_NAME} {
position: absolute;
}
.${e.RECT_INNER_CLASS_NAME} {
position: absolute;
box-sizing: border-box;
top: calc(-1 * ${o});
left: calc(-1 * ${o});
right: calc(-1 * ${o});
bottom: calc(-1 * ${o});
border: ${s} solid var(${e.CSS_VAR_BORDER_COLOR}, #6644ff);
border-radius: var(${e.CSS_VAR_BORDER_RADIUS}, 6px);
opacity: 0;
}
.${e.RECT_CLASS_NAME}.${e.RECT_HOVER_CLASS_NAME} .${e.RECT_INNER_CLASS_NAME} {
--hover-opacity: var(${e.CSS_VAR_HOVER_OPACITY}, 0.333);
opacity: var(--hover-opacity);
}
.${e.RECT_CLASS_NAME}.${e.RECT_PARENT_HOVER_CLASS_NAME} .${e.RECT_INNER_CLASS_NAME} {
opacity: calc(var(--hover-opacity) / 3);
}
.${e.RECT_HIGHLIGHT_CLASS_NAME} {
pointer-events: all;
cursor: pointer;
}
.${e.RECT_HIGHLIGHT_CLASS_NAME} .${e.RECT_INNER_CLASS_NAME} {
opacity: var(${e.CSS_VAR_HIGHLIGHT_OPACITY}, 0.333);
}
.${e.RECT_BUTTON_CLASS_NAME}:visited,
.${e.RECT_BUTTON_CLASS_NAME}:active,
.${e.RECT_BUTTON_CLASS_NAME}:hover,
.${e.RECT_BUTTON_CLASS_NAME}:focus,
.${e.RECT_BUTTON_CLASS_NAME} {
all: initial;
pointer-events: all;
cursor: pointer;
position: absolute;
z-index: 1;
top: calc(-1 * ${o} + ${s} / 2);
transform: translate(-50%, -50%);
width: ${n};
height: var(${e.CSS_VAR_BUTTON_HEIGHT}, 28px);
border-radius: var(${e.CSS_VAR_BUTTON_RADIUS}, 50%);
background-position: center;
background-repeat: no-repeat;
opacity: 0;
}
.${e.RECT_BUTTON_CLASS_NAME}.${e.RECT_EDIT_BUTTON_CLASS_NAME} {
left: calc(-1 * ${o} + ${s} / 2);
background-color: ${r};
background-image: var(${e.CSS_VAR_EDIT_BUTTON_ICON_BG_IMAGE}, ${e.ICON_EDIT});
background-size: var(${e.CSS_VAR_EDIT_BUTTON_ICON_BG_SIZE}, 66.6%);
}
.${e.RECT_BUTTON_CLASS_NAME}.${e.RECT_AI_BUTTON_CLASS_NAME} {
left: calc(-1 * ${o} + ${s} / 2 + ${n} + var(${e.CSS_VAR_ACTIONS_GAP}, 4px));
background-color: ${i};
background-image: var(${e.CSS_VAR_AI_BUTTON_ICON_BG_IMAGE}, ${e.ICON_AI});
background-size: var(${e.CSS_VAR_AI_BUTTON_ICON_BG_SIZE}, 66.6%);
}
.${e.RECT_CLASS_NAME}.${e.RECT_HOVER_CLASS_NAME}:not(.${e.RECT_PARENT_HOVER_CLASS_NAME}) .${e.RECT_BUTTON_CLASS_NAME},
.${e.RECT_HIGHLIGHT_ACTIVE_CLASS_NAME} .${e.RECT_INNER_CLASS_NAME},
.${e.RECT_HIGHLIGHT_CLASS_NAME}:hover .${e.RECT_BUTTON_CLASS_NAME},
.${e.RECT_BUTTON_CLASS_NAME}:hover,
.${e.RECT_BUTTON_CLASS_NAME}:hover ~ .${e.RECT_INNER_CLASS_NAME},
.${e.RECT_HIGHLIGHT_CLASS_NAME}:hover .${e.RECT_INNER_CLASS_NAME},
.${e.RECT_CLASS_NAME}:has(.${e.RECT_BUTTON_CLASS_NAME}:hover) .${e.RECT_BUTTON_CLASS_NAME} {
opacity: 1;
}
.${e.RECT_BUTTON_CLASS_NAME}.${e.RECT_EDIT_BUTTON_CLASS_NAME}:hover {
background-color: color-mix(in srgb, ${r}, ${a});
}
.${e.RECT_BUTTON_CLASS_NAME}.${e.RECT_AI_BUTTON_CLASS_NAME}:hover {
background-color: color-mix(in srgb, ${i}, ${a});
}
`)),document.head.appendChild(t)}},u=class{hasNoDimensions=!1;element;container;editButton;aiButton;constructor(){this.container=this.createContainer(),this.element=this.createElement(),this.editButton=this.createEditButton(),this.aiButton=new p().isAiEnabled()?this.createAiButton():null,this.createRectElement(),l.getGlobalOverlay().appendChild(this.container),f.highlightOverlayElements&&this.toggleHighlight(!0),this.element.addEventListener(`click`,()=>this.editButton.click())}createContainer(){let e=document.createElement(`div`);return e.classList.add(l.CONTAINER_RECT_CLASS_NAME),e}createElement(){let e=document.createElement(`div`);return e.classList.add(l.RECT_CLASS_NAME),this.container.appendChild(e),e}createRectElement(){let e=document.createElement(`div`);e.classList.add(l.RECT_INNER_CLASS_NAME),this.element.appendChild(e)}createEditButton(){let e=document.createElement(`button`);return e.type=`button`,e.classList.add(l.RECT_BUTTON_CLASS_NAME),e.classList.add(l.RECT_EDIT_BUTTON_CLASS_NAME),this.element.appendChild(e),e}createAiButton(){let e=document.createElement(`button`);return e.type=`button`,e.classList.add(l.RECT_BUTTON_CLASS_NAME),e.classList.add(l.RECT_AI_BUTTON_CLASS_NAME),this.element.appendChild(e),e}updateRect(e){let t=e.width!==0&&e.height!==0;if(!this.hasNoDimensions&&!t){this.hasNoDimensions=!0,this.disable();return}this.hasNoDimensions&&t&&(this.hasNoDimensions=!1,this.enable()),this.element.style.width=`${e.width}px`,this.element.style.height=`${e.height}px`,this.element.style.transform=`translate(${e.left}px,${e.top}px)`}setCustomClass(e){e!==void 0&&/^[a-zA-Z_][\w-]*$/.test(e)&&this.container.classList.add(e)}toggleHover(e){this.element.classList.toggle(l.RECT_HOVER_CLASS_NAME,e)}toggleParentHover(e){this.element.classList.toggle(l.RECT_PARENT_HOVER_CLASS_NAME,e)}toggleHighlight(e){this.element.classList.toggle(l.RECT_HIGHLIGHT_CLASS_NAME,e)}toggleHighlightActive(e){this.element.classList.toggle(l.RECT_HIGHLIGHT_ACTIVE_CLASS_NAME,e)}disable(){this.element.style.display=`none`}enable(){this.element.style.removeProperty(`display`)}remove(){this.container.remove()}},d=class e{static DATASET=`directus`;static DATA_ATTRIBUTE_VALID_KEYS=[`collection`,`item`,`fields`,`mode`];optionsWritable=!0;element;key;editConfig;rectObserver;overlayElement;rect;hover=!1;disabled=!1;onSaved=void 0;boundMouseenter;boundMouseleave;constructor(t){this.element=t,this.boundMouseenter=this.onMouseenter.bind(this),this.boundMouseleave=this.onMouseleave.bind(this),this.element.addEventListener(`mouseenter`,this.boundMouseenter),this.element.addEventListener(`mouseleave`,this.boundMouseleave),this.key=crypto.randomUUID(),this.editConfig=e.editAttrToObject(this.element.dataset[e.DATASET]),this.rect=this.element.getBoundingClientRect(),this.overlayElement=new u,this.overlayElement.updateRect(this.rect),this.overlayElement.editButton.addEventListener(`click`,this.onClickEdit.bind(this)),this.overlayElement.aiButton?.addEventListener(`click`,this.onClickAddToContext.bind(this)),this.rectObserver=(0,c.default)(this.element,this.onObserveRect.bind(this)),this.rectObserver.observe()}static query(t){return t?(Array.isArray(t)?t:[t]).filter(e=>e instanceof HTMLElement).flatMap(t=>t.dataset[e.DATASET]===void 0?Array.from(t.querySelectorAll(`[data-${e.DATASET}]`)):t).filter(e=>e!==null):Array.from(document.querySelectorAll(`[data-${e.DATASET}]`))}static objectToEditAttr(t){let n=[];for(let[r,i]of Object.entries(t))e.validEditConfigKey(r)&&(r===`fields`&&Array.isArray(i)?n.push(`${r}:${i.join(`,`)}`):n.push(`${r}:${i}`));return n.join(`;`)}static editAttrToObject(t){let n=t.split(`;`),r={};return n.forEach(t=>{let n=t.split(`:`);if(n[0]===void 0||n?.[1]===void 0)return;let i=n[0].trim();if(!e.validEditConfigKey(i))return;let a=n[1];if(i===`fields`){r.fields=a.split(`,`).map(e=>e.trim());return}r[i]=a.trim()}),r}static validEditConfigKey(t){return e.DATA_ATTRIBUTE_VALID_KEYS.includes(t)}applyOptions({customClass:e,onSaved:t},n=!1){this.optionsWritable&&(n&&(this.optionsWritable=!1),this.overlayElement.setCustomClass(e),t!==void 0&&(this.onSaved=t))}removeHoverListener(){this.element.removeEventListener(`mouseenter`,this.boundMouseenter),this.element.removeEventListener(`mouseleave`,this.boundMouseleave)}onClickEdit(){new p().send(`edit`,{key:this.key,editConfig:this.editConfig,rect:this.rect})}onClickAddToContext(e){e.stopPropagation(),new p().send(`addToContext`,{key:this.key,editConfig:this.editConfig,rect:this.rect})}onMouseenter(e){this.toggleItemHover(!0,e)}onMouseleave(e){this.toggleItemHover(!1,e)}toggleItemHover(e,t){this.element!==t.currentTarget||this.hover===e||(this.hover=e,this.setParentsHover(),this.overlayElement.toggleHover(e))}setParentsHover(){let e=f.getHoveredItems();e.forEach(t=>{let n=e.filter(e=>e.element!==t.element).some(e=>t.element.contains(e.element));t.overlayElement.toggleParentHover(n)})}onObserveRect(e){this.disabled||(this.rect=e,this.overlayElement.updateRect(e))}},f=class e{static item Line truncated
//# sourceMappingURL=index.cjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.cjs","names":[],"sources":["../src/lib/overlay-manager.ts","../src/lib/overlay-element.ts","../src/lib/editable-element.ts","../src/lib/editable-store.ts","../src/lib/directus-frame.ts","../src/lib/page-manager.ts","../src/index.ts"],"sourcesContent":["export class OverlayManager {\n\tprivate static readonly CSS_VAR_Z_INDEX = '--directus-visual-editing--overlay--z-index';\n\tprivate static readonly CSS_VAR_BORDER_SPACING = '--directus-visual-editing--rect--border-spacing';\n\tprivate static readonly CSS_VAR_BORDER_WIDTH = '--directus-visual-editing--rect--border-width';\n\tprivate static readonly CSS_VAR_BORDER_COLOR = '--directus-visual-editing--rect--border-color';\n\tprivate static readonly CSS_VAR_BORDER_RADIUS = '--directus-visual-editing--rect--border-radius';\n\tprivate static readonly CSS_VAR_HOVER_OPACITY = '--directus-visual-editing--rect-hover--opacity';\n\tprivate static readonly CSS_VAR_HIGHLIGHT_OPACITY = '--directus-visual-editing--rect-highlight--opacity';\n\tprivate static readonly CSS_VAR_ACTIONS_GAP = '--directus-visual-editing--actions--gap';\n\tprivate static readonly CSS_VAR_BUTTON_WIDTH = '--directus-visual-editing--edit-btn--width';\n\tprivate static readonly CSS_VAR_BUTTON_HEIGHT = '--directus-visual-editing--edit-btn--height';\n\tprivate static readonly CSS_VAR_BUTTON_RADIUS = '--directus-visual-editing--edit-btn--radius';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_BG_COLOR = '--directus-visual-editing--edit-btn--bg-color';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_ICON_BG_IMAGE = '--directus-visual-editing--edit-btn--icon-bg-image';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_ICON_BG_SIZE = '--directus-visual-editing--edit-btn--icon-bg-size';\n\tprivate static readonly CSS_VAR_AI_BUTTON_BG_COLOR = '--directus-visual-editing--ai-btn--bg-color';\n\tprivate static readonly CSS_VAR_AI_BUTTON_ICON_BG_IMAGE = '--directus-visual-editing--ai-btn--icon-bg-image';\n\tprivate static readonly CSS_VAR_AI_BUTTON_ICON_BG_SIZE = '--directus-visual-editing--ai-btn--icon-bg-size';\n\n\t// For icons use https://fonts.google.com/icons?icon.set=Material+Icons&icon.color=%23ffffff\n\tprivate static readonly ICON_EDIT = `url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"%23ffffff\"><path d=\"M0 0h24v24H0V0z\" fill=\"none\"/><path d=\"M14.06 9.02l.92.92L5.92 19H5v-.92l9.06-9.06M17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29zm-3.6 3.19L3 17.25V21h3.75L17.81 9.94l-3.75-3.75z\"/></svg>')`;\n\tprivate static readonly ICON_AI = `url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\"><path fill=\"%23ffffff\" d=\"M10 14.175L11 12l2.175-1L11 10l-1-2.175L9 10l-2.175 1L9 12l1 2.175ZM10 19l-2.5-5.5L2 11l5.5-2.5L10 3l2.5 5.5L18 11l-5.5 2.5L10 19Zm8 2l-1.25-2.75L14 17l2.75-1.25L18 13l1.25 2.75L22 17l-2.75 1.25L18 21Zm-8-10Z\"/></svg>')`;\n\n\tprivate static readonly OVERLAY_ID = 'directus-visual-editing';\n\tprivate static readonly STYLE_ID = 'directus-visual-editing-style';\n\n\tstatic readonly CONTAINER_RECT_CLASS_NAME = 'directus-visual-editing-overlay';\n\tstatic readonly RECT_CLASS_NAME = 'directus-visual-editing-rect';\n\tstatic readonly RECT_HIGHLIGHT_CLASS_NAME = 'directus-visual-editing-rect-highlight';\n\tstatic readonly RECT_HIGHLIGHT_ACTIVE_CLASS_NAME = 'directus-visual-editing-rect-highlight-active';\n\tstatic readonly RECT_PARENT_HOVER_CLASS_NAME = 'directus-visual-editing-rect-parent-hover';\n\tstatic readonly RECT_HOVER_CLASS_NAME = 'directus-visual-editing-rect-hover';\n\tstatic readonly RECT_INNER_CLASS_NAME = 'directus-visual-editing-rect-inner';\n\tstatic readonly RECT_BUTTON_CLASS_NAME = 'directus-visual-editing-button';\n\tstatic readonly RECT_EDIT_BUTTON_CLASS_NAME = 'directus-visual-editing-edit-button';\n\tstatic readonly RECT_AI_BUTTON_CLASS_NAME = 'directus-visual-editing-ai-button';\n\n\tstatic getGlobalOverlay(): HTMLElement {\n\t\tconst existingOverlay = document.getElementById(OverlayManager.OVERLAY_ID);\n\t\tif (existingOverlay) return existingOverlay;\n\n\t\tconst globalOverlay = document.createElement('div');\n\t\tglobalOverlay.id = OverlayManager.OVERLAY_ID;\n\t\tdocument.body.insertAdjacentElement('afterend', globalOverlay);\n\n\t\treturn globalOverlay;\n\t}\n\n\tstatic addStyles(): void {\n\t\tconst existingStyle = document.getElementById(OverlayManager.STYLE_ID);\n\t\tif (existingStyle) return;\n\n\t\tconst style = document.createElement('style');\n\t\tstyle.id = OverlayManager.STYLE_ID;\n\n\t\tconst buttonSize = 28;\n\t\tconst buttonWidth = `var(${OverlayManager.CSS_VAR_BUTTON_WIDTH}, ${buttonSize}px)`;\n\t\tconst buttonGap = 4;\n\t\tconst editButtonBgColor = `var(${OverlayManager.CSS_VAR_EDIT_BUTTON_BG_COLOR}, #6644ff)`;\n\t\tconst aiButtonBgColor = `var(${OverlayManager.CSS_VAR_AI_BUTTON_BG_COLOR}, ${editButtonBgColor})`;\n\t\tconst Line truncated
+50
View File
@@ -0,0 +1,50 @@
//#region src/lib/types/directus.d.ts
/** These types are shared with Directus */
/** Keep in sync with Directus */
type PrimaryKey = string | number;
type EditConfig$1 = {
collection: string;
item: PrimaryKey | null;
fields?: string[];
mode?: 'drawer' | 'modal' | 'popover';
};
type SavedData$1 = {
key: string;
collection: EditConfig$1['collection'];
item: EditConfig$1['item'];
payload: Record<string, unknown>;
};
//#endregion
//#region src/lib/types/index.d.ts
type EditConfigStrict = EditConfig$1;
type EditConfig = Omit<EditConfigStrict, 'fields'> & {
fields?: EditConfigStrict['fields'] | string;
};
type SavedData = SavedData$1;
type EditableElementOptions = {
customClass?: string | undefined;
onSaved?: ((data: Omit<SavedData, 'key'>) => void) | undefined;
};
//#endregion
//#region src/index.d.ts
declare function apply({
directusUrl,
elements,
customClass,
onSaved
}: {
directusUrl: string;
elements?: HTMLElement | HTMLElement[] | null;
} & EditableElementOptions): Promise<{
remove(): void;
enable(): void;
disable(): void;
} | undefined>;
declare function remove(): void;
declare function disable(): {
enable(): void;
};
declare function setAttr(editConfig: EditConfig): string;
//#endregion
export { apply, disable, remove, setAttr };
//# sourceMappingURL=index.d.cts.map
+50
View File
@@ -0,0 +1,50 @@
//#region src/lib/types/directus.d.ts
/** These types are shared with Directus */
/** Keep in sync with Directus */
type PrimaryKey = string | number;
type EditConfig$1 = {
collection: string;
item: PrimaryKey | null;
fields?: string[];
mode?: 'drawer' | 'modal' | 'popover';
};
type SavedData$1 = {
key: string;
collection: EditConfig$1['collection'];
item: EditConfig$1['item'];
payload: Record<string, unknown>;
};
//#endregion
//#region src/lib/types/index.d.ts
type EditConfigStrict = EditConfig$1;
type EditConfig = Omit<EditConfigStrict, 'fields'> & {
fields?: EditConfigStrict['fields'] | string;
};
type SavedData = SavedData$1;
type EditableElementOptions = {
customClass?: string | undefined;
onSaved?: ((data: Omit<SavedData, 'key'>) => void) | undefined;
};
//#endregion
//#region src/index.d.ts
declare function apply({
directusUrl,
elements,
customClass,
onSaved
}: {
directusUrl: string;
elements?: HTMLElement | HTMLElement[] | null;
} & EditableElementOptions): Promise<{
remove(): void;
enable(): void;
disable(): void;
} | undefined>;
declare function remove(): void;
declare function disable(): {
enable(): void;
};
declare function setAttr(editConfig: EditConfig): string;
//#endregion
export { apply, disable, remove, setAttr };
//# sourceMappingURL=index.d.ts.map
+89
View File
@@ -0,0 +1,89 @@
import e from"@reach/observe-rect";var t=class e{static CSS_VAR_Z_INDEX=`--directus-visual-editing--overlay--z-index`;static CSS_VAR_BORDER_SPACING=`--directus-visual-editing--rect--border-spacing`;static CSS_VAR_BORDER_WIDTH=`--directus-visual-editing--rect--border-width`;static CSS_VAR_BORDER_COLOR=`--directus-visual-editing--rect--border-color`;static CSS_VAR_BORDER_RADIUS=`--directus-visual-editing--rect--border-radius`;static CSS_VAR_HOVER_OPACITY=`--directus-visual-editing--rect-hover--opacity`;static CSS_VAR_HIGHLIGHT_OPACITY=`--directus-visual-editing--rect-highlight--opacity`;static CSS_VAR_ACTIONS_GAP=`--directus-visual-editing--actions--gap`;static CSS_VAR_BUTTON_WIDTH=`--directus-visual-editing--edit-btn--width`;static CSS_VAR_BUTTON_HEIGHT=`--directus-visual-editing--edit-btn--height`;static CSS_VAR_BUTTON_RADIUS=`--directus-visual-editing--edit-btn--radius`;static CSS_VAR_EDIT_BUTTON_BG_COLOR=`--directus-visual-editing--edit-btn--bg-color`;static CSS_VAR_EDIT_BUTTON_ICON_BG_IMAGE=`--directus-visual-editing--edit-btn--icon-bg-image`;static CSS_VAR_EDIT_BUTTON_ICON_BG_SIZE=`--directus-visual-editing--edit-btn--icon-bg-size`;static CSS_VAR_AI_BUTTON_BG_COLOR=`--directus-visual-editing--ai-btn--bg-color`;static CSS_VAR_AI_BUTTON_ICON_BG_IMAGE=`--directus-visual-editing--ai-btn--icon-bg-image`;static CSS_VAR_AI_BUTTON_ICON_BG_SIZE=`--directus-visual-editing--ai-btn--icon-bg-size`;static ICON_EDIT=`url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="%23ffffff"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M14.06 9.02l.92.92L5.92 19H5v-.92l9.06-9.06M17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29zm-3.6 3.19L3 17.25V21h3.75L17.81 9.94l-3.75-3.75z"/></svg>')`;static ICON_AI=`url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"><path fill="%23ffffff" d="M10 14.175L11 12l2.175-1L11 10l-1-2.175L9 10l-2.175 1L9 12l1 2.175ZM10 19l-2.5-5.5L2 11l5.5-2.5L10 3l2.5 5.5L18 11l-5.5 2.5L10 19Zm8 2l-1.25-2.75L14 17l2.75-1.25L18 13l1.25 2.75L22 17l-2.75 1.25L18 21Zm-8-10Z"/></svg>')`;static OVERLAY_ID=`directus-visual-editing`;static STYLE_ID=`directus-visual-editing-style`;static CONTAINER_RECT_CLASS_NAME=`directus-visual-editing-overlay`;static RECT_CLASS_NAME=`directus-visual-editing-rect`;static RECT_HIGHLIGHT_CLASS_NAME=`directus-visual-editing-rect-highlight`;static RECT_HIGHLIGHT_ACTIVE_CLASS_NAME=`directus-visual-editing-rect-highlight-active`;static RECT_PARENT_HOVER_CLASS_NAME=`directus-visual-editing-rect-parent-hover`;static RECT_HOVER_CLASS_NAME=`directus-visual-editing-rect-hover`;static RECT_INNER_CLASS_NAME=`directus-visual-editing-rect-inner`;static RECT_BUTTON_CLASS_NAME=`directus-visual-editing-button`;static RECT_EDIT_BUTTON_CLASS_NAME=`directus-visual-editing-edit-button`;static RECT_AI_BUTTON_CLASS_NAME=`directus-visual-editing-ai-button`;static getGlobalOverlay(){let t=document.getElementById(e.OVERLAY_ID);if(t)return t;let n=document.createElement(`div`);return n.id=e.OVERLAY_ID,document.body.insertAdjacentElement(`afterend`,n),n}static addStyles(){if(document.getElementById(e.STYLE_ID))return;let t=document.createElement(`style`);t.id=e.STYLE_ID;let n=`var(${e.CSS_VAR_BUTTON_WIDTH}, 28px)`,r=`var(${e.CSS_VAR_EDIT_BUTTON_BG_COLOR}, #6644ff)`,i=`var(${e.CSS_VAR_AI_BUTTON_BG_COLOR}, ${r})`,a=`#2e3C43 25%`,o=`var(${e.CSS_VAR_BORDER_SPACING}, 9px)`,s=`var(${e.CSS_VAR_BORDER_WIDTH}, 2px)`;t.appendChild(document.createTextNode(`
#${e.OVERLAY_ID} {
display: contents;
}
.${e.CONTAINER_RECT_CLASS_NAME} {
pointer-events: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: var(${e.CSS_VAR_Z_INDEX}, 999999999);
}
.${e.RECT_CLASS_NAME} {
position: absolute;
}
.${e.RECT_INNER_CLASS_NAME} {
position: absolute;
box-sizing: border-box;
top: calc(-1 * ${o});
left: calc(-1 * ${o});
right: calc(-1 * ${o});
bottom: calc(-1 * ${o});
border: ${s} solid var(${e.CSS_VAR_BORDER_COLOR}, #6644ff);
border-radius: var(${e.CSS_VAR_BORDER_RADIUS}, 6px);
opacity: 0;
}
.${e.RECT_CLASS_NAME}.${e.RECT_HOVER_CLASS_NAME} .${e.RECT_INNER_CLASS_NAME} {
--hover-opacity: var(${e.CSS_VAR_HOVER_OPACITY}, 0.333);
opacity: var(--hover-opacity);
}
.${e.RECT_CLASS_NAME}.${e.RECT_PARENT_HOVER_CLASS_NAME} .${e.RECT_INNER_CLASS_NAME} {
opacity: calc(var(--hover-opacity) / 3);
}
.${e.RECT_HIGHLIGHT_CLASS_NAME} {
pointer-events: all;
cursor: pointer;
}
.${e.RECT_HIGHLIGHT_CLASS_NAME} .${e.RECT_INNER_CLASS_NAME} {
opacity: var(${e.CSS_VAR_HIGHLIGHT_OPACITY}, 0.333);
}
.${e.RECT_BUTTON_CLASS_NAME}:visited,
.${e.RECT_BUTTON_CLASS_NAME}:active,
.${e.RECT_BUTTON_CLASS_NAME}:hover,
.${e.RECT_BUTTON_CLASS_NAME}:focus,
.${e.RECT_BUTTON_CLASS_NAME} {
all: initial;
pointer-events: all;
cursor: pointer;
position: absolute;
z-index: 1;
top: calc(-1 * ${o} + ${s} / 2);
transform: translate(-50%, -50%);
width: ${n};
height: var(${e.CSS_VAR_BUTTON_HEIGHT}, 28px);
border-radius: var(${e.CSS_VAR_BUTTON_RADIUS}, 50%);
background-position: center;
background-repeat: no-repeat;
opacity: 0;
}
.${e.RECT_BUTTON_CLASS_NAME}.${e.RECT_EDIT_BUTTON_CLASS_NAME} {
left: calc(-1 * ${o} + ${s} / 2);
background-color: ${r};
background-image: var(${e.CSS_VAR_EDIT_BUTTON_ICON_BG_IMAGE}, ${e.ICON_EDIT});
background-size: var(${e.CSS_VAR_EDIT_BUTTON_ICON_BG_SIZE}, 66.6%);
}
.${e.RECT_BUTTON_CLASS_NAME}.${e.RECT_AI_BUTTON_CLASS_NAME} {
left: calc(-1 * ${o} + ${s} / 2 + ${n} + var(${e.CSS_VAR_ACTIONS_GAP}, 4px));
background-color: ${i};
background-image: var(${e.CSS_VAR_AI_BUTTON_ICON_BG_IMAGE}, ${e.ICON_AI});
background-size: var(${e.CSS_VAR_AI_BUTTON_ICON_BG_SIZE}, 66.6%);
}
.${e.RECT_CLASS_NAME}.${e.RECT_HOVER_CLASS_NAME}:not(.${e.RECT_PARENT_HOVER_CLASS_NAME}) .${e.RECT_BUTTON_CLASS_NAME},
.${e.RECT_HIGHLIGHT_ACTIVE_CLASS_NAME} .${e.RECT_INNER_CLASS_NAME},
.${e.RECT_HIGHLIGHT_CLASS_NAME}:hover .${e.RECT_BUTTON_CLASS_NAME},
.${e.RECT_BUTTON_CLASS_NAME}:hover,
.${e.RECT_BUTTON_CLASS_NAME}:hover ~ .${e.RECT_INNER_CLASS_NAME},
.${e.RECT_HIGHLIGHT_CLASS_NAME}:hover .${e.RECT_INNER_CLASS_NAME},
.${e.RECT_CLASS_NAME}:has(.${e.RECT_BUTTON_CLASS_NAME}:hover) .${e.RECT_BUTTON_CLASS_NAME} {
opacity: 1;
}
.${e.RECT_BUTTON_CLASS_NAME}.${e.RECT_EDIT_BUTTON_CLASS_NAME}:hover {
background-color: color-mix(in srgb, ${r}, ${a});
}
.${e.RECT_BUTTON_CLASS_NAME}.${e.RECT_AI_BUTTON_CLASS_NAME}:hover {
background-color: color-mix(in srgb, ${i}, ${a});
}
`)),document.head.appendChild(t)}},n=class{hasNoDimensions=!1;element;container;editButton;aiButton;constructor(){this.container=this.createContainer(),this.element=this.createElement(),this.editButton=this.createEditButton(),this.aiButton=new a().isAiEnabled()?this.createAiButton():null,this.createRectElement(),t.getGlobalOverlay().appendChild(this.container),i.highlightOverlayElements&&this.toggleHighlight(!0),this.element.addEventListener(`click`,()=>this.editButton.click())}createContainer(){let e=document.createElement(`div`);return e.classList.add(t.CONTAINER_RECT_CLASS_NAME),e}createElement(){let e=document.createElement(`div`);return e.classList.add(t.RECT_CLASS_NAME),this.container.appendChild(e),e}createRectElement(){let e=document.createElement(`div`);e.classList.add(t.RECT_INNER_CLASS_NAME),this.element.appendChild(e)}createEditButton(){let e=document.createElement(`button`);return e.type=`button`,e.classList.add(t.RECT_BUTTON_CLASS_NAME),e.classList.add(t.RECT_EDIT_BUTTON_CLASS_NAME),this.element.appendChild(e),e}createAiButton(){let e=document.createElement(`button`);return e.type=`button`,e.classList.add(t.RECT_BUTTON_CLASS_NAME),e.classList.add(t.RECT_AI_BUTTON_CLASS_NAME),this.element.appendChild(e),e}updateRect(e){let t=e.width!==0&&e.height!==0;if(!this.hasNoDimensions&&!t){this.hasNoDimensions=!0,this.disable();return}this.hasNoDimensions&&t&&(this.hasNoDimensions=!1,this.enable()),this.element.style.width=`${e.width}px`,this.element.style.height=`${e.height}px`,this.element.style.transform=`translate(${e.left}px,${e.top}px)`}setCustomClass(e){e!==void 0&&/^[a-zA-Z_][\w-]*$/.test(e)&&this.container.classList.add(e)}toggleHover(e){this.element.classList.toggle(t.RECT_HOVER_CLASS_NAME,e)}toggleParentHover(e){this.element.classList.toggle(t.RECT_PARENT_HOVER_CLASS_NAME,e)}toggleHighlight(e){this.element.classList.toggle(t.RECT_HIGHLIGHT_CLASS_NAME,e)}toggleHighlightActive(e){this.element.classList.toggle(t.RECT_HIGHLIGHT_ACTIVE_CLASS_NAME,e)}disable(){this.element.style.display=`none`}enable(){this.element.style.removeProperty(`display`)}remove(){this.container.remove()}},r=class t{static DATASET=`directus`;static DATA_ATTRIBUTE_VALID_KEYS=[`collection`,`item`,`fields`,`mode`];optionsWritable=!0;element;key;editConfig;rectObserver;overlayElement;rect;hover=!1;disabled=!1;onSaved=void 0;boundMouseenter;boundMouseleave;constructor(r){this.element=r,this.boundMouseenter=this.onMouseenter.bind(this),this.boundMouseleave=this.onMouseleave.bind(this),this.element.addEventListener(`mouseenter`,this.boundMouseenter),this.element.addEventListener(`mouseleave`,this.boundMouseleave),this.key=crypto.randomUUID(),this.editConfig=t.editAttrToObject(this.element.dataset[t.DATASET]),this.rect=this.element.getBoundingClientRect(),this.overlayElement=new n,this.overlayElement.updateRect(this.rect),this.overlayElement.editButton.addEventListener(`click`,this.onClickEdit.bind(this)),this.overlayElement.aiButton?.addEventListener(`click`,this.onClickAddToContext.bind(this)),this.rectObserver=e(this.element,this.onObserveRect.bind(this)),this.rectObserver.observe()}static query(e){return e?(Array.isArray(e)?e:[e]).filter(e=>e instanceof HTMLElement).flatMap(e=>e.dataset[t.DATASET]===void 0?Array.from(e.querySelectorAll(`[data-${t.DATASET}]`)):e).filter(e=>e!==null):Array.from(document.querySelectorAll(`[data-${t.DATASET}]`))}static objectToEditAttr(e){let n=[];for(let[r,i]of Object.entries(e))t.validEditConfigKey(r)&&(r===`fields`&&Array.isArray(i)?n.push(`${r}:${i.join(`,`)}`):n.push(`${r}:${i}`));return n.join(`;`)}static editAttrToObject(e){let n=e.split(`;`),r={};return n.forEach(e=>{let n=e.split(`:`);if(n[0]===void 0||n?.[1]===void 0)return;let i=n[0].trim();if(!t.validEditConfigKey(i))return;let a=n[1];if(i===`fields`){r.fields=a.split(`,`).map(e=>e.trim());return}r[i]=a.trim()}),r}static validEditConfigKey(e){return t.DATA_ATTRIBUTE_VALID_KEYS.includes(e)}applyOptions({customClass:e,onSaved:t},n=!1){this.optionsWritable&&(n&&(this.optionsWritable=!1),this.overlayElement.setCustomClass(e),t!==void 0&&(this.onSaved=t))}removeHoverListener(){this.element.removeEventListener(`mouseenter`,this.boundMouseenter),this.element.removeEventListener(`mouseleave`,this.boundMouseleave)}onClickEdit(){new a().send(`edit`,{key:this.key,editConfig:this.editConfig,rect:this.rect})}onClickAddToContext(e){e.stopPropagation(),new a().send(`addToContext`,{key:this.key,editConfig:this.editConfig,rect:this.rect})}onMouseenter(e){this.toggleItemHover(!0,e)}onMouseleave(e){this.toggleItemHover(!1,e)}toggleItemHover(e,t){this.element!==t.currentTarget||this.hover===e||(this.hover=e,this.setParentsHover(),this.overlayElement.toggleHover(e))}setParentsHover(){let e=i.getHoveredItems();e.forEach(t=>{let n=e.filter(e=>e.element!==t.element).some(e=>t.element.contains(e.element));t.overlayElement.toggleParentHover(n)})}onObserveRect(e){this.disabled||(this.rect=e,this.overlayElement.updateRect(e))}},i=class e{static items=[];static Line truncated
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","names":[],"sources":["../src/lib/overlay-manager.ts","../src/lib/overlay-element.ts","../src/lib/editable-element.ts","../src/lib/editable-store.ts","../src/lib/directus-frame.ts","../src/lib/page-manager.ts","../src/index.ts"],"sourcesContent":["export class OverlayManager {\n\tprivate static readonly CSS_VAR_Z_INDEX = '--directus-visual-editing--overlay--z-index';\n\tprivate static readonly CSS_VAR_BORDER_SPACING = '--directus-visual-editing--rect--border-spacing';\n\tprivate static readonly CSS_VAR_BORDER_WIDTH = '--directus-visual-editing--rect--border-width';\n\tprivate static readonly CSS_VAR_BORDER_COLOR = '--directus-visual-editing--rect--border-color';\n\tprivate static readonly CSS_VAR_BORDER_RADIUS = '--directus-visual-editing--rect--border-radius';\n\tprivate static readonly CSS_VAR_HOVER_OPACITY = '--directus-visual-editing--rect-hover--opacity';\n\tprivate static readonly CSS_VAR_HIGHLIGHT_OPACITY = '--directus-visual-editing--rect-highlight--opacity';\n\tprivate static readonly CSS_VAR_ACTIONS_GAP = '--directus-visual-editing--actions--gap';\n\tprivate static readonly CSS_VAR_BUTTON_WIDTH = '--directus-visual-editing--edit-btn--width';\n\tprivate static readonly CSS_VAR_BUTTON_HEIGHT = '--directus-visual-editing--edit-btn--height';\n\tprivate static readonly CSS_VAR_BUTTON_RADIUS = '--directus-visual-editing--edit-btn--radius';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_BG_COLOR = '--directus-visual-editing--edit-btn--bg-color';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_ICON_BG_IMAGE = '--directus-visual-editing--edit-btn--icon-bg-image';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_ICON_BG_SIZE = '--directus-visual-editing--edit-btn--icon-bg-size';\n\tprivate static readonly CSS_VAR_AI_BUTTON_BG_COLOR = '--directus-visual-editing--ai-btn--bg-color';\n\tprivate static readonly CSS_VAR_AI_BUTTON_ICON_BG_IMAGE = '--directus-visual-editing--ai-btn--icon-bg-image';\n\tprivate static readonly CSS_VAR_AI_BUTTON_ICON_BG_SIZE = '--directus-visual-editing--ai-btn--icon-bg-size';\n\n\t// For icons use https://fonts.google.com/icons?icon.set=Material+Icons&icon.color=%23ffffff\n\tprivate static readonly ICON_EDIT = `url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"%23ffffff\"><path d=\"M0 0h24v24H0V0z\" fill=\"none\"/><path d=\"M14.06 9.02l.92.92L5.92 19H5v-.92l9.06-9.06M17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29zm-3.6 3.19L3 17.25V21h3.75L17.81 9.94l-3.75-3.75z\"/></svg>')`;\n\tprivate static readonly ICON_AI = `url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\"><path fill=\"%23ffffff\" d=\"M10 14.175L11 12l2.175-1L11 10l-1-2.175L9 10l-2.175 1L9 12l1 2.175ZM10 19l-2.5-5.5L2 11l5.5-2.5L10 3l2.5 5.5L18 11l-5.5 2.5L10 19Zm8 2l-1.25-2.75L14 17l2.75-1.25L18 13l1.25 2.75L22 17l-2.75 1.25L18 21Zm-8-10Z\"/></svg>')`;\n\n\tprivate static readonly OVERLAY_ID = 'directus-visual-editing';\n\tprivate static readonly STYLE_ID = 'directus-visual-editing-style';\n\n\tstatic readonly CONTAINER_RECT_CLASS_NAME = 'directus-visual-editing-overlay';\n\tstatic readonly RECT_CLASS_NAME = 'directus-visual-editing-rect';\n\tstatic readonly RECT_HIGHLIGHT_CLASS_NAME = 'directus-visual-editing-rect-highlight';\n\tstatic readonly RECT_HIGHLIGHT_ACTIVE_CLASS_NAME = 'directus-visual-editing-rect-highlight-active';\n\tstatic readonly RECT_PARENT_HOVER_CLASS_NAME = 'directus-visual-editing-rect-parent-hover';\n\tstatic readonly RECT_HOVER_CLASS_NAME = 'directus-visual-editing-rect-hover';\n\tstatic readonly RECT_INNER_CLASS_NAME = 'directus-visual-editing-rect-inner';\n\tstatic readonly RECT_BUTTON_CLASS_NAME = 'directus-visual-editing-button';\n\tstatic readonly RECT_EDIT_BUTTON_CLASS_NAME = 'directus-visual-editing-edit-button';\n\tstatic readonly RECT_AI_BUTTON_CLASS_NAME = 'directus-visual-editing-ai-button';\n\n\tstatic getGlobalOverlay(): HTMLElement {\n\t\tconst existingOverlay = document.getElementById(OverlayManager.OVERLAY_ID);\n\t\tif (existingOverlay) return existingOverlay;\n\n\t\tconst globalOverlay = document.createElement('div');\n\t\tglobalOverlay.id = OverlayManager.OVERLAY_ID;\n\t\tdocument.body.insertAdjacentElement('afterend', globalOverlay);\n\n\t\treturn globalOverlay;\n\t}\n\n\tstatic addStyles(): void {\n\t\tconst existingStyle = document.getElementById(OverlayManager.STYLE_ID);\n\t\tif (existingStyle) return;\n\n\t\tconst style = document.createElement('style');\n\t\tstyle.id = OverlayManager.STYLE_ID;\n\n\t\tconst buttonSize = 28;\n\t\tconst buttonWidth = `var(${OverlayManager.CSS_VAR_BUTTON_WIDTH}, ${buttonSize}px)`;\n\t\tconst buttonGap = 4;\n\t\tconst editButtonBgColor = `var(${OverlayManager.CSS_VAR_EDIT_BUTTON_BG_COLOR}, #6644ff)`;\n\t\tconst aiButtonBgColor = `var(${OverlayManager.CSS_VAR_AI_BUTTON_BG_COLOR}, ${editButtonBgColor})`;\n\t\tconst bLine truncated
+89
View File
@@ -0,0 +1,89 @@
var DirectusVisualEditing=(function(e,t){var n=Object.create,r=Object.defineProperty,i=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,o=Object.getPrototypeOf,s=Object.prototype.hasOwnProperty,c=(e,t,n,o)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var c=a(t),l=0,u=c.length,d;l<u;l++)d=c[l],!s.call(e,d)&&d!==n&&r(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(o=i(t,d))||o.enumerable});return e};t=((e,t,i)=>(i=e==null?{}:n(o(e)),c(t||!e||!e.__esModule?r(i,`default`,{value:e,enumerable:!0}):i,e)))(t);var l=class e{static CSS_VAR_Z_INDEX=`--directus-visual-editing--overlay--z-index`;static CSS_VAR_BORDER_SPACING=`--directus-visual-editing--rect--border-spacing`;static CSS_VAR_BORDER_WIDTH=`--directus-visual-editing--rect--border-width`;static CSS_VAR_BORDER_COLOR=`--directus-visual-editing--rect--border-color`;static CSS_VAR_BORDER_RADIUS=`--directus-visual-editing--rect--border-radius`;static CSS_VAR_HOVER_OPACITY=`--directus-visual-editing--rect-hover--opacity`;static CSS_VAR_HIGHLIGHT_OPACITY=`--directus-visual-editing--rect-highlight--opacity`;static CSS_VAR_ACTIONS_GAP=`--directus-visual-editing--actions--gap`;static CSS_VAR_BUTTON_WIDTH=`--directus-visual-editing--edit-btn--width`;static CSS_VAR_BUTTON_HEIGHT=`--directus-visual-editing--edit-btn--height`;static CSS_VAR_BUTTON_RADIUS=`--directus-visual-editing--edit-btn--radius`;static CSS_VAR_EDIT_BUTTON_BG_COLOR=`--directus-visual-editing--edit-btn--bg-color`;static CSS_VAR_EDIT_BUTTON_ICON_BG_IMAGE=`--directus-visual-editing--edit-btn--icon-bg-image`;static CSS_VAR_EDIT_BUTTON_ICON_BG_SIZE=`--directus-visual-editing--edit-btn--icon-bg-size`;static CSS_VAR_AI_BUTTON_BG_COLOR=`--directus-visual-editing--ai-btn--bg-color`;static CSS_VAR_AI_BUTTON_ICON_BG_IMAGE=`--directus-visual-editing--ai-btn--icon-bg-image`;static CSS_VAR_AI_BUTTON_ICON_BG_SIZE=`--directus-visual-editing--ai-btn--icon-bg-size`;static ICON_EDIT=`url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="%23ffffff"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M14.06 9.02l.92.92L5.92 19H5v-.92l9.06-9.06M17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29zm-3.6 3.19L3 17.25V21h3.75L17.81 9.94l-3.75-3.75z"/></svg>')`;static ICON_AI=`url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"><path fill="%23ffffff" d="M10 14.175L11 12l2.175-1L11 10l-1-2.175L9 10l-2.175 1L9 12l1 2.175ZM10 19l-2.5-5.5L2 11l5.5-2.5L10 3l2.5 5.5L18 11l-5.5 2.5L10 19Zm8 2l-1.25-2.75L14 17l2.75-1.25L18 13l1.25 2.75L22 17l-2.75 1.25L18 21Zm-8-10Z"/></svg>')`;static OVERLAY_ID=`directus-visual-editing`;static STYLE_ID=`directus-visual-editing-style`;static CONTAINER_RECT_CLASS_NAME=`directus-visual-editing-overlay`;static RECT_CLASS_NAME=`directus-visual-editing-rect`;static RECT_HIGHLIGHT_CLASS_NAME=`directus-visual-editing-rect-highlight`;static RECT_HIGHLIGHT_ACTIVE_CLASS_NAME=`directus-visual-editing-rect-highlight-active`;static RECT_PARENT_HOVER_CLASS_NAME=`directus-visual-editing-rect-parent-hover`;static RECT_HOVER_CLASS_NAME=`directus-visual-editing-rect-hover`;static RECT_INNER_CLASS_NAME=`directus-visual-editing-rect-inner`;static RECT_BUTTON_CLASS_NAME=`directus-visual-editing-button`;static RECT_EDIT_BUTTON_CLASS_NAME=`directus-visual-editing-edit-button`;static RECT_AI_BUTTON_CLASS_NAME=`directus-visual-editing-ai-button`;static getGlobalOverlay(){let t=document.getElementById(e.OVERLAY_ID);if(t)return t;let n=document.createElement(`div`);return n.id=e.OVERLAY_ID,document.body.insertAdjacentElement(`afterend`,n),n}static addStyles(){if(document.getElementById(e.STYLE_ID))return;let t=document.createElement(`style`);t.id=e.STYLE_ID;let n=`var(${e.CSS_VAR_BUTTON_WIDTH}, 28px)`,r=`var(${e.CSS_VAR_EDIT_BUTTON_BG_COLOR}, #6644ff)`,i=`var(${e.CSS_VAR_AI_BUTTON_BG_COLOR}, ${r})`,a=`#2e3C43 25%`,o=`var(${e.CSS_VAR_BORDER_SPACING}, 9px)`,s=`var(${e.CSS_VAR_BORDER_WIDTH}, 2px)`;t.appendChild(document.createTextNode(`
#${e.OVERLAY_ID} {
display: contents;
}
.${e.CONTAINER_RECT_CLASS_NAME} {
pointer-events: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: var(${e.CSS_VAR_Z_INDEX}, 999999999);
}
.${e.RECT_CLASS_NAME} {
position: absolute;
}
.${e.RECT_INNER_CLASS_NAME} {
position: absolute;
box-sizing: border-box;
top: calc(-1 * ${o});
left: calc(-1 * ${o});
right: calc(-1 * ${o});
bottom: calc(-1 * ${o});
border: ${s} solid var(${e.CSS_VAR_BORDER_COLOR}, #6644ff);
border-radius: var(${e.CSS_VAR_BORDER_RADIUS}, 6px);
opacity: 0;
}
.${e.RECT_CLASS_NAME}.${e.RECT_HOVER_CLASS_NAME} .${e.RECT_INNER_CLASS_NAME} {
--hover-opacity: var(${e.CSS_VAR_HOVER_OPACITY}, 0.333);
opacity: var(--hover-opacity);
}
.${e.RECT_CLASS_NAME}.${e.RECT_PARENT_HOVER_CLASS_NAME} .${e.RECT_INNER_CLASS_NAME} {
opacity: calc(var(--hover-opacity) / 3);
}
.${e.RECT_HIGHLIGHT_CLASS_NAME} {
pointer-events: all;
cursor: pointer;
}
.${e.RECT_HIGHLIGHT_CLASS_NAME} .${e.RECT_INNER_CLASS_NAME} {
opacity: var(${e.CSS_VAR_HIGHLIGHT_OPACITY}, 0.333);
}
.${e.RECT_BUTTON_CLASS_NAME}:visited,
.${e.RECT_BUTTON_CLASS_NAME}:active,
.${e.RECT_BUTTON_CLASS_NAME}:hover,
.${e.RECT_BUTTON_CLASS_NAME}:focus,
.${e.RECT_BUTTON_CLASS_NAME} {
all: initial;
pointer-events: all;
cursor: pointer;
position: absolute;
z-index: 1;
top: calc(-1 * ${o} + ${s} / 2);
transform: translate(-50%, -50%);
width: ${n};
height: var(${e.CSS_VAR_BUTTON_HEIGHT}, 28px);
border-radius: var(${e.CSS_VAR_BUTTON_RADIUS}, 50%);
background-position: center;
background-repeat: no-repeat;
opacity: 0;
}
.${e.RECT_BUTTON_CLASS_NAME}.${e.RECT_EDIT_BUTTON_CLASS_NAME} {
left: calc(-1 * ${o} + ${s} / 2);
background-color: ${r};
background-image: var(${e.CSS_VAR_EDIT_BUTTON_ICON_BG_IMAGE}, ${e.ICON_EDIT});
background-size: var(${e.CSS_VAR_EDIT_BUTTON_ICON_BG_SIZE}, 66.6%);
}
.${e.RECT_BUTTON_CLASS_NAME}.${e.RECT_AI_BUTTON_CLASS_NAME} {
left: calc(-1 * ${o} + ${s} / 2 + ${n} + var(${e.CSS_VAR_ACTIONS_GAP}, 4px));
background-color: ${i};
background-image: var(${e.CSS_VAR_AI_BUTTON_ICON_BG_IMAGE}, ${e.ICON_AI});
background-size: var(${e.CSS_VAR_AI_BUTTON_ICON_BG_SIZE}, 66.6%);
}
.${e.RECT_CLASS_NAME}.${e.RECT_HOVER_CLASS_NAME}:not(.${e.RECT_PARENT_HOVER_CLASS_NAME}) .${e.RECT_BUTTON_CLASS_NAME},
.${e.RECT_HIGHLIGHT_ACTIVE_CLASS_NAME} .${e.RECT_INNER_CLASS_NAME},
.${e.RECT_HIGHLIGHT_CLASS_NAME}:hover .${e.RECT_BUTTON_CLASS_NAME},
.${e.RECT_BUTTON_CLASS_NAME}:hover,
.${e.RECT_BUTTON_CLASS_NAME}:hover ~ .${e.RECT_INNER_CLASS_NAME},
.${e.RECT_HIGHLIGHT_CLASS_NAME}:hover .${e.RECT_INNER_CLASS_NAME},
.${e.RECT_CLASS_NAME}:has(.${e.RECT_BUTTON_CLASS_NAME}:hover) .${e.RECT_BUTTON_CLASS_NAME} {
opacity: 1;
}
.${e.RECT_BUTTON_CLASS_NAME}.${e.RECT_EDIT_BUTTON_CLASS_NAME}:hover {
background-color: color-mix(in srgb, ${r}, ${a});
}
.${e.RECT_BUTTON_CLASS_NAME}.${e.RECT_AI_BUTTON_CLASS_NAME}:hover {
background-color: color-mix(in srgb, ${i}, ${a});
}
`)),document.head.appendChild(t)}},u=class{hasNoDimensions=!1;element;container;editButton;aiButton;constructor(){this.container=this.createContainer(),this.element=this.createElement(),this.editButton=this.createEditButton(),this.aiButton=new p().isAiEnabled()?this.createAiButton():null,this.createRectElement(),l.getGlobalOverlay().appendChild(this.container),f.highlightOverlayElements&&this.toggleHighlight(!0),this.element.addEventListener(`click`,()=>this.editButton.click())}createContainer(){let e=document.createElement(`div`);return e.classList.add(l.CONTAINER_RECT_CLASS_NAME),e}createElement(){let e=document.createElement(`div`);return e.classList.add(l.RECT_CLASS_NAME),this.container.appendChild(e),e}createRectElement(){let e=document.createElement(`div`);e.classList.add(l.RECT_INNER_CLASS_NAME),this.element.appendChild(e)}createEditButton(){let e=document.createElement(`button`);return e.type=`button`,e.classList.add(l.RECT_BUTTON_CLASS_NAME),e.classList.add(l.RECT_EDIT_BUTTON_CLASS_NAME),this.element.appendChild(e),e}createAiButton(){let e=document.createElement(`button`);return e.type=`button`,e.classList.add(l.RECT_BUTTON_CLASS_NAME),e.classList.add(l.RECT_AI_BUTTON_CLASS_NAME),this.element.appendChild(e),e}updateRect(e){let t=e.width!==0&&e.height!==0;if(!this.hasNoDimensions&&!t){this.hasNoDimensions=!0,this.disable();return}this.hasNoDimensions&&t&&(this.hasNoDimensions=!1,this.enable()),this.element.style.width=`${e.width}px`,this.element.style.height=`${e.height}px`,this.element.style.transform=`translate(${e.left}px,${e.top}px)`}setCustomClass(e){e!==void 0&&/^[a-zA-Z_][\w-]*$/.test(e)&&this.container.classList.add(e)}toggleHover(e){this.element.classList.toggle(l.RECT_HOVER_CLASS_NAME,e)}toggleParentHover(e){this.element.classList.toggle(l.RECT_PARENT_HOVER_CLASS_NAME,e)}toggleHighlight(e){this.element.classList.toggle(l.RECT_HIGHLIGHT_CLASS_NAME,e)}toggleHighlightActive(e){this.element.classList.toggle(l.RECT_HIGHLIGHT_ACTIVE_CLASS_NAME,e)}disable(){this.element.style.display=`none`}enable(){this.element.style.removeProperty(`display`)}remove(){this.container.remove()}},d=class e{static DATASET=`directus`;static DATA_ATTRIBUTE_VALID_KEYS=[`collection`,`item`,`fields`,`mode`];optionsWritable=!0;element;key;editConfig;rectObserver;overlayElement;rect;hover=!1;disabled=!1;onSaved=void 0;boundMouseenter;boundMouseleave;constructor(n){this.element=n,this.boundMouseenter=this.onMouseenter.bind(this),this.boundMouseleave=this.onMouseleave.bind(this),this.element.addEventListener(`mouseenter`,this.boundMouseenter),this.element.addEventListener(`mouseleave`,this.boundMouseleave),this.key=crypto.randomUUID(),this.editConfig=e.editAttrToObject(this.element.dataset[e.DATASET]),this.rect=this.element.getBoundingClientRect(),this.overlayElement=new u,this.overlayElement.updateRect(this.rect),this.overlayElement.editButton.addEventListener(`click`,this.onClickEdit.bind(this)),this.overlayElement.aiButton?.addEventListener(`click`,this.onClickAddToContext.bind(this)),this.rectObserver=(0,t.default)(this.element,this.onObserveRect.bind(this)),this.rectObserver.observe()}static query(t){return t?(Array.isArray(t)?t:[t]).filter(e=>e instanceof HTMLElement).flatMap(t=>t.dataset[e.DATASET]===void 0?Array.from(t.querySelectorAll(`[data-${e.DATASET}]`)):t).filter(e=>e!==null):Array.from(document.querySelectorAll(`[data-${e.DATASET}]`))}static objectToEditAttr(t){let n=[];for(let[r,i]of Object.entries(t))e.validEditConfigKey(r)&&(r===`fields`&&Array.isArray(i)?n.push(`${r}:${i.join(`,`)}`):n.push(`${r}:${i}`));return n.join(`;`)}static editAttrToObject(t){let n=t.split(`;`),r={};return n.forEach(t=>{let n=t.split(`:`);if(n[0]===void 0||n?.[1]===void 0)return;let i=n[0].trim();if(!e.validEditConfigKey(i))return;let a=n[1];if(i===`fields`){r.fields=a.split(`,`).map(e=>e.trim());return}r[i]=a.trim()}),r}static validEditConfigKey(t){return e.DATA_ATTRIBUTE_VALID_KEYS.includes(t)}applyOptions({customClass:e,onSaved:t},n=!1){this.optionsWritable&&(n&&(this.optionsWritable=!1),this.overlayElement.setCustomClass(e),t!==void 0&&(this.onSaved=t))}removeHoverListener(){this.element.removeEventListener(`mouseenter`,this.boundMouseenter),this.element.removeEventListener(`mouseleave`,this.boundMouseleave)}onClickEdit(){new p().send(`edit`,{key:this.key,editConfig:this.editConfig,rect:this.rect})}onClickAddToContext(e){e.stopPropagation(),new p().send(`addToContext`,{key:this.key,editConfig:this.editConfig,rect:this.rect})}onMouseenter(e){this.toggleItemHover(!0,e)}onMouseleave(e){this.toggleItemHover(!1,e)}toggleItemHover(e,t){this.element!==t.currentTarget||this.hover===e||(this.hover=e,this.setParentsHover(),this.overlayElement.toggleHover(e))}setParentsHover(){let e=f.getHoveredItems();e.forEach(t=>{let n=e.filter(e=>e.element!==t.element).some(e=>t.element.contains(e.element));t.overlayElement.toggleParentHover(n)})}onObserveRect(e){this.disabled||(this.rect=e,this.overlayElement.updateRect(e))}},f=class e{static item Line truncated
//# sourceMappingURL=visual-editing.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"visual-editing.js","names":[],"sources":["../src/lib/overlay-manager.ts","../src/lib/overlay-element.ts","../src/lib/editable-element.ts","../src/lib/editable-store.ts","../src/lib/directus-frame.ts","../src/lib/page-manager.ts","../src/index.ts"],"sourcesContent":["export class OverlayManager {\n\tprivate static readonly CSS_VAR_Z_INDEX = '--directus-visual-editing--overlay--z-index';\n\tprivate static readonly CSS_VAR_BORDER_SPACING = '--directus-visual-editing--rect--border-spacing';\n\tprivate static readonly CSS_VAR_BORDER_WIDTH = '--directus-visual-editing--rect--border-width';\n\tprivate static readonly CSS_VAR_BORDER_COLOR = '--directus-visual-editing--rect--border-color';\n\tprivate static readonly CSS_VAR_BORDER_RADIUS = '--directus-visual-editing--rect--border-radius';\n\tprivate static readonly CSS_VAR_HOVER_OPACITY = '--directus-visual-editing--rect-hover--opacity';\n\tprivate static readonly CSS_VAR_HIGHLIGHT_OPACITY = '--directus-visual-editing--rect-highlight--opacity';\n\tprivate static readonly CSS_VAR_ACTIONS_GAP = '--directus-visual-editing--actions--gap';\n\tprivate static readonly CSS_VAR_BUTTON_WIDTH = '--directus-visual-editing--edit-btn--width';\n\tprivate static readonly CSS_VAR_BUTTON_HEIGHT = '--directus-visual-editing--edit-btn--height';\n\tprivate static readonly CSS_VAR_BUTTON_RADIUS = '--directus-visual-editing--edit-btn--radius';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_BG_COLOR = '--directus-visual-editing--edit-btn--bg-color';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_ICON_BG_IMAGE = '--directus-visual-editing--edit-btn--icon-bg-image';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_ICON_BG_SIZE = '--directus-visual-editing--edit-btn--icon-bg-size';\n\tprivate static readonly CSS_VAR_AI_BUTTON_BG_COLOR = '--directus-visual-editing--ai-btn--bg-color';\n\tprivate static readonly CSS_VAR_AI_BUTTON_ICON_BG_IMAGE = '--directus-visual-editing--ai-btn--icon-bg-image';\n\tprivate static readonly CSS_VAR_AI_BUTTON_ICON_BG_SIZE = '--directus-visual-editing--ai-btn--icon-bg-size';\n\n\t// For icons use https://fonts.google.com/icons?icon.set=Material+Icons&icon.color=%23ffffff\n\tprivate static readonly ICON_EDIT = `url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"%23ffffff\"><path d=\"M0 0h24v24H0V0z\" fill=\"none\"/><path d=\"M14.06 9.02l.92.92L5.92 19H5v-.92l9.06-9.06M17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29zm-3.6 3.19L3 17.25V21h3.75L17.81 9.94l-3.75-3.75z\"/></svg>')`;\n\tprivate static readonly ICON_AI = `url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\"><path fill=\"%23ffffff\" d=\"M10 14.175L11 12l2.175-1L11 10l-1-2.175L9 10l-2.175 1L9 12l1 2.175ZM10 19l-2.5-5.5L2 11l5.5-2.5L10 3l2.5 5.5L18 11l-5.5 2.5L10 19Zm8 2l-1.25-2.75L14 17l2.75-1.25L18 13l1.25 2.75L22 17l-2.75 1.25L18 21Zm-8-10Z\"/></svg>')`;\n\n\tprivate static readonly OVERLAY_ID = 'directus-visual-editing';\n\tprivate static readonly STYLE_ID = 'directus-visual-editing-style';\n\n\tstatic readonly CONTAINER_RECT_CLASS_NAME = 'directus-visual-editing-overlay';\n\tstatic readonly RECT_CLASS_NAME = 'directus-visual-editing-rect';\n\tstatic readonly RECT_HIGHLIGHT_CLASS_NAME = 'directus-visual-editing-rect-highlight';\n\tstatic readonly RECT_HIGHLIGHT_ACTIVE_CLASS_NAME = 'directus-visual-editing-rect-highlight-active';\n\tstatic readonly RECT_PARENT_HOVER_CLASS_NAME = 'directus-visual-editing-rect-parent-hover';\n\tstatic readonly RECT_HOVER_CLASS_NAME = 'directus-visual-editing-rect-hover';\n\tstatic readonly RECT_INNER_CLASS_NAME = 'directus-visual-editing-rect-inner';\n\tstatic readonly RECT_BUTTON_CLASS_NAME = 'directus-visual-editing-button';\n\tstatic readonly RECT_EDIT_BUTTON_CLASS_NAME = 'directus-visual-editing-edit-button';\n\tstatic readonly RECT_AI_BUTTON_CLASS_NAME = 'directus-visual-editing-ai-button';\n\n\tstatic getGlobalOverlay(): HTMLElement {\n\t\tconst existingOverlay = document.getElementById(OverlayManager.OVERLAY_ID);\n\t\tif (existingOverlay) return existingOverlay;\n\n\t\tconst globalOverlay = document.createElement('div');\n\t\tglobalOverlay.id = OverlayManager.OVERLAY_ID;\n\t\tdocument.body.insertAdjacentElement('afterend', globalOverlay);\n\n\t\treturn globalOverlay;\n\t}\n\n\tstatic addStyles(): void {\n\t\tconst existingStyle = document.getElementById(OverlayManager.STYLE_ID);\n\t\tif (existingStyle) return;\n\n\t\tconst style = document.createElement('style');\n\t\tstyle.id = OverlayManager.STYLE_ID;\n\n\t\tconst buttonSize = 28;\n\t\tconst buttonWidth = `var(${OverlayManager.CSS_VAR_BUTTON_WIDTH}, ${buttonSize}px)`;\n\t\tconst buttonGap = 4;\n\t\tconst editButtonBgColor = `var(${OverlayManager.CSS_VAR_EDIT_BUTTON_BG_COLOR}, #6644ff)`;\n\t\tconst aiButtonBgColor = `var(${OverlayManager.CSS_VAR_AI_BUTTON_BG_COLOR}, ${editButtonBgColor})`;\n\tLine truncated
+16
View File
@@ -0,0 +1,16 @@
MIT License
Copyright 2025 Monospace, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the “Software”), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+72
View File
@@ -0,0 +1,72 @@
{
"name": "@directus/visual-editing",
"version": "1.2.0",
"description": "Visual editing library to enable in-place editing of your website’s frontend from within the Visual Editor in Directus",
"homepage": "https://directus.io/docs/guides/content/visual-editor",
"repository": {
"type": "git",
"url": "https://github.com/directus/visual-editing.git"
},
"funding": "https://github.com/directus/directus?sponsor=1",
"license": "MIT",
"keywords": [
"visual-editing",
"visual-editor",
"content-editing-experience",
"in-place-editing",
"in-place-editor",
"frontend-editing",
"frontend-editor",
"content-editing",
"content-editor",
"live-editing",
"live-editor",
"directus",
"in-place",
"frontend",
"overlays",
"preview",
"editing",
"editor",
"iframe",
"cms"
],
"type": "module",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.cjs",
"default": "./dist/visual-editing.js"
},
"./package.json": "./package.json"
},
"main": "./dist/index.js",
"files": [
"dist"
],
"dependencies": {
"@reach/observe-rect": "1.2.0"
},
"devDependencies": {
"@directus/tsconfig": "3.0.0",
"@eslint/js": "9.39.2",
"eslint": "9.39.2",
"eslint-config-prettier": "10.1.8",
"eslint-plugin-vue": "10.7.0",
"globals": "17.3.0",
"prettier": "3.8.1",
"tsdown": "0.20.1",
"typescript": "5.9.3",
"typescript-eslint": "8.54.0",
"vitest": "4.0.18",
"vue-eslint-parser": "10.2.0"
},
"engines": {
"node": ">=22.12.0"
},
"scripts": {
"dev": "NODE_ENV=development tsdown",
"build": "NODE_ENV=production tsdown",
"test": "vitest --typecheck --watch=false"
}
}
+30
View File
@@ -0,0 +1,30 @@
# Visual Editing Frontend Library by Directus
This library works together with a Directus instance to enable Visual Editing functionality from within the Visual
Editor module in Directus Studio.
Web developers must make use of this library to ensure communication between their website’s HTML elements and their
Directus instance. This is done through data attributes and helper functions built into the library and imported into
your website.
## Documentation
Documentation covering the setup and functionality for both the frontend library and the studio module can be found in
the [Directus documentation](https://directus.io/docs/guides/content/visual-editor).
## Test Website
A test website pre-configured to work with the Directus Visual Editor module is included in the library’s repository.
This can be used for example purposes and to make it easy to set up an environment for testing or contributing.
For detailed instructions on setting up the test environment see the
[test website's readme.md](https://github.com/directus/visual-editing/blob/main/test-website/readme.md).
## License
This package is licensed under the MIT License. See the LICENSE file for more information.
## Additional Resources
- [Directus Website](https://directus.io)
- [Directus GitHub Repository](https://github.com/directus/directus)