From fbf90d68abf1320beae9f31580a701ecc14ad832 Mon Sep 17 00:00:00 2001 From: AleksandrHovhannisyan Date: Wed, 7 Dec 2022 18:50:38 -0500 Subject: [PATCH] Use clsx to chain class name attributes --- .eleventy.js | 1 + README.md | 2 ++ demo/index.md | 26 +++++++++++++++++++++----- package.json | 1 + src/index.js | 7 ++++++- src/typedefs.js | 2 +- yarn.lock | 5 +++++ 7 files changed, 37 insertions(+), 7 deletions(-) diff --git a/.eleventy.js b/.eleventy.js index 6a18ad5..3c41a35 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -17,6 +17,7 @@ module.exports = (eleventyConfig) => { `, iframeAttributes: { height: '100', + class: 'code-demo', }, }); diff --git a/README.md b/README.md index 8ebc3ff..aaafc6f 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,8 @@ button.addEventListener('click', () => { {% endcodeDemo %} ```` +If you're using Nunjucks, you'll need to use [the `safe` filter](https://mozilla.github.io/nunjucks/templating.html#autoescaping) to opt out of auto-escaping the HTML. + ### Setting HTML Attributes on the Code Demo As we saw, you can set HTML attributes globally on all code demos in your `.eleventy.js` config using the `iframeAttributes` option, but you can also pass in attributes on a case-by-case basis. The example below leverages Nunjucks's support for [keyword arguments](https://mozilla.github.io/nunjucks/templating.html#keyword-arguments) to create a code demo that is 400 pixels tall: diff --git a/demo/index.md b/demo/index.md index 55076e6..af6581f 100644 --- a/demo/index.md +++ b/demo/index.md @@ -2,9 +2,7 @@ permalink: / --- -Below is an interactive code demo: - -{% codeDemo 'Code demo', height="400" %} +{% set html %} ```html
@@ -12,7 +10,9 @@ Below is an interactive code demo:
0 ``` +{% endset %} +{% set css %} ```css * { box-sizing: border-box; @@ -38,7 +38,9 @@ button { line-height: 1; } ``` +{% endset %} +{% set js %} ```js const buttons = document.querySelectorAll('[data-step]'); const output = document.querySelector('output'); @@ -48,6 +50,20 @@ buttons.forEach((button) => { count += Number(button.getAttribute('data-step')); output.innerHTML = count; }); -});; +}); ``` -{% endcodeDemo %} \ No newline at end of file +{% endset %} + +Below is an interactive code demo: + +{% codeDemo 'Code demo', height="400", class="another-class" %} +{{ html | safe }} +{{ css | safe }} +{{ js | safe }} +{% endcodeDemo %} + +Code blocks used: + +{{ html | safe }} +{{ css | safe }} +{{ js | safe }} \ No newline at end of file diff --git a/package.json b/package.json index 3e53505..a185113 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ }, "dependencies": { "@minify-html/node": "^0.10.3", + "clsx": "^1.2.1", "lodash.escape": "^4.0.1", "markdown-it": "^13.0.1", "outdent": "^0.8.0" diff --git a/src/index.js b/src/index.js index 7f42d24..7d71dad 100644 --- a/src/index.js +++ b/src/index.js @@ -3,12 +3,15 @@ const minifyHtml = require('@minify-html/node'); const markdownIt = require('markdown-it'); const outdent = require('outdent'); const { parseCode, stringifyAttributes } = require('./utils'); +const clsx = require('clsx'); /** * Higher-order function that takes user configuration options and returns the plugin shortcode. * @param {import('./typedefs').EleventyPluginCodeDemoOptions} options */ const makeCodeDemoShortcode = (options) => { + const sharedIframeAttributes = options.iframeAttributes; + /** * @param {string} source The children of this shortcode, as Markdown code blocks. * @param {string} title The title to set on the iframe. @@ -23,7 +26,9 @@ const makeCodeDemoShortcode = (options) => { const css = parseCode(tokens, 'css'); const html = parseCode(tokens, 'html'); const js = parseCode(tokens, 'js'); - const iframeAttributes = stringifyAttributes({ ...options.iframeAttributes, ...props }); + + const className = clsx(sharedIframeAttributes?.class, props.class); + const iframeAttributes = stringifyAttributes({ ...sharedIframeAttributes, ...props, class: className }); let srcdoc = `${options.renderDocument({ html, css, js })}`; diff --git a/src/typedefs.js b/src/typedefs.js index 8e7c2a9..db1b0d4 100644 --- a/src/typedefs.js +++ b/src/typedefs.js @@ -9,7 +9,7 @@ * @typedef EleventyPluginCodeDemoOptions * @property {string} name The shortcode name to use. * @property {(args: RenderArgs) => string} renderDocument A render function to render the iframe's document definition. - * @property {Record} iframeAttributes Any HTML attributes you want to set on the `