@realiizlabs/admin 0.15.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bar/index.cjs +37 -8
- package/dist/bar/index.cjs.map +1 -1
- package/dist/bar/index.js +37 -8
- package/dist/bar/index.js.map +1 -1
- package/dist/studio/index.cjs +1 -1
- package/dist/studio/index.js +1 -1
- package/dist/studio-ui/index.cjs +1 -1
- package/dist/studio-ui/index.js +1 -1
- package/package.json +2 -2
package/dist/bar/index.cjs
CHANGED
|
@@ -20,26 +20,55 @@ function editHrefFor(pathname, routes, adminPath = "/admin") {
|
|
|
20
20
|
}
|
|
21
21
|
return null;
|
|
22
22
|
}
|
|
23
|
+
function usePathname() {
|
|
24
|
+
const [path, setPath] = react.useState("");
|
|
25
|
+
react.useEffect(() => {
|
|
26
|
+
const read = () => setPath(window.location.pathname);
|
|
27
|
+
read();
|
|
28
|
+
window.addEventListener("popstate", read);
|
|
29
|
+
const h = window.history;
|
|
30
|
+
if (!h.__rzWrapped) {
|
|
31
|
+
h.__rzWrapped = true;
|
|
32
|
+
for (const m of ["pushState", "replaceState"]) {
|
|
33
|
+
const orig = h[m].bind(h);
|
|
34
|
+
h[m] = ((...args) => {
|
|
35
|
+
orig(...args);
|
|
36
|
+
window.dispatchEvent(new Event("rz:navigate"));
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
window.addEventListener("rz:navigate", read);
|
|
41
|
+
return () => {
|
|
42
|
+
window.removeEventListener("popstate", read);
|
|
43
|
+
window.removeEventListener("rz:navigate", read);
|
|
44
|
+
};
|
|
45
|
+
}, []);
|
|
46
|
+
return path;
|
|
47
|
+
}
|
|
23
48
|
function StudioBar({ routes = {}, adminPath = "/admin", label = "Studio" }) {
|
|
24
|
-
const
|
|
49
|
+
const path = usePathname();
|
|
50
|
+
const [show, setShow] = react.useState(false);
|
|
25
51
|
react.useEffect(() => {
|
|
26
|
-
|
|
27
|
-
if (path === adminPath || path.startsWith(`${adminPath}/`))
|
|
52
|
+
if (!path) return;
|
|
53
|
+
if (path === adminPath || path.startsWith(`${adminPath}/`)) {
|
|
54
|
+
setShow(false);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
28
57
|
let hidden = false;
|
|
29
58
|
try {
|
|
30
59
|
hidden = sessionStorage.getItem(HIDE_KEY) === "1";
|
|
31
60
|
} catch {
|
|
32
61
|
}
|
|
33
|
-
|
|
34
|
-
}, [adminPath]);
|
|
35
|
-
if (!
|
|
36
|
-
const edit = editHrefFor(
|
|
62
|
+
setShow(!hidden && hasStudioMarker());
|
|
63
|
+
}, [path, adminPath]);
|
|
64
|
+
if (!show) return null;
|
|
65
|
+
const edit = editHrefFor(path, routes, adminPath);
|
|
37
66
|
const close = () => {
|
|
38
67
|
try {
|
|
39
68
|
sessionStorage.setItem(HIDE_KEY, "1");
|
|
40
69
|
} catch {
|
|
41
70
|
}
|
|
42
|
-
|
|
71
|
+
setShow(false);
|
|
43
72
|
};
|
|
44
73
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: S.wrap, role: "region", "aria-label": "Studio", "data-studio-bar": true, children: [
|
|
45
74
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: S.brand, children: [
|
package/dist/bar/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bar/StudioBar.tsx"],"names":["useState","useEffect","jsxs","jsx"],"mappings":";;;;;;AAIO,IAAM,oBAAA,GAAuB;AACpC,IAAM,QAAA,GAAW,eAAA;AAYV,SAAS,gBAAgB,MAAA,GAAiB,OAAO,aAAa,WAAA,GAAc,EAAA,GAAK,SAAS,MAAA,EAAiB;AAChH,EAAA,OAAO,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA,CAAE,KAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAK,CAAE,UAAA,CAAW,CAAA,EAAG,oBAAoB,IAAI,CAAC,CAAA;AACvF;AAGO,SAAS,WAAA,CAAY,QAAA,EAAkB,MAAA,EAAgC,SAAA,GAAY,QAAA,EAAyB;AACjH,EAAA,KAAA,MAAW,CAAC,MAAA,EAAQ,MAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACrD,IAAA,IAAI,CAAC,QAAA,CAAS,UAAA,CAAW,MAAM,CAAA,EAAG;AAClC,IAAA,MAAM,IAAA,GAAO,SAAS,KAAA,CAAM,MAAA,CAAO,MAAM,CAAA,CAAE,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAC7D,IAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG;AACjC,IAAA,IAAI,CAAC,4BAAA,CAA6B,IAAA,CAAK,IAAI,CAAA,EAAG;AAC9C,IAAA,OAAO,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,MAAM,IAAI,IAAI,CAAA,CAAA;AAAA,EACvC;AACA,EAAA,OAAO,IAAA;AACT;AAEO,SAAS,SAAA,CAAU,EAAE,MAAA,GAAS,IAAI,SAAA,GAAY,QAAA,EAAU,KAAA,GAAQ,QAAA,EAAS,EAAmB;AACjG,EAAA,MAAM,
|
|
1
|
+
{"version":3,"sources":["../../src/bar/StudioBar.tsx"],"names":["useState","useEffect","jsxs","jsx"],"mappings":"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","file":"index.cjs","sourcesContent":["\"use client\";\n\nimport { useEffect, useState, type CSSProperties } from \"react\";\n\nexport const STUDIO_MARKER_COOKIE = \"rz-studio\";\nconst HIDE_KEY = \"rz-bar-hidden\";\n\nexport interface StudioBarProps {\n /** Public URL prefix → content type id, e.g. { \"/blog/\": \"posts\", \"/events/\": \"events\" }. */\n routes?: Record<string, string>;\n /** Where Studio lives. Default \"/admin\". */\n adminPath?: string;\n /** Shown on the pill. Default \"Studio\". */\n label?: string;\n}\n\n/** True when Studio's marker cookie is present (someone signed in to Studio in this browser). */\nexport function hasStudioMarker(cookie: string = typeof document === \"undefined\" ? \"\" : document.cookie): boolean {\n return cookie.split(\";\").some((c) => c.trim().startsWith(`${STUDIO_MARKER_COOKIE}=1`));\n}\n\n/** The Studio edit page for a public path, or null when the path isn't an item Studio manages. */\nexport function editHrefFor(pathname: string, routes: Record<string, string>, adminPath = \"/admin\"): string | null {\n for (const [prefix, typeId] of Object.entries(routes)) {\n if (!pathname.startsWith(prefix)) continue;\n const rest = pathname.slice(prefix.length).replace(/\\/+$/, \"\");\n if (!rest || rest.includes(\"/\")) continue; // the index page, or something nested — not an item\n if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(rest)) continue;\n return `${adminPath}/${typeId}/${rest}`;\n }\n return null;\n}\n\n/** The current pathname, kept in step with client-side navigation (Next's router uses pushState). */\nfunction usePathname(): string {\n const [path, setPath] = useState(\"\");\n useEffect(() => {\n const read = () => setPath(window.location.pathname);\n read();\n window.addEventListener(\"popstate\", read);\n // pushState/replaceState fire no event; wrap them once per page so every router notifies us.\n const h = window.history as History & { __rzWrapped?: boolean };\n if (!h.__rzWrapped) {\n h.__rzWrapped = true;\n for (const m of [\"pushState\", \"replaceState\"] as const) {\n const orig = h[m].bind(h);\n h[m] = ((...args: Parameters<History[\"pushState\"]>) => { orig(...args); window.dispatchEvent(new Event(\"rz:navigate\")); }) as History[\"pushState\"];\n }\n }\n window.addEventListener(\"rz:navigate\", read);\n return () => { window.removeEventListener(\"popstate\", read); window.removeEventListener(\"rz:navigate\", read); };\n }, []);\n return path;\n}\n\nexport function StudioBar({ routes = {}, adminPath = \"/admin\", label = \"Studio\" }: StudioBarProps) {\n const path = usePathname();\n const [show, setShow] = useState(false);\n\n useEffect(() => {\n if (!path) return;\n if (path === adminPath || path.startsWith(`${adminPath}/`)) { setShow(false); return; }\n let hidden = false;\n try { hidden = sessionStorage.getItem(HIDE_KEY) === \"1\"; } catch { /* private mode */ }\n setShow(!hidden && hasStudioMarker());\n }, [path, adminPath]);\n\n if (!show) return null;\n const edit = editHrefFor(path, routes, adminPath);\n const close = () => { try { sessionStorage.setItem(HIDE_KEY, \"1\"); } catch { /* private mode */ } setShow(false); };\n\n return (\n <div style={S.wrap} role=\"region\" aria-label=\"Studio\" data-studio-bar>\n <span style={S.brand}>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.4\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 3l7 3v5c0 5-3.5 8.5-7 10-3.5-1.5-7-5-7-10V6z\" /></svg>\n {label}\n </span>\n {edit && <a href={edit} style={S.link}>Edit this page</a>}\n <a href={adminPath} style={S.link}>Dashboard</a>\n <button type=\"button\" onClick={close} style={S.close} aria-label=\"Hide the Studio bar for this tab\">×</button>\n </div>\n );\n}\n\n/* Self-contained styles: no dependency on the site's CSS, fonts or theme. */\nconst S: Record<string, CSSProperties> = {\n wrap: {\n position: \"fixed\", left: 16, bottom: 16, zIndex: 2147483000,\n display: \"flex\", alignItems: \"center\", gap: 2,\n padding: \"4px 6px 4px 10px\", borderRadius: 999,\n background: \"#0b1220\", color: \"#e5e7eb\", boxShadow: \"0 6px 24px rgba(0,0,0,.28)\",\n font: \"500 13px/1 system-ui, -apple-system, Segoe UI, Roboto, sans-serif\", letterSpacing: \".01em\",\n WebkitFontSmoothing: \"antialiased\",\n },\n brand: { display: \"inline-flex\", alignItems: \"center\", gap: 6, paddingRight: 8, marginRight: 4, borderRight: \"1px solid rgba(255,255,255,.18)\", color: \"#a5b4fc\", fontWeight: 600 },\n link: { color: \"#e5e7eb\", textDecoration: \"none\", padding: \"6px 8px\", borderRadius: 999 },\n close: { marginLeft: 2, width: 26, height: 26, border: 0, borderRadius: 999, background: \"transparent\", color: \"#9ca3af\", fontSize: 16, lineHeight: 1, cursor: \"pointer\" },\n};\n"]}
|
package/dist/bar/index.js
CHANGED
|
@@ -18,26 +18,55 @@ function editHrefFor(pathname, routes, adminPath = "/admin") {
|
|
|
18
18
|
}
|
|
19
19
|
return null;
|
|
20
20
|
}
|
|
21
|
+
function usePathname() {
|
|
22
|
+
const [path, setPath] = useState("");
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const read = () => setPath(window.location.pathname);
|
|
25
|
+
read();
|
|
26
|
+
window.addEventListener("popstate", read);
|
|
27
|
+
const h = window.history;
|
|
28
|
+
if (!h.__rzWrapped) {
|
|
29
|
+
h.__rzWrapped = true;
|
|
30
|
+
for (const m of ["pushState", "replaceState"]) {
|
|
31
|
+
const orig = h[m].bind(h);
|
|
32
|
+
h[m] = ((...args) => {
|
|
33
|
+
orig(...args);
|
|
34
|
+
window.dispatchEvent(new Event("rz:navigate"));
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
window.addEventListener("rz:navigate", read);
|
|
39
|
+
return () => {
|
|
40
|
+
window.removeEventListener("popstate", read);
|
|
41
|
+
window.removeEventListener("rz:navigate", read);
|
|
42
|
+
};
|
|
43
|
+
}, []);
|
|
44
|
+
return path;
|
|
45
|
+
}
|
|
21
46
|
function StudioBar({ routes = {}, adminPath = "/admin", label = "Studio" }) {
|
|
22
|
-
const
|
|
47
|
+
const path = usePathname();
|
|
48
|
+
const [show, setShow] = useState(false);
|
|
23
49
|
useEffect(() => {
|
|
24
|
-
|
|
25
|
-
if (path === adminPath || path.startsWith(`${adminPath}/`))
|
|
50
|
+
if (!path) return;
|
|
51
|
+
if (path === adminPath || path.startsWith(`${adminPath}/`)) {
|
|
52
|
+
setShow(false);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
26
55
|
let hidden = false;
|
|
27
56
|
try {
|
|
28
57
|
hidden = sessionStorage.getItem(HIDE_KEY) === "1";
|
|
29
58
|
} catch {
|
|
30
59
|
}
|
|
31
|
-
|
|
32
|
-
}, [adminPath]);
|
|
33
|
-
if (!
|
|
34
|
-
const edit = editHrefFor(
|
|
60
|
+
setShow(!hidden && hasStudioMarker());
|
|
61
|
+
}, [path, adminPath]);
|
|
62
|
+
if (!show) return null;
|
|
63
|
+
const edit = editHrefFor(path, routes, adminPath);
|
|
35
64
|
const close = () => {
|
|
36
65
|
try {
|
|
37
66
|
sessionStorage.setItem(HIDE_KEY, "1");
|
|
38
67
|
} catch {
|
|
39
68
|
}
|
|
40
|
-
|
|
69
|
+
setShow(false);
|
|
41
70
|
};
|
|
42
71
|
return /* @__PURE__ */ jsxs("div", { style: S.wrap, role: "region", "aria-label": "Studio", "data-studio-bar": true, children: [
|
|
43
72
|
/* @__PURE__ */ jsxs("span", { style: S.brand, children: [
|
package/dist/bar/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bar/StudioBar.tsx"],"names":[],"mappings":";;;;AAIO,IAAM,oBAAA,GAAuB;AACpC,IAAM,QAAA,GAAW,eAAA;AAYV,SAAS,gBAAgB,MAAA,GAAiB,OAAO,aAAa,WAAA,GAAc,EAAA,GAAK,SAAS,MAAA,EAAiB;AAChH,EAAA,OAAO,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA,CAAE,KAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAK,CAAE,UAAA,CAAW,CAAA,EAAG,oBAAoB,IAAI,CAAC,CAAA;AACvF;AAGO,SAAS,WAAA,CAAY,QAAA,EAAkB,MAAA,EAAgC,SAAA,GAAY,QAAA,EAAyB;AACjH,EAAA,KAAA,MAAW,CAAC,MAAA,EAAQ,MAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACrD,IAAA,IAAI,CAAC,QAAA,CAAS,UAAA,CAAW,MAAM,CAAA,EAAG;AAClC,IAAA,MAAM,IAAA,GAAO,SAAS,KAAA,CAAM,MAAA,CAAO,MAAM,CAAA,CAAE,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAC7D,IAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG;AACjC,IAAA,IAAI,CAAC,4BAAA,CAA6B,IAAA,CAAK,IAAI,CAAA,EAAG;AAC9C,IAAA,OAAO,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,MAAM,IAAI,IAAI,CAAA,CAAA;AAAA,EACvC;AACA,EAAA,OAAO,IAAA;AACT;AAEO,SAAS,SAAA,CAAU,EAAE,MAAA,GAAS,IAAI,SAAA,GAAY,QAAA,EAAU,KAAA,GAAQ,QAAA,EAAS,EAAmB;AACjG,EAAA,MAAM,
|
|
1
|
+
{"version":3,"sources":["../../src/bar/StudioBar.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["\"use client\";\n\nimport { useEffect, useState, type CSSProperties } from \"react\";\n\nexport const STUDIO_MARKER_COOKIE = \"rz-studio\";\nconst HIDE_KEY = \"rz-bar-hidden\";\n\nexport interface StudioBarProps {\n /** Public URL prefix → content type id, e.g. { \"/blog/\": \"posts\", \"/events/\": \"events\" }. */\n routes?: Record<string, string>;\n /** Where Studio lives. Default \"/admin\". */\n adminPath?: string;\n /** Shown on the pill. Default \"Studio\". */\n label?: string;\n}\n\n/** True when Studio's marker cookie is present (someone signed in to Studio in this browser). */\nexport function hasStudioMarker(cookie: string = typeof document === \"undefined\" ? \"\" : document.cookie): boolean {\n return cookie.split(\";\").some((c) => c.trim().startsWith(`${STUDIO_MARKER_COOKIE}=1`));\n}\n\n/** The Studio edit page for a public path, or null when the path isn't an item Studio manages. */\nexport function editHrefFor(pathname: string, routes: Record<string, string>, adminPath = \"/admin\"): string | null {\n for (const [prefix, typeId] of Object.entries(routes)) {\n if (!pathname.startsWith(prefix)) continue;\n const rest = pathname.slice(prefix.length).replace(/\\/+$/, \"\");\n if (!rest || rest.includes(\"/\")) continue; // the index page, or something nested — not an item\n if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(rest)) continue;\n return `${adminPath}/${typeId}/${rest}`;\n }\n return null;\n}\n\n/** The current pathname, kept in step with client-side navigation (Next's router uses pushState). */\nfunction usePathname(): string {\n const [path, setPath] = useState(\"\");\n useEffect(() => {\n const read = () => setPath(window.location.pathname);\n read();\n window.addEventListener(\"popstate\", read);\n // pushState/replaceState fire no event; wrap them once per page so every router notifies us.\n const h = window.history as History & { __rzWrapped?: boolean };\n if (!h.__rzWrapped) {\n h.__rzWrapped = true;\n for (const m of [\"pushState\", \"replaceState\"] as const) {\n const orig = h[m].bind(h);\n h[m] = ((...args: Parameters<History[\"pushState\"]>) => { orig(...args); window.dispatchEvent(new Event(\"rz:navigate\")); }) as History[\"pushState\"];\n }\n }\n window.addEventListener(\"rz:navigate\", read);\n return () => { window.removeEventListener(\"popstate\", read); window.removeEventListener(\"rz:navigate\", read); };\n }, []);\n return path;\n}\n\nexport function StudioBar({ routes = {}, adminPath = \"/admin\", label = \"Studio\" }: StudioBarProps) {\n const path = usePathname();\n const [show, setShow] = useState(false);\n\n useEffect(() => {\n if (!path) return;\n if (path === adminPath || path.startsWith(`${adminPath}/`)) { setShow(false); return; }\n let hidden = false;\n try { hidden = sessionStorage.getItem(HIDE_KEY) === \"1\"; } catch { /* private mode */ }\n setShow(!hidden && hasStudioMarker());\n }, [path, adminPath]);\n\n if (!show) return null;\n const edit = editHrefFor(path, routes, adminPath);\n const close = () => { try { sessionStorage.setItem(HIDE_KEY, \"1\"); } catch { /* private mode */ } setShow(false); };\n\n return (\n <div style={S.wrap} role=\"region\" aria-label=\"Studio\" data-studio-bar>\n <span style={S.brand}>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.4\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 3l7 3v5c0 5-3.5 8.5-7 10-3.5-1.5-7-5-7-10V6z\" /></svg>\n {label}\n </span>\n {edit && <a href={edit} style={S.link}>Edit this page</a>}\n <a href={adminPath} style={S.link}>Dashboard</a>\n <button type=\"button\" onClick={close} style={S.close} aria-label=\"Hide the Studio bar for this tab\">×</button>\n </div>\n );\n}\n\n/* Self-contained styles: no dependency on the site's CSS, fonts or theme. */\nconst S: Record<string, CSSProperties> = {\n wrap: {\n position: \"fixed\", left: 16, bottom: 16, zIndex: 2147483000,\n display: \"flex\", alignItems: \"center\", gap: 2,\n padding: \"4px 6px 4px 10px\", borderRadius: 999,\n background: \"#0b1220\", color: \"#e5e7eb\", boxShadow: \"0 6px 24px rgba(0,0,0,.28)\",\n font: \"500 13px/1 system-ui, -apple-system, Segoe UI, Roboto, sans-serif\", letterSpacing: \".01em\",\n WebkitFontSmoothing: \"antialiased\",\n },\n brand: { display: \"inline-flex\", alignItems: \"center\", gap: 6, paddingRight: 8, marginRight: 4, borderRight: \"1px solid rgba(255,255,255,.18)\", color: \"#a5b4fc\", fontWeight: 600 },\n link: { color: \"#e5e7eb\", textDecoration: \"none\", padding: \"6px 8px\", borderRadius: 999 },\n close: { marginLeft: 2, width: 26, height: 26, border: 0, borderRadius: 999, background: \"transparent\", color: \"#9ca3af\", fontSize: 16, lineHeight: 1, cursor: \"pointer\" },\n};\n"]}
|
package/dist/studio/index.cjs
CHANGED
package/dist/studio/index.js
CHANGED
package/dist/studio-ui/index.cjs
CHANGED
package/dist/studio-ui/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@realiizlabs/admin",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "Realiiz Studio — the publishing dashboard for websites built on site-starter-pro.",
|
|
5
|
-
"releaseNotes": "
|
|
5
|
+
"releaseNotes": "The Studio pill now follows you as you move around the site: Edit this page appears the moment you open a post or event and steps aside on other pages, no reload needed.",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "./dist/index.cjs",
|