UNPKG

tinacms

Version:

> The Fastest Way to Edit Next.js Content

238 lines (237 loc) • 7.92 kB
(function(global, factory) { typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("react")) : typeof define === "function" && define.amd ? define(["exports", "react"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.tinacms = {}, global.NOOP)); })(this, function(exports2, React) { "use strict"; function useTina(props) { const stringifiedQuery = JSON.stringify({ query: props.query, variables: props.variables }); const id = React.useMemo( () => hashFromQuery(stringifiedQuery), [stringifiedQuery] ); const [data, setData] = React.useState(props.data); const [isClient, setIsClient] = React.useState(false); const [quickEditEnabled, setQuickEditEnabled] = React.useState(false); const [isInTinaIframe, setIsInTinaIframe] = React.useState(false); React.useEffect(() => { setIsClient(true); setData(props.data); }, [id]); React.useEffect(() => { if (quickEditEnabled) { let mouseDownHandler = function(e) { const attributeNames = e.target.getAttributeNames(); const tinaAttribute = attributeNames.find( (name) => name.startsWith("data-tina-field") ); let fieldName; if (tinaAttribute) { e.preventDefault(); e.stopPropagation(); fieldName = e.target.getAttribute(tinaAttribute); } else { const ancestor = e.target.closest( "[data-tina-field], [data-tina-field-overlay]" ); if (ancestor) { const attributeNames2 = ancestor.getAttributeNames(); const tinaAttribute2 = attributeNames2.find( (name) => name.startsWith("data-tina-field") ); if (tinaAttribute2) { e.preventDefault(); e.stopPropagation(); fieldName = ancestor.getAttribute(tinaAttribute2); } } } if (fieldName) { if (isInTinaIframe) { parent.postMessage( { type: "field:selected", fieldName }, window.location.origin ); } } }; const style = document.createElement("style"); style.type = "text/css"; style.textContent = ` [data-tina-field] { outline: 2px dashed rgba(34,150,254,0.5); transition: box-shadow ease-out 150ms; } [data-tina-field]:hover { box-shadow: inset 100vi 100vh rgba(34,150,254,0.3); outline: 2px solid rgba(34,150,254,1); cursor: pointer; } [data-tina-field-overlay] { outline: 2px dashed rgba(34,150,254,0.5); position: relative; } [data-tina-field-overlay]:hover { cursor: pointer; outline: 2px solid rgba(34,150,254,1); } [data-tina-field-overlay]::after { content: ''; position: absolute; inset: 0; z-index: 20; transition: opacity ease-out 150ms; background-color: rgba(34,150,254,0.3); opacity: 0; } [data-tina-field-overlay]:hover::after { opacity: 1; } `; document.head.appendChild(style); document.body.classList.add("__tina-quick-editing-enabled"); document.addEventListener("click", mouseDownHandler, true); return () => { document.removeEventListener("click", mouseDownHandler, true); document.body.classList.remove("__tina-quick-editing-enabled"); style.remove(); }; } }, [quickEditEnabled, isInTinaIframe]); React.useEffect(() => { parent.postMessage({ type: "open", ...props, id }, window.location.origin); window.addEventListener("message", (event) => { if (event.data.type === "quickEditEnabled") { setQuickEditEnabled(event.data.value); } if (event.data.id === id && event.data.type === "updateData") { setData(event.data.data); setIsInTinaIframe(true); const anyTinaField = document.querySelector("[data-tina-field]"); if (anyTinaField) { parent.postMessage( { type: "quick-edit", value: true }, window.location.origin ); } else { parent.postMessage( { type: "quick-edit", value: false }, window.location.origin ); } } }); return () => { parent.postMessage({ type: "close", id }, window.location.origin); }; }, [id, setQuickEditEnabled]); return { data, isClient }; } function useEditState() { const [edit, setEdit] = React.useState(false); React.useEffect(() => { if (typeof window !== "undefined") { parent.postMessage({ type: "isEditMode" }, window.location.origin); window.addEventListener("message", (event) => { var _a; if (((_a = event.data) == null ? void 0 : _a.type) === "tina:editMode") { setEdit(true); } }); } }, []); return { edit }; } const tinaField = (object, property, index) => { var _a, _b, _c; if (!object) { return ""; } if (object._content_source) { if (!property) { return [ (_a = object._content_source) == null ? void 0 : _a.queryId, object._content_source.path.join(".") ].join("---"); } if (typeof index === "number") { return [ (_b = object._content_source) == null ? void 0 : _b.queryId, [...object._content_source.path, property, index].join(".") ].join("---"); } return [ (_c = object._content_source) == null ? void 0 : _c.queryId, [...object._content_source.path, property].join(".") ].join("---"); } return ""; }; const addMetadata = (id, object, path) => { Object.entries(object).forEach(([key, value]) => { if (Array.isArray(value)) { value.forEach((item, index) => { if (isScalarOrUndefined(item)) { return; } if (Array.isArray(item)) { return; } const itemObject = item; addMetadata(id, itemObject, [...path, key, index]); }); } else { if (isScalarOrUndefined(value)) { return; } const itemObject = value; addMetadata(id, itemObject, [...path, key]); } }); if ((object == null ? void 0 : object.type) === "root") { return; } object._content_source = { queryId: id, path }; return object; }; function isScalarOrUndefined(value) { const type = typeof value; if (type === "string") return true; if (type === "number") return true; if (type === "boolean") return true; if (type === "undefined") return true; if (value == null) return true; if (value instanceof String) return true; if (value instanceof Number) return true; if (value instanceof Boolean) return true; return false; } const hashFromQuery = (input) => { let hash = 0; for (let i = 0; i < input.length; i++) { const char = input.charCodeAt(i); hash = (hash << 5) - hash + char & 4294967295; } const nonNegativeHash = Math.abs(hash); const alphanumericHash = nonNegativeHash.toString(36); return alphanumericHash; }; exports2.addMetadata = addMetadata; exports2.hashFromQuery = hashFromQuery; exports2.tinaField = tinaField; exports2.useEditState = useEditState; exports2.useTina = useTina; Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" }); });