-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add initial preview and export of auto generated styleguide #41
- Loading branch information
1 parent
d403f3e
commit 163ca82
Showing
14 changed files
with
753 additions
and
17 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
packages/buttery-tokens-studio/app/features/style-guide/StyleGuidePageBreak.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { classes } from "@buttery/components"; | ||
import { css } from "@linaria/core"; | ||
import type { JSX } from "react"; | ||
import { forwardRef } from "react"; | ||
|
||
export type StyleGuidePageBreakPropsNative = JSX.IntrinsicElements["div"]; | ||
export type StyleGuidePageBreakProps = StyleGuidePageBreakPropsNative; | ||
|
||
const styles = css` | ||
display: block; | ||
break-after: page; | ||
page-break-after: always; | ||
`; | ||
|
||
export const StyleGuidePageBreak = forwardRef< | ||
HTMLDivElement, | ||
StyleGuidePageBreakProps | ||
>(function StyleGuidePageBreak({ children, className, ...restProps }, ref) { | ||
return ( | ||
<div | ||
{...restProps} | ||
className={classes(styles, "page-break", className)} | ||
ref={ref} | ||
> | ||
{children} | ||
</div> | ||
); | ||
}); |
31 changes: 31 additions & 0 deletions
31
packages/buttery-tokens-studio/app/features/style-guide/style-guide.useDownload.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { useConfigurationContext } from "../Config.context"; | ||
|
||
/** | ||
* Returns a named exportStyleGuide function that will | ||
* save the configuration. All sever loaders will | ||
* re-update | ||
*/ | ||
export function useExportStyleGuide() { | ||
const { getConfigFromState } = useConfigurationContext(); | ||
|
||
async function exportStyleGuide() { | ||
const config = getConfigFromState(); | ||
|
||
const formData = new FormData(); | ||
formData.append("config", JSON.stringify(config, null, 2)); | ||
|
||
// Send a POST request and open the PDF in a new tab | ||
const response = await fetch("/api/style-guide/export", { | ||
method: "POST", | ||
body: formData, | ||
}); | ||
|
||
if (response.ok) { | ||
const blob = await response.blob(); | ||
const url = window.URL.createObjectURL(blob); | ||
window.open(url, "_blank"); // Open the PDF in a new tab | ||
} | ||
} | ||
|
||
return { exportStyleGuide }; | ||
} |
11 changes: 11 additions & 0 deletions
11
packages/buttery-tokens-studio/app/features/style-guide/style-guide.utils.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
143 changes: 143 additions & 0 deletions
143
packages/buttery-tokens-studio/app/routes/api.style-guide.export.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
import path from "node:path"; | ||
import { readdir, readFile, writeFile } from "node:fs/promises"; | ||
|
||
import puppeteer from "puppeteer"; | ||
// import { json } from "@remix-run/node"; | ||
import type { ButteryTokensConfig } from "@buttery/tokens-utils/schemas"; | ||
import { renderToString } from "react-dom/server"; | ||
// import React from "react"; | ||
import type { ActionFunctionArgs } from "react-router"; | ||
import { collect } from "@linaria/server"; | ||
|
||
import { ConfigurationProvider } from "~/features/Config.context"; | ||
import { StyleGuideBasic } from "~/features/style-guide/StyleGuideBasic"; | ||
import { | ||
convertBrandColorIntoVariants, | ||
convertNeutralColorIntoVariants, | ||
getInitColorStateFromConfig, | ||
} from "~/features/color/color.utils"; | ||
import { | ||
getSGColorClass, | ||
getSgColorClassValues, | ||
} from "~/features/style-guide/style-guide.utils"; | ||
|
||
function htmlTemplate(htmlString: string, cssString: string) { | ||
return `<!DOCTYPE html><html> | ||
<head> | ||
<style type="text/css">${cssString}</style> | ||
</head> | ||
<body>${htmlString}</body></html>`; | ||
} | ||
|
||
export async function action({ request }: ActionFunctionArgs) { | ||
const formData = await request.formData(); | ||
const config = String(formData.get("config")); | ||
const configJson = JSON.parse(config) as ButteryTokensConfig; | ||
|
||
const clientAssetsDir = | ||
process.env.NODE_ENV !== "production" | ||
? path.resolve(process.cwd(), "./build/client/assets") | ||
: ""; | ||
const cssOutFile = | ||
process.env.NODE_ENV !== "production" | ||
? path.resolve(process.cwd(), "./build/app-css.css") | ||
: ""; | ||
const htmlOutFile = | ||
process.env.NODE_ENV !== "production" | ||
? path.resolve(process.cwd(), "./build/app-html.html") | ||
: ""; | ||
|
||
// Manually create some CSS styles | ||
const color = getInitColorStateFromConfig(configJson); | ||
const bVariants = convertBrandColorIntoVariants(color); | ||
const nVariants = convertNeutralColorIntoVariants(color); | ||
const variants = Object.assign(bVariants, nVariants); | ||
|
||
// Loop through all of the color and their variants and create individual classes | ||
let styleGuideCSS = ""; | ||
for (const [colorName, { base }] of Object.entries(variants)) { | ||
const attributes = getSgColorClassValues(base); | ||
styleGuideCSS = styleGuideCSS.concat(` | ||
.${getSGColorClass(colorName)} { | ||
background-color: ${attributes.backgroundColor}; | ||
color: ${attributes.color}; | ||
}`); | ||
} | ||
|
||
const dirents = await readdir(clientAssetsDir, { withFileTypes: true }); | ||
let restCss = ""; | ||
let root = ""; | ||
for await (const dirent of dirents) { | ||
if (!dirent.name.includes(".css")) continue; | ||
const cssFilePath = path.join(dirent.parentPath, dirent.name); | ||
const cssContent = await readFile(cssFilePath, { encoding: "utf8" }); | ||
// add the root to the beginning | ||
if (dirent.name.includes("root-")) { | ||
root = cssContent; | ||
continue; | ||
} | ||
restCss = restCss.concat(cssContent); | ||
} | ||
|
||
// Assemble the root, the style guide colors and the rest of the CSS | ||
const css = styleGuideCSS.concat(root).concat(restCss); | ||
|
||
// Assemble the HTML with the critical CSS to the react tree | ||
const reactHtml = renderToString( | ||
<ConfigurationProvider originalConfig={configJson}> | ||
<StyleGuideBasic /> | ||
</ConfigurationProvider> | ||
); | ||
const { critical: criticalCSS } = collect(reactHtml, css); | ||
const html = htmlTemplate(reactHtml, criticalCSS); | ||
|
||
// Print out some test's for verification | ||
if (process.env.NODE_ENV !== "production") { | ||
await writeFile(htmlOutFile, html); | ||
await writeFile(cssOutFile, criticalCSS); | ||
} | ||
|
||
// Render the style guide as HTML | ||
const browser = await puppeteer.launch({ headless: true }); | ||
const page = await browser.newPage(); | ||
await page.setContent(html, { | ||
waitUntil: "load", | ||
}); | ||
await page.evaluate(() => { | ||
document.querySelectorAll(".page-break").forEach((el) => { | ||
const node = el as HTMLElement; | ||
node.style.display = "block"; | ||
node.style.breakAfter = "page"; | ||
node.style.pageBreakAfter = "always"; // Fallback | ||
}); | ||
|
||
document.querySelectorAll(".page").forEach((el) => { | ||
const node = el as HTMLElement; | ||
node.style.borderBottom = "unset"; | ||
node.style.marginBottom = "unset"; | ||
node.style.paddingBottom = "unset"; | ||
node.style.padding = "unset"; | ||
node.style.border = "1px solid green"; | ||
}); | ||
}); | ||
const pdfBuffer = await page.pdf({ | ||
format: "A4", | ||
printBackground: true, | ||
landscape: true, | ||
margin: { | ||
top: ".5in", | ||
right: ".5in", | ||
bottom: ".5in", | ||
left: ".5in", | ||
}, | ||
displayHeaderFooter: false, | ||
}); | ||
await browser.close(); | ||
|
||
return new Response(pdfBuffer, { | ||
headers: { | ||
"Content-Type": "application/pdf", | ||
"Content-Disposition": "inline; filename=style-guide.pdf", // Open in browser instead of downloading | ||
}, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.