@sudajs/cli 0.18.10 → 0.18.11
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/index.d.ts +5 -1
- package/dist/index.js +168 -27
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1816,7 +1816,9 @@ declare const __testUtils: {
|
|
|
1816
1816
|
performUpdateThemeSettings: typeof performUpdateThemeSettings;
|
|
1817
1817
|
getRemoteThemeSettings: typeof getRemoteThemeSettings;
|
|
1818
1818
|
renderDevStarterPageHtml: typeof renderDevStarterPageHtml;
|
|
1819
|
+
renderDevEditorPageHtml: typeof renderDevEditorPageHtml;
|
|
1819
1820
|
writeVitePreviewEntries: typeof writeVitePreviewEntries;
|
|
1821
|
+
resolveDevEditorSlug: typeof resolveDevEditorSlug;
|
|
1820
1822
|
resolveDevStarterSlug: typeof resolveDevStarterSlug;
|
|
1821
1823
|
resolveScreenshotOptions: typeof resolveScreenshotOptions;
|
|
1822
1824
|
slugifyThemeName: typeof slugifyThemeName;
|
|
@@ -1834,6 +1836,7 @@ declare const __testUtils: {
|
|
|
1834
1836
|
declare function watchTheme(root: string, port: number): Promise<void>;
|
|
1835
1837
|
declare function writeVitePreviewEntries(root: string): Promise<void>;
|
|
1836
1838
|
declare function withSerializedVitePreviewLocaleLoad<Result>(server: object, load: () => Promise<Result>): Promise<Result>;
|
|
1839
|
+
declare function resolveDevEditorSlug(pathname: string): string | null | undefined;
|
|
1837
1840
|
declare function resolveDevStarterSlug(pathname: string): string | null | undefined;
|
|
1838
1841
|
declare function resolveThemePreviewLocale(params: {
|
|
1839
1842
|
previewLocales: string[] | undefined;
|
|
@@ -1858,7 +1861,8 @@ interface ThemeRenderer {
|
|
|
1858
1861
|
renderToString: typeof renderToString;
|
|
1859
1862
|
}
|
|
1860
1863
|
declare function loadThemeScopedRenderer(themeRoot: string): Promise<ThemeRenderer>;
|
|
1861
|
-
declare function renderDevStarterPageHtml(theme: ValidatedTheme, page: ThemeStarterPage, renderer: ThemeRenderer, locale?: string, preserveLang?: boolean, previewLocaleMessages?: ThemePreviewLocaleMessages): string;
|
|
1864
|
+
declare function renderDevStarterPageHtml(theme: ValidatedTheme, page: ThemeStarterPage, renderer: ThemeRenderer, locale?: string, preserveLang?: boolean, previewLocaleMessages?: ThemePreviewLocaleMessages, searchParams?: URLSearchParams): string;
|
|
1865
|
+
declare function renderDevEditorPageHtml(theme: ValidatedTheme, page: ThemeStarterPage, renderer: ThemeRenderer, locale?: string, searchParams?: URLSearchParams, previewLocaleMessages?: ThemePreviewLocaleMessages): string;
|
|
1862
1866
|
interface ScreenshotOptions extends ThemeRootOptions {
|
|
1863
1867
|
device?: string[] | string;
|
|
1864
1868
|
output?: string;
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { themeDesignSystemSchema, createThemeDesignCssVariables, createThemeAgen
|
|
|
12
12
|
import { themeManifestSchema, runWithThemePreviewLocale } from '@sudajs/theme-engine/server';
|
|
13
13
|
import { Command } from 'commander';
|
|
14
14
|
import { build } from 'esbuild';
|
|
15
|
-
import { CircleCheck } from 'lucide-react';
|
|
15
|
+
import { CircleCheck, Pencil } from 'lucide-react';
|
|
16
16
|
import { createElement } from 'react';
|
|
17
17
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
18
18
|
import { z } from 'zod';
|
|
@@ -1738,7 +1738,9 @@ var __testUtils = {
|
|
|
1738
1738
|
performUpdateThemeSettings,
|
|
1739
1739
|
getRemoteThemeSettings,
|
|
1740
1740
|
renderDevStarterPageHtml,
|
|
1741
|
+
renderDevEditorPageHtml,
|
|
1741
1742
|
writeVitePreviewEntries,
|
|
1743
|
+
resolveDevEditorSlug,
|
|
1742
1744
|
resolveDevStarterSlug,
|
|
1743
1745
|
resolveScreenshotOptions,
|
|
1744
1746
|
slugifyThemeName,
|
|
@@ -1819,7 +1821,7 @@ async function startViteDevPreviewServer(root, port) {
|
|
|
1819
1821
|
cacheDir: path2.join(root, ".suda-build", "node_modules", ".vite"),
|
|
1820
1822
|
appType: "custom",
|
|
1821
1823
|
optimizeDeps: {
|
|
1822
|
-
entries: [".suda-build/preview-client.ts"]
|
|
1824
|
+
entries: [".suda-build/preview-client.ts", ".suda-build/editor-client.ts"]
|
|
1823
1825
|
},
|
|
1824
1826
|
server: { host, port },
|
|
1825
1827
|
plugins: [createSudaPreviewVitePlugin(root)]
|
|
@@ -1858,6 +1860,28 @@ async function writeVitePreviewEntries(root) {
|
|
|
1858
1860
|
].join("\n"),
|
|
1859
1861
|
"utf8"
|
|
1860
1862
|
);
|
|
1863
|
+
await writeFile(
|
|
1864
|
+
path2.join(buildDir, "editor-client.ts"),
|
|
1865
|
+
[
|
|
1866
|
+
'import "@puckeditor/core/puck.css";',
|
|
1867
|
+
'import { composeUnifiedThemeEditorData, createUnifiedThemeEditorConfig, installThemePreviewLocale, resolveAssetPath, ThemeEditor } from "@sudajs/theme-engine";',
|
|
1868
|
+
'import { createElement } from "react";',
|
|
1869
|
+
'import { createRoot } from "react-dom/client";',
|
|
1870
|
+
'import runtime from "./runtime.dev";',
|
|
1871
|
+
'const payloadElement=document.querySelector("#suda-theme-editor-data");',
|
|
1872
|
+
'if(!payloadElement){throw new Error("Missing Suda theme editor payload.")}',
|
|
1873
|
+
"const payload=JSON.parse(payloadElement.textContent ?? '{}');",
|
|
1874
|
+
"if(payload.previewLocaleMessages){installThemePreviewLocale(payload.previewLocaleMessages)}",
|
|
1875
|
+
'const resolveAssetUrl=(value: string | undefined)=>resolveAssetPath(value,{legacyResolve:(key)=>key.startsWith("themes/")?`/api/themes/${key.slice("themes/".length)}`:undefined});',
|
|
1876
|
+
'const config=createUnifiedThemeEditorConfig(runtime.theme,undefined,{labels:{pageContent:"Page content",themeSettings:"Theme settings"}});',
|
|
1877
|
+
"const data=composeUnifiedThemeEditorData(payload.layoutData,payload.pageData,{layoutConfig:runtime.theme.layoutConfig,pageConfig:runtime.theme.pageConfig});",
|
|
1878
|
+
'const editorContext={assets:[],resolveAssetUrl,currentPageId:payload.currentPageId,backHref:payload.backHref,editorPages:payload.editorPages,editorLocale:payload.locale,chromeMessages:{backToPages:"Back to preview",pageMenuLabel:"Switch starter page",themeSettings:"Theme settings",outline:"Outline",blocks:"Blocks",switchViewport:"Switch viewport"}};',
|
|
1879
|
+
"const metadata={contactForm:payload.contactForm,isEditor:true,resolveAssetUrl};",
|
|
1880
|
+
'createRoot(document.querySelector("#suda-theme-dev-editor-root")!).render(createElement(ThemeEditor,{config,data,editorContext,metadata,iframe:false,height:"100%",publishActionVisible:false}));',
|
|
1881
|
+
""
|
|
1882
|
+
].join("\n"),
|
|
1883
|
+
"utf8"
|
|
1884
|
+
);
|
|
1861
1885
|
}
|
|
1862
1886
|
function createClientRuntimeSource(clientHooksImport, useClientDirective) {
|
|
1863
1887
|
return [
|
|
@@ -1894,11 +1918,14 @@ function createSudaPreviewVitePlugin(root) {
|
|
|
1894
1918
|
next();
|
|
1895
1919
|
return;
|
|
1896
1920
|
}
|
|
1897
|
-
const
|
|
1898
|
-
|
|
1921
|
+
const editorSlug = resolveDevEditorSlug(url.pathname);
|
|
1922
|
+
const previewSlug = resolveDevStarterSlug(url.pathname);
|
|
1923
|
+
if (editorSlug === void 0 && previewSlug === void 0) {
|
|
1899
1924
|
next();
|
|
1900
1925
|
return;
|
|
1901
1926
|
}
|
|
1927
|
+
const isEditor = editorSlug !== void 0;
|
|
1928
|
+
const slug = isEditor ? editorSlug : previewSlug;
|
|
1902
1929
|
try {
|
|
1903
1930
|
const acceptLanguageHeader = request.headers["accept-language"];
|
|
1904
1931
|
const acceptLanguage = Array.isArray(acceptLanguageHeader) ? acceptLanguageHeader.join(",") : acceptLanguageHeader;
|
|
@@ -1919,17 +1946,23 @@ function createSudaPreviewVitePlugin(root) {
|
|
|
1919
1946
|
);
|
|
1920
1947
|
return;
|
|
1921
1948
|
}
|
|
1922
|
-
const
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1949
|
+
const htmlSource = isEditor ? renderDevEditorPageHtml(
|
|
1950
|
+
localized.theme,
|
|
1951
|
+
starter,
|
|
1952
|
+
renderer,
|
|
1953
|
+
localized.locale,
|
|
1954
|
+
url.searchParams,
|
|
1955
|
+
localized.previewLocaleMessages
|
|
1956
|
+
) : renderDevStarterPageHtml(
|
|
1957
|
+
localized.theme,
|
|
1958
|
+
starter,
|
|
1959
|
+
renderer,
|
|
1960
|
+
localized.locale,
|
|
1961
|
+
canonicalLocale(explicitLang) !== null,
|
|
1962
|
+
localized.previewLocaleMessages,
|
|
1963
|
+
url.searchParams
|
|
1932
1964
|
);
|
|
1965
|
+
const html = await server.transformIndexHtml(url.pathname, htmlSource);
|
|
1933
1966
|
response.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
1934
1967
|
response.end(html);
|
|
1935
1968
|
} catch (error2) {
|
|
@@ -2009,6 +2042,20 @@ function pickStarterSlug(theme) {
|
|
|
2009
2042
|
function findStarterPage(theme, slug) {
|
|
2010
2043
|
return theme.module.starterPages.find((page) => page.slug === slug) ?? null;
|
|
2011
2044
|
}
|
|
2045
|
+
var DEV_EDITOR_PATH = "/__suda/editor";
|
|
2046
|
+
function resolveDevEditorSlug(pathname) {
|
|
2047
|
+
if (pathname === DEV_EDITOR_PATH || pathname === `${DEV_EDITOR_PATH}/`) {
|
|
2048
|
+
return null;
|
|
2049
|
+
}
|
|
2050
|
+
if (!pathname.startsWith(`${DEV_EDITOR_PATH}/`)) {
|
|
2051
|
+
return void 0;
|
|
2052
|
+
}
|
|
2053
|
+
const normalized = pathname.slice(DEV_EDITOR_PATH.length + 1).replace(/\/+$/, "");
|
|
2054
|
+
if (!normalized || normalized.includes("/")) {
|
|
2055
|
+
return void 0;
|
|
2056
|
+
}
|
|
2057
|
+
return decodeURIComponent(normalized);
|
|
2058
|
+
}
|
|
2012
2059
|
function resolveDevStarterSlug(pathname) {
|
|
2013
2060
|
if (pathname === "/") {
|
|
2014
2061
|
return null;
|
|
@@ -2122,8 +2169,9 @@ async function loadThemeScopedRenderer(themeRoot) {
|
|
|
2122
2169
|
renderToString: reactDomServerModule.renderToString
|
|
2123
2170
|
};
|
|
2124
2171
|
}
|
|
2125
|
-
function renderDevStarterPageHtml(theme, page, renderer, locale = "en", preserveLang = false, previewLocaleMessages) {
|
|
2126
|
-
const
|
|
2172
|
+
function renderDevStarterPageHtml(theme, page, renderer, locale = "en", preserveLang = false, previewLocaleMessages, searchParams = new URLSearchParams()) {
|
|
2173
|
+
const layoutData = createDevPreviewLayout(theme, searchParams);
|
|
2174
|
+
const chrome = renderer.extractLayoutChrome(layoutData);
|
|
2127
2175
|
const metadata = {
|
|
2128
2176
|
resolveAssetUrl: createPreviewAssetResolver(renderer.resolveAssetPath),
|
|
2129
2177
|
contactForm: PREVIEW_CONTACT_FORM
|
|
@@ -2132,17 +2180,20 @@ function renderDevStarterPageHtml(theme, page, renderer, locale = "en", preserve
|
|
|
2132
2180
|
renderer.createElement(renderer.ThemeRender, {
|
|
2133
2181
|
theme: theme.module,
|
|
2134
2182
|
pageData: page.data,
|
|
2135
|
-
layoutData
|
|
2183
|
+
layoutData,
|
|
2136
2184
|
metadata
|
|
2137
2185
|
})
|
|
2138
2186
|
);
|
|
2139
2187
|
const cssVarStyle = Object.entries(chrome.cssVariables).map(([key, value]) => `${key}: ${value};`).join(" ");
|
|
2140
2188
|
const customHead = chrome.customHeadCode ?? "";
|
|
2141
2189
|
const customBody = chrome.customBodyCode ?? "";
|
|
2142
|
-
const designPalette = renderDevDesignPalette(
|
|
2190
|
+
const designPalette = renderDevDesignPalette(
|
|
2191
|
+
theme.module.manifest.designSystem,
|
|
2192
|
+
createDevEditorHref(page.slug, searchParams)
|
|
2193
|
+
);
|
|
2143
2194
|
const hydrationPayload = serializeInlineScriptValue({
|
|
2144
2195
|
pageData: page.data,
|
|
2145
|
-
layoutData
|
|
2196
|
+
layoutData,
|
|
2146
2197
|
contactForm: PREVIEW_CONTACT_FORM,
|
|
2147
2198
|
previewLocaleMessages
|
|
2148
2199
|
});
|
|
@@ -2173,13 +2224,95 @@ function renderDevStarterPageHtml(theme, page, renderer, locale = "en", preserve
|
|
|
2173
2224
|
"</html>"
|
|
2174
2225
|
].join("");
|
|
2175
2226
|
}
|
|
2227
|
+
function copyDevPreviewSearchParams(searchParams) {
|
|
2228
|
+
const copied = new URLSearchParams();
|
|
2229
|
+
for (const key of ["lang", "designPreset"]) {
|
|
2230
|
+
const value = searchParams.get(key);
|
|
2231
|
+
if (value) {
|
|
2232
|
+
copied.set(key, value);
|
|
2233
|
+
}
|
|
2234
|
+
}
|
|
2235
|
+
return copied;
|
|
2236
|
+
}
|
|
2237
|
+
function createDevEditorHref(slug, searchParams) {
|
|
2238
|
+
const query = copyDevPreviewSearchParams(searchParams).toString();
|
|
2239
|
+
return `${DEV_EDITOR_PATH}/${encodeURIComponent(slug)}${query ? `?${query}` : ""}`;
|
|
2240
|
+
}
|
|
2241
|
+
function createDevPreviewHref(page, searchParams) {
|
|
2242
|
+
const pathname = page.isHome ? "/" : `/${encodeURIComponent(page.slug)}`;
|
|
2243
|
+
const query = copyDevPreviewSearchParams(searchParams).toString();
|
|
2244
|
+
return `${pathname}${query ? `?${query}` : ""}`;
|
|
2245
|
+
}
|
|
2246
|
+
function createDevPreviewLayout(theme, searchParams) {
|
|
2247
|
+
const requestedPresetId = searchParams.get("designPreset");
|
|
2248
|
+
const requestedPreset = requestedPresetId ? theme.module.manifest.designSystem.presets.find(
|
|
2249
|
+
(preset) => preset.id === requestedPresetId
|
|
2250
|
+
) : void 0;
|
|
2251
|
+
if (!requestedPreset) {
|
|
2252
|
+
return theme.module.defaultLayout;
|
|
2253
|
+
}
|
|
2254
|
+
const rootFields = theme.module.layoutConfig.root?.fields ?? {};
|
|
2255
|
+
const designFieldName = Object.entries(rootFields).find(
|
|
2256
|
+
([, field]) => field.metadata?.sudaField === "designSystem"
|
|
2257
|
+
)?.[0];
|
|
2258
|
+
if (!designFieldName) {
|
|
2259
|
+
return theme.module.defaultLayout;
|
|
2260
|
+
}
|
|
2261
|
+
const layoutData = structuredClone(theme.module.defaultLayout);
|
|
2262
|
+
layoutData.root = {
|
|
2263
|
+
...layoutData.root ?? {},
|
|
2264
|
+
props: {
|
|
2265
|
+
...layoutData.root?.props ?? {},
|
|
2266
|
+
[designFieldName]: { presetId: requestedPreset.id }
|
|
2267
|
+
}
|
|
2268
|
+
};
|
|
2269
|
+
return layoutData;
|
|
2270
|
+
}
|
|
2271
|
+
function renderDevEditorPageHtml(theme, page, renderer, locale = "en", searchParams = new URLSearchParams(), previewLocaleMessages) {
|
|
2272
|
+
const layoutData = createDevPreviewLayout(theme, searchParams);
|
|
2273
|
+
const chrome = renderer.extractLayoutChrome(layoutData);
|
|
2274
|
+
const cssVariables = { ...chrome.cssVariables };
|
|
2275
|
+
const cssVarStyle = Object.entries(cssVariables).map(([key, value]) => `${key}: ${value};`).join(" ");
|
|
2276
|
+
const editorPages = theme.module.starterPages.map((starterPage) => ({
|
|
2277
|
+
id: starterPage.slug,
|
|
2278
|
+
handle: starterPage.slug,
|
|
2279
|
+
label: starterPage.title,
|
|
2280
|
+
group: starterPage.isHome ? "home" : "static",
|
|
2281
|
+
editorHref: createDevEditorHref(starterPage.slug, searchParams)
|
|
2282
|
+
}));
|
|
2283
|
+
const payload = serializeInlineScriptValue({
|
|
2284
|
+
pageData: page.data,
|
|
2285
|
+
layoutData,
|
|
2286
|
+
contactForm: PREVIEW_CONTACT_FORM,
|
|
2287
|
+
previewLocaleMessages,
|
|
2288
|
+
locale,
|
|
2289
|
+
currentPageId: page.slug,
|
|
2290
|
+
backHref: createDevPreviewHref(page, searchParams),
|
|
2291
|
+
editorPages
|
|
2292
|
+
});
|
|
2293
|
+
return [
|
|
2294
|
+
"<!doctype html>",
|
|
2295
|
+
`<html lang="${escapeHtml(locale)}">`,
|
|
2296
|
+
"<head>",
|
|
2297
|
+
'<meta charset="utf-8" />',
|
|
2298
|
+
'<meta name="viewport" content="width=device-width, initial-scale=1" />',
|
|
2299
|
+
`<title>${escapeHtml(`Edit ${theme.module.manifest.name} \u2014 ${page.title}`)}</title>`,
|
|
2300
|
+
'<link rel="stylesheet" href="/src/styles.css" />',
|
|
2301
|
+
"<style>html,body,#suda-theme-dev-editor-root{height:100%;margin:0}body{overflow:hidden}</style>",
|
|
2302
|
+
"</head>",
|
|
2303
|
+
`<body${cssVarStyle ? ` style="${cssVarStyle}"` : ""}>`,
|
|
2304
|
+
'<div id="suda-theme-dev-editor-root"></div>',
|
|
2305
|
+
`<script id="suda-theme-editor-data" type="application/json">${payload}</script>`,
|
|
2306
|
+
'<script type="module">void import("/.suda-build/editor-client.ts").catch((error)=>console.error("[theme-dev] theme editor failed to load",error))</script>',
|
|
2307
|
+
"</body>",
|
|
2308
|
+
"</html>"
|
|
2309
|
+
].join("");
|
|
2310
|
+
}
|
|
2176
2311
|
function serializeInlineScriptValue(value) {
|
|
2177
2312
|
return JSON.stringify(value).replaceAll("<", "\\u003c").replaceAll("\u2028", "\\u2028").replaceAll("\u2029", "\\u2029");
|
|
2178
2313
|
}
|
|
2179
|
-
function renderDevDesignPalette(designSystem) {
|
|
2180
|
-
|
|
2181
|
-
return { style: "", html: "" };
|
|
2182
|
-
}
|
|
2314
|
+
function renderDevDesignPalette(designSystem, editorHref) {
|
|
2315
|
+
const hasPresetSwitcher = designSystem.presets.length >= 2;
|
|
2183
2316
|
const presets = designSystem.presets.map((preset) => ({
|
|
2184
2317
|
id: preset.id,
|
|
2185
2318
|
variables: createThemeDesignCssVariables(preset.tokens)
|
|
@@ -2193,20 +2326,28 @@ function renderDevDesignPalette(designSystem) {
|
|
|
2193
2326
|
focusable: false
|
|
2194
2327
|
})
|
|
2195
2328
|
);
|
|
2196
|
-
const
|
|
2329
|
+
const editIcon = renderToStaticMarkup(
|
|
2330
|
+
createElement(Pencil, {
|
|
2331
|
+
width: 20,
|
|
2332
|
+
height: 20,
|
|
2333
|
+
"aria-hidden": true,
|
|
2334
|
+
focusable: false
|
|
2335
|
+
})
|
|
2336
|
+
);
|
|
2337
|
+
const buttons = hasPresetSwitcher ? designSystem.presets.map(
|
|
2197
2338
|
(preset) => `<button type="button" data-suda-dev-preset="${escapeHtml(preset.id)}" title="${escapeHtml(
|
|
2198
2339
|
preset.description ? `${preset.label} \u2014 ${preset.description}` : preset.label
|
|
2199
2340
|
)}" aria-label="${escapeHtml(preset.label)}"><span style="background:${escapeHtml(
|
|
2200
2341
|
preset.tokens.colors.primary
|
|
2201
2342
|
)}"></span>${selectedIcon}</button>`
|
|
2202
|
-
).join("");
|
|
2343
|
+
).join("") : "";
|
|
2203
2344
|
const config = serializeInlineScriptValue({
|
|
2204
2345
|
defaultPresetId: designSystem.defaultPresetId,
|
|
2205
2346
|
presets
|
|
2206
2347
|
});
|
|
2207
2348
|
return {
|
|
2208
|
-
style: '<style data-suda-dev-palette-style>\n#suda-dev-palette{all:initial;position:fixed;z-index:2147483000;top:50%;right:16px;width:64px;max-height:calc(100svh - 32px);padding:8px 9px;overflow-x:hidden;overflow-y:auto;box-sizing:border-box;background:#fff;border:1px solid #d1d5db;border-radius:999px;box-shadow:0 8px 24px rgb(15 23 42 / 12%);transform:translateY(-50%);color-scheme:light;scrollbar-width:none;-ms-overflow-style:none}\n#suda-dev-palette::-webkit-scrollbar{display:none}\n#suda-dev-palette button{all:initial;position:relative;display:grid;width:44px;height:44px;box-sizing:border-box;cursor:pointer;border-radius:999px;place-items:center}\n#suda-dev-palette button span{display:block;width:32px;height:32px;border-radius:999px;transition:transform 120ms ease}\n#suda-dev-palette button:hover span{transform:scale(1.08)}\n#suda-dev-palette button[aria-pressed="true"] span{visibility:hidden}\n#suda-dev-palette .suda-dev-preset-selected-icon{position:absolute;display:block;width:32px;height:32px;color:var(--suda-dev-preset-primary);visibility:hidden;opacity:0;transform:scale(.85);transition:opacity 120ms ease,transform 120ms ease}\n#suda-dev-palette button[aria-pressed="true"] .suda-dev-preset-selected-icon{visibility:visible;opacity:1;transform:scale(1)}\n#suda-dev-palette button:focus-visible{outline:2px solid #94a3b8;outline-offset:2px}\n@media(max-width:640px){#suda-dev-palette{right:8px;max-height:calc(100svh - 16px)}}\n@media(prefers-reduced-motion:reduce){#suda-dev-palette button span,#suda-dev-palette .suda-dev-preset-selected-icon{transition:none}}\n</style>',
|
|
2209
|
-
html: `<aside id="suda-dev-palette" aria-label="
|
|
2349
|
+
style: '<style data-suda-dev-palette-style>\n#suda-dev-palette{all:initial;position:fixed;z-index:2147483000;top:50%;right:16px;width:64px;max-height:calc(100svh - 32px);padding:8px 9px;overflow-x:hidden;overflow-y:auto;box-sizing:border-box;background:#fff;border:1px solid #d1d5db;border-radius:999px;box-shadow:0 8px 24px rgb(15 23 42 / 12%);transform:translateY(-50%);color-scheme:light;scrollbar-width:none;-ms-overflow-style:none}\n#suda-dev-palette::-webkit-scrollbar{display:none}\n#suda-dev-palette button{all:initial;position:relative;display:grid;width:44px;height:44px;box-sizing:border-box;cursor:pointer;border-radius:999px;place-items:center}\n#suda-dev-palette button span{display:block;width:32px;height:32px;border-radius:999px;transition:transform 120ms ease}\n#suda-dev-palette button:hover span{transform:scale(1.08)}\n#suda-dev-palette button[aria-pressed="true"] span{visibility:hidden}\n#suda-dev-palette .suda-dev-preset-selected-icon{position:absolute;display:block;width:32px;height:32px;color:var(--suda-dev-preset-primary);visibility:hidden;opacity:0;transform:scale(.85);transition:opacity 120ms ease,transform 120ms ease}\n#suda-dev-palette button[aria-pressed="true"] .suda-dev-preset-selected-icon{visibility:visible;opacity:1;transform:scale(1)}\n#suda-dev-palette button:focus-visible{outline:2px solid #94a3b8;outline-offset:2px}\n#suda-dev-palette .suda-dev-edit-divider{display:block;width:28px;height:1px;margin:4px auto;background:#e2e8f0}\n#suda-dev-palette .suda-dev-edit-link{all:initial;display:grid;width:44px;height:44px;box-sizing:border-box;color:#334155;cursor:pointer;border-radius:999px;place-items:center;transition:background-color 120ms ease,color 120ms ease}\n#suda-dev-palette .suda-dev-edit-link:hover{color:#0f172a;background:#f1f5f9}\n#suda-dev-palette .suda-dev-edit-link:focus-visible{outline:2px solid #94a3b8;outline-offset:2px}\n@media(max-width:640px){#suda-dev-palette{right:8px;max-height:calc(100svh - 16px)}}\n@media(prefers-reduced-motion:reduce){#suda-dev-palette button span,#suda-dev-palette .suda-dev-preset-selected-icon,#suda-dev-palette .suda-dev-edit-link{transition:none}}\n</style>',
|
|
2350
|
+
html: `<aside id="suda-dev-palette" aria-label="Theme development tools">${buttons}${hasPresetSwitcher ? '<span class="suda-dev-edit-divider" aria-hidden="true"></span>' : ""}<a class="suda-dev-edit-link" data-suda-dev-editor-link="" href="${escapeHtml(editorHref)}" title="Edit starter page" aria-label="Edit starter page">${editIcon}</a></aside>` + (hasPresetSwitcher ? `<script data-suda-dev-palette-script>(function(){const config=${config};const palette=document.getElementById("suda-dev-palette");if(!palette)return;const byId=new Map(config.presets.map((preset)=>[preset.id,preset]));const params=new URL(location.href).searchParams;const requested=params.get("designPreset");const selected=byId.has(requested)?requested:config.defaultPresetId;function apply(id,updateUrl){const preset=byId.get(id);if(!preset)return;const properties=Object.keys(preset.variables);const targets=[document.documentElement,document.body,...document.querySelectorAll("[style]")].filter((element,index,items)=>items.indexOf(element)===index&&(element===document.documentElement||element===document.body||properties.some((property)=>element.style.getPropertyValue(property)!=="")));for(const target of targets){for(const [property,value] of Object.entries(preset.variables))target.style.setProperty(property,value)}for(const button of palette.querySelectorAll("[data-suda-dev-preset]")){const active=button.dataset.sudaDevPreset===id;button.setAttribute("aria-pressed",String(active));button.style.setProperty("--suda-dev-preset-primary",byId.get(button.dataset.sudaDevPreset).variables["--suda-color-primary"])}const editorLink=palette.querySelector("[data-suda-dev-editor-link]");if(editorLink){const editorUrl=new URL(editorLink.href,location.href);editorUrl.searchParams.set("designPreset",id);editorLink.href=editorUrl.pathname+editorUrl.search+editorUrl.hash}if(updateUrl){const url=new URL(location.href);url.searchParams.set("designPreset",id);history.replaceState(history.state,"",url)}}if(requested&&byId.has(requested))apply(selected,false);else for(const button of palette.querySelectorAll("[data-suda-dev-preset]")){button.setAttribute("aria-pressed",String(button.dataset.sudaDevPreset===selected));button.style.setProperty("--suda-dev-preset-primary",byId.get(button.dataset.sudaDevPreset).variables["--suda-color-primary"])}palette.addEventListener("click",(event)=>{const button=event.target.closest("[data-suda-dev-preset]");if(button)apply(button.dataset.sudaDevPreset,true)})})();</script>` : "")
|
|
2210
2351
|
};
|
|
2211
2352
|
}
|
|
2212
2353
|
var SCREENSHOT_DEVICES = ["desktop", "tablet", "mobile"];
|