Skip to content

Commit

Permalink
feat: Add showcase rendering Mode (#275)
Browse files Browse the repository at this point in the history
* add showcase option

* apply requested changes
  • Loading branch information
tlgimenes authored Jun 2, 2023
1 parent 729c7e1 commit 1675000
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 9 deletions.
94 changes: 94 additions & 0 deletions components/LivePageShowcase.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { Head } from "$fresh/runtime.ts";

// Should give you pretty editor syntax and highlight on VSCode
const css = (x: TemplateStringsArray) => x.toString();

const styles = css`
body {
display: flex;
flex-direction: column;
gap: 40px;
background-color: transparent;
}
body>section {
border: 1px solid hsl(180, 5%, 70%);
border-radius: 4px;
cursor: pointer;
max-height: 500px;
overflow: hidden;
background-color: white;
}
body>section>:not(*:first-child) {
zoom: 0.75;
}
body>section:hover {
border-width: 1px;
filter: drop-shadow(0px 4px 8px rgba(0, 0, 0, 0.15)) drop-shadow(0px 8px 32px rgba(0, 0, 0, 0.1));
}
body>section>* {
pointer-events: none;
filter: none;
}
`;

const snippet = () => {
const register = () => {
((document.getRootNode() as HTMLElement).firstElementChild as HTMLElement)
?.style?.setProperty(
"background-color",
"transparent",
);

document.querySelectorAll("body>section").forEach((section, index) => {
// Treshold to consider a section as rendered. This is important for those
// sections that render a blank section
const [descriptor] = section.id.split(".tsx-");
const segments = descriptor.split("/");
const label = segments[segments.length - 1];
const description = segments.slice(0, segments.length - 1);

const div = document.createElement("div");
div.innerHTML = `
<div style="width: 100%; padding: 16px;">
<h2 style="font-size: 20px; font-weight: 700">${label}</h2>
<p style="font-size: 15px;">${description.join("/")}</p>
</div>
`;

section.insertBefore(div, section.firstChild);

section.addEventListener(
"click",
() =>
top?.postMessage(
{ type: "live::selectSession", payload: index },
"*",
),
);
});
};

if (document.readyState === "complete") {
register();
} else {
document.addEventListener("DOMContentLoaded", register);
}
};

function LivePageShowcase() {
return (
<Head>
<style dangerouslySetInnerHTML={{ __html: styles }} />
<script
type="text/javascript"
dangerouslySetInnerHTML={{ __html: `(${snippet})();` }}
/>
</Head>
);
}

export default LivePageShowcase;
2 changes: 1 addition & 1 deletion engine/schema/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const jsDocToSchema = (node: JsDoc) =>
}

const match = (tag as JsDocTagValued).value?.match(
/^@(?<key>[a-zA-Z]+) (?<value>.*)$/,
/^@(?<key>[a-zA-Z$]+) (?<value>.*)$/,
);

const key = match?.groups?.key;
Expand Down
32 changes: 24 additions & 8 deletions pages/LivePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { isSection, Section } from "$live/blocks/section.ts";
import LiveAnalytics from "$live/components/LiveAnalytics.tsx";
import LiveControls from "$live/components/LiveControls.tsx";
import LivePolyfills from "$live/components/LivePolyfills.tsx";
import LivePageShowcase from "../components/LivePageShowcase.tsx";
import LivePageEditor, {
BlockControls,
EditorContextProvider,
Expand All @@ -28,13 +29,18 @@ export interface Props {
sections: Section[];
}

type Mode = "default" | "edit" | "showcase";

const IdentityComponent = ({ children }: { children: ComponentChildren }) => (
<>{children}</>
);

export function renderSectionFor(editMode?: boolean) {
const Controls = editMode ? BlockControls : () => null;
const EditContext = editMode ? EditorContextProvider : IdentityComponent;
export function renderSectionFor(mode?: Mode) {
const isEditMode = mode === "edit"
const Controls = isEditMode ? BlockControls : () => null;
const EditContext = isEditMode
? EditorContextProvider
: IdentityComponent;

return function _renderSection(
{ Component: Section, props, metadata }: Props["sections"][0],
Expand Down Expand Up @@ -146,7 +152,7 @@ const useSlots = (
const renderPage = (
{ layout, sections: maybeSections }: Props,
useSlotsFromChild: Record<string, UseSlotSection> = {},
editMode = false,
editMode: Mode = "default",
): JSX.Element => {
const validSections = maybeSections?.filter(notUndefined) ?? [];
const layoutProps = layout?.props;
Expand Down Expand Up @@ -216,19 +222,29 @@ export default function LivePage(
);
}

const getMode = (params?: URLSearchParams): "edit" | "showcase" | "default" => {
const mode = params?.get("mode");
if (mode === "edit" || mode === "showcase") {
return mode;
}

return "default";
};

export function Preview(props: Props) {
const pageCtx = usePageContext();
const editMode = pageCtx?.url.searchParams.has("editMode") ?? false;
const mode = getMode(pageCtx?.url.searchParams);

return (
<LivePageContext.Provider
value={{ renderSection: renderSectionFor(editMode) }}
value={{ renderSection: renderSectionFor(mode) }}
>
<Head>
<meta name="robots" content="noindex, nofollow" />
</Head>
{renderPage(props, {}, editMode)}
{editMode && <LivePageEditor />}
{renderPage(props, {}, mode)}
{mode === "edit" && <LivePageEditor />}
{mode === "showcase" && <LivePageShowcase />}
</LivePageContext.Provider>
);
}

0 comments on commit 1675000

Please sign in to comment.