mirror of
https://github.com/danog/sass-site.git
synced 2024-11-26 20:14:53 +01:00
canSplit calculation and new codeExample short code
This commit is contained in:
parent
f67317f20d
commit
a3442155a5
@ -1,5 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const { EleventyRenderPlugin } = require('@11ty/eleventy');
|
||||
const syntaxHighlight = require('@11ty/eleventy-plugin-syntaxhighlight');
|
||||
const formatDistanceToNow = require('date-fns/formatDistanceToNow');
|
||||
@ -9,8 +10,8 @@ const markdown = require('markdown-it');
|
||||
const markdownItAttrs = require('markdown-it-attrs');
|
||||
const markdownDefList = require('markdown-it-deflist');
|
||||
const typogrify = require('typogr');
|
||||
const sass = require('sass');
|
||||
const { getImplStatus } = require('./source/helpers/sass_helpers.ts');
|
||||
const { Liquid } = require('liquidjs');
|
||||
const { getImplStatus, canSplit, generateCodeExample } = require('./source/helpers/sass_helpers.ts');
|
||||
|
||||
/** @param {import('@11ty/eleventy').UserConfig} eleventyConfig */
|
||||
module.exports = (eleventyConfig) => {
|
||||
@ -53,6 +54,15 @@ module.exports = (eleventyConfig) => {
|
||||
return '';
|
||||
});
|
||||
|
||||
const engine = new Liquid({
|
||||
root: path.resolve(__dirname, 'source/_includes/'),
|
||||
extname: '.liquid',
|
||||
});
|
||||
eleventyConfig.addLiquidShortcode('codeExample', (contents, exampleName, autogenCSS = true, syntax = null) => {
|
||||
const codeExample = generateCodeExample(contents, autogenCSS)
|
||||
return engine.renderFile('code_example.liquid', {code: codeExample, exampleName: exampleName})
|
||||
})
|
||||
|
||||
// Paired shortcodes...
|
||||
eleventyConfig.addPairedLiquidShortcode('markdown', (content) =>
|
||||
mdown.render(content),
|
||||
@ -109,42 +119,6 @@ module.exports = (eleventyConfig) => {
|
||||
},
|
||||
);
|
||||
|
||||
eleventyConfig.addLiquidFilter(
|
||||
'codeExample',
|
||||
(contents, autogenCSS = true, syntax = null) => {
|
||||
//TODO when are values for syntax passed in?
|
||||
//TODO add tests
|
||||
const splitContents = contents.split('===');
|
||||
|
||||
const scssContents = splitContents[0];
|
||||
const sassContents = splitContents[1];
|
||||
const cssContents = splitContents[2];
|
||||
|
||||
const scssExamples = scssContents.split('---');
|
||||
const sassExamples = sassContents.split('---');
|
||||
|
||||
let cssExample;
|
||||
if (cssContents) {
|
||||
cssExample = cssContents;
|
||||
} else if (!cssContents && autogenCSS) {
|
||||
// TODO check first if you even have scss or sass to generate css from
|
||||
// TODO what if no scss but sass?
|
||||
cssExample = '';
|
||||
scssExamples.forEach((scssSnippet) => {
|
||||
const generatedCSS = sass.compileString(scssSnippet);
|
||||
cssExample += generatedCSS.css;
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
scss: scssExamples,
|
||||
css: cssExample,
|
||||
sass: sassExamples,
|
||||
splitLocation: '50.0%', //TODO dynamically determine
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
eleventyConfig.addPlugin(EleventyRenderPlugin);
|
||||
eleventyConfig.addPlugin(syntaxHighlight);
|
||||
|
||||
|
@ -1,56 +1,52 @@
|
||||
{% assign first_tab_id = ui_id %}
|
||||
{% assign second_tab_id = first_tab_id | plus: 1 %}
|
||||
{% assign third_tab_id = second_tab_id | plus: 1 %}
|
||||
|
||||
<div class="code-example ui-tabs" style="--split-location: {{ code.splitLocation }}">
|
||||
<div class="code-example ui-tabs {% if code.canSplit %}can-split{% endif %}" style="--split-location: {{ code.splitLocation }}" >
|
||||
<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix" role="tablist">
|
||||
<li
|
||||
class="ui-tabs-tab ui-tab ui-tabs-active"
|
||||
aria-controls="example-{{ example_id | strip }}-scss"
|
||||
aria-controls="example-{{ exampleName | strip }}-scss"
|
||||
role="tab"
|
||||
aria-expanded="true"
|
||||
aria-selected="true">
|
||||
<a
|
||||
href="#example-{{ example_id | strip }}-scss"
|
||||
href="#example-{{ exampleName | strip }}-scss"
|
||||
class="ui-tabs-anchor"
|
||||
role="presentation"
|
||||
tabindex="-1"
|
||||
id="ui-id-{{ first_tab_id | strip }}">SCSS</a>
|
||||
id="ui-id-{{ exampleName | strip }}-scss">SCSS</a>
|
||||
</li>
|
||||
<li
|
||||
class="ui-tabs-tab ui-tab"
|
||||
role="tab"
|
||||
aria-controls="example-{{ example_id | strip }}-sass"
|
||||
aria-controls="example-{{ exampleName | strip }}-sass"
|
||||
aria-selected="false"
|
||||
aria-expanded="false"
|
||||
tabindex="-1">
|
||||
<a
|
||||
href="#example-{{ example_id | strip }}-sass"
|
||||
href="#example-{{ exampleName | strip }}-sass"
|
||||
class="ui-tabs-anchor"
|
||||
role="presentation"
|
||||
tabindex="-1"
|
||||
id="ui-id-{{ second_tab_id | strip }}">Sass</a>
|
||||
id="ui-id-{{ exampleName | strip }}-sass">Sass</a>
|
||||
</li>
|
||||
<li
|
||||
class="ui-tabs-tab css-tab ui-tab"
|
||||
role="tab"
|
||||
tabindex="-1"
|
||||
aria-controls="example-{{ example_id | strip }}-css"
|
||||
aria-labelledby="ui-id-{{ third_tab_id | strip }}"
|
||||
aria-controls="example-{{ exampleName | strip }}-css"
|
||||
aria-labelledby="ui-id-{{ exampleName | strip }}-css"
|
||||
aria-selected="false"
|
||||
aria-expanded="false">
|
||||
<a
|
||||
href="#example-{{ example_id | strip }}-css"
|
||||
href="#example-{{ exampleName | strip }}-css"
|
||||
class="ui-tabs-anchor"
|
||||
role="presentation"
|
||||
tabindex="-1"
|
||||
id="ui-id-{{ third_tab_id | strip }}">CSS</a>
|
||||
id="ui-id-{{ exampleName | strip }}-css">CSS</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div
|
||||
id="example-{{ example_id | strip }}-scss"
|
||||
id="example-{{ exampleName | strip }}-scss"
|
||||
class="ui-tabs-panel scss"
|
||||
aria-labelledby="ui-id-{{ first_tab_id | strip }}"
|
||||
aria-labelledby="ui-id-{{ exampleName | strip }}-scss"
|
||||
role="tabpanel"
|
||||
aria-hidden="false"
|
||||
style="">
|
||||
@ -59,9 +55,9 @@
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
<div
|
||||
id="example-{{ example_id | strip }}-sass"
|
||||
id="example-{{ exampleName | strip }}-sass"
|
||||
class="ui-tabs-panel sass ui-tabs-panel-inactive ui-tabs-panel-previously-active"
|
||||
aria-labelledby="ui-id-{{ second_tab_id | strip }}"
|
||||
aria-labelledby="ui-id-{{ exampleName | strip }}-sass"
|
||||
role="tabpanel"
|
||||
aria-hidden="true"
|
||||
style="">
|
||||
@ -70,9 +66,9 @@
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
<div
|
||||
id="example-{{ example_id | strip }}-css"
|
||||
id="example-{{ exampleName | strip }}-css"
|
||||
class="ui-tabs-panel css ui-tabs-panel-inactive"
|
||||
aria-labelledby="ui-id-{{ third_tab_id | strip }}"
|
||||
aria-labelledby="ui-id-{{ exampleName | strip }}-css"
|
||||
role="tabpanel"
|
||||
aria-hidden="true"
|
||||
style="">
|
||||
|
@ -82,7 +82,7 @@ separate them. All our examples are available in both syntaxes.
|
||||
|
||||
{% endmarkdown %}
|
||||
|
||||
{%- capture captureCode -%}
|
||||
{%- capture variablesCodeExample -%}
|
||||
$font-stack: Helvetica, sans-serif;
|
||||
$primary-color: #333;
|
||||
|
||||
@ -98,12 +98,7 @@ body
|
||||
font: 100% $font-stack
|
||||
color: $primary-color
|
||||
{%- endcapture -%}
|
||||
|
||||
{%- assign parsedExample = captureCode | codeExample: true, 'scss' -%}
|
||||
{%- assign example_id = 1 -%}
|
||||
{%- assign ui_id = 1 -%}
|
||||
|
||||
{% render 'code_example', code: parsedExample,example_id: example_id, ui_id: ui_id %}
|
||||
{% codeExample variablesCodeExample, 'variables' %}
|
||||
|
||||
{% markdown %}
|
||||
When the Sass is processed, it takes the variables we define for the
|
||||
@ -134,7 +129,7 @@ navigation:
|
||||
|
||||
{% endmarkdown %}
|
||||
|
||||
{%- capture captureCode -%}
|
||||
{%- capture nestingCodeExample -%}
|
||||
nav {
|
||||
ul {
|
||||
margin: 0;
|
||||
@ -165,18 +160,7 @@ nav
|
||||
padding: 6px 12px
|
||||
text-decoration: none
|
||||
{%- endcapture -%}
|
||||
|
||||
{% capture example_id %}
|
||||
{{ example_id | plus: 1 }}
|
||||
{% endcapture %}
|
||||
|
||||
{% capture ui_id %}
|
||||
{{ ui_id | plus: 3 }}
|
||||
{% endcapture %}
|
||||
|
||||
{%- assign parsedExample = captureCode | codeExample: true, 'scss' -%}
|
||||
|
||||
{% render 'code_example', code: parsedExample, example_id: example_id, ui_id: ui_id %}
|
||||
{% codeExample nestingCodeExample, 'nesting' %}
|
||||
|
||||
</section>
|
||||
|
||||
@ -210,7 +194,6 @@ partials are used with the `@use` rule.
|
||||
{% assign implStatusData = "1.23.0" | implStatus: false, false, false, false, "Only Dart Sass currently supports `@use`. Users of other implementations must use the [`@import` rule][] instead.
|
||||
|
||||
[`@import` rule]: /documentation/at-rules/import" %}
|
||||
|
||||
{% render 'impl_status', implStatusData: implStatusData %}
|
||||
|
||||
You don't have to write all your Sass in a single file. You can split it up
|
||||
@ -224,7 +207,7 @@ file will also include the CSS it generates in your compiled output!
|
||||
|
||||
{% endmarkdown %}
|
||||
|
||||
{%- capture captureCode -%}
|
||||
{%- capture modulesCodeExample -%}
|
||||
// _base.scss
|
||||
$font-stack: Helvetica, sans-serif;
|
||||
$primary-color: #333;
|
||||
@ -271,18 +254,7 @@ body {
|
||||
color: white;
|
||||
}
|
||||
{% endcapture %}
|
||||
|
||||
{% capture example_id %}
|
||||
{{ example_id | plus: 1 }}
|
||||
{% endcapture %}
|
||||
|
||||
{% capture ui_id %}
|
||||
{{ ui_id | plus: 3 }}
|
||||
{% endcapture %}
|
||||
|
||||
{%- assign parsedExample = captureCode | codeExample: true, 'scss' -%}
|
||||
|
||||
{% render 'code_example', code: parsedExample, example_id: example_id, ui_id: ui_id %}
|
||||
{% codeExample modulesCodeExample, 'modules' %}
|
||||
|
||||
</section>
|
||||
|
||||
@ -299,7 +271,7 @@ Sass very DRY. You can even pass in values to make your mixin more flexible. Her
|
||||
|
||||
{% endmarkdown %}
|
||||
|
||||
{% capture captureCode %}
|
||||
{% capture mixinsCodeExample %}
|
||||
@mixin theme($theme: DarkGray) {
|
||||
background: $theme;
|
||||
box-shadow: 0 0 1px rgba($theme, .25);
|
||||
@ -332,17 +304,7 @@ Sass very DRY. You can even pass in values to make your mixin more flexible. Her
|
||||
@include theme($theme: DarkGreen)
|
||||
{% endcapture %}
|
||||
|
||||
{% capture example_id %}
|
||||
{{ example_id | plus: 1 }}
|
||||
{% endcapture %}
|
||||
|
||||
{% capture ui_id %}
|
||||
{{ ui_id | plus: 3 }}
|
||||
{% endcapture %}
|
||||
|
||||
{%- assign parsedExample = captureCode | codeExample: true, 'scss' -%}
|
||||
|
||||
{% render 'code_example', code: parsedExample, example_id: example_id, ui_id: ui_id %}
|
||||
{% codeExample mixinsCodeExample, 'mixins' %}
|
||||
|
||||
{% markdown %}
|
||||
To create a mixin you use the `@mixin` directive and give it a name. We've named our mixin `theme`. We're also using the variable `$theme` inside the parentheses so we can pass in a `theme` of whatever we want. After you create your mixin, you can then use it as a CSS declaration starting with `@include` followed by the name of the mixin.
|
||||
@ -362,7 +324,7 @@ Using `@extend` lets you share a set of CSS properties from one selector to anot
|
||||
|
||||
{% endmarkdown %}
|
||||
|
||||
{%- capture captureCode -%}
|
||||
{%- capture extendInheritanceCodeExample -%}
|
||||
// This CSS will print because %message-shared is extended.
|
||||
%message-shared {
|
||||
border: 1px solid #ccc;
|
||||
@ -422,18 +384,7 @@ Using `@extend` lets you share a set of CSS properties from one selector to anot
|
||||
@extend %message-shared
|
||||
border-color: yellow
|
||||
{% endcapture %}
|
||||
|
||||
{% capture example_id %}
|
||||
{{ example_id | plus: 1 }}
|
||||
{% endcapture %}
|
||||
|
||||
{% capture ui_id %}
|
||||
{{ ui_id | plus: 3 }}
|
||||
{% endcapture %}
|
||||
|
||||
{%- assign parsedExample = captureCode | codeExample: true, 'scss' -%}
|
||||
|
||||
{% render 'code_example', code: parsedExample, example_id: example_id, ui_id: ui_id %}
|
||||
{% codeExample extendInheritanceCodeExample, 'extend-inheritance' %}
|
||||
|
||||
{% markdown %}
|
||||
What the above code does is tells `.message`, `.success`, `.error`, and
|
||||
@ -468,7 +419,7 @@ to do some simple math to calculate widths for an `article` and `aside`.
|
||||
|
||||
{% endmarkdown %}
|
||||
|
||||
{%- capture captureCode -%}
|
||||
{%- capture operatorsCodeExample -%}
|
||||
@use "sass:math";
|
||||
|
||||
.container {
|
||||
@ -512,18 +463,7 @@ aside[role="complementary"] {
|
||||
margin-left: auto;
|
||||
}
|
||||
{% endcapture %}
|
||||
|
||||
{% capture example_id %}
|
||||
{{ example_id | plus: 1 }}
|
||||
{% endcapture %}
|
||||
|
||||
{% capture ui_id %}
|
||||
{{ ui_id | plus: 3 }}
|
||||
{% endcapture %}
|
||||
|
||||
{%- assign parsedExample = captureCode | codeExample: true, 'scss' -%}
|
||||
|
||||
{% render 'code_example', code: parsedExample, example_id: example_id, ui_id: ui_id %}
|
||||
{% codeExample operatorsCodeExample, 'operators' %}
|
||||
|
||||
{% markdown %}
|
||||
We've created a very simple fluid grid, based on 960px. Operations in Sass
|
||||
|
@ -1,3 +1,37 @@
|
||||
import sass from 'sass';
|
||||
|
||||
export function generateCodeExample(contents: string, autogenCSS: boolean, syntax: string) {
|
||||
const splitContents = contents.split('===');
|
||||
|
||||
const scssContents = splitContents[0];
|
||||
const sassContents = splitContents[1];
|
||||
const cssContents = splitContents[2];
|
||||
|
||||
const scssExamples = scssContents.split('---');
|
||||
const sassExamples = sassContents.split('---');
|
||||
|
||||
let cssExample: string;
|
||||
if (cssContents) {
|
||||
cssExample = cssContents;
|
||||
} else {
|
||||
// TODO check first if you even have scss or sass to generate css from
|
||||
// TODO what if no scss but sass?
|
||||
cssExample = '';
|
||||
scssExamples.forEach((scssSnippet) => {
|
||||
const generatedCSS = sass.compileString(scssSnippet);
|
||||
cssExample += generatedCSS.css;
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
scss: scssExamples,
|
||||
css: cssExample,
|
||||
sass: sassExamples,
|
||||
canSplit: canSplit(scssExamples, sassExamples, cssExample),
|
||||
splitLocation: '50.0%', // TODO remove when css grid implementation done
|
||||
};
|
||||
}
|
||||
|
||||
export function getImplStatus(status: string | boolean | null) {
|
||||
switch (status) {
|
||||
case null:
|
||||
@ -12,3 +46,26 @@ export function getImplStatus(status: string | boolean | null) {
|
||||
return `since ${status}`;
|
||||
}
|
||||
}
|
||||
|
||||
export function canSplit(
|
||||
scssExamples: string[],
|
||||
sassExamples: string[],
|
||||
cssExample: string,
|
||||
) {
|
||||
const exampleSources: [string[], string[]] = [scssExamples, sassExamples];
|
||||
const exampleSourceLengths = exampleSources
|
||||
.map((sourceList) =>
|
||||
sourceList.map((source) =>
|
||||
source.split('\n').map((line) => line.length),
|
||||
),
|
||||
)
|
||||
.flat()
|
||||
.flat();
|
||||
const cssSourceLengths = cssExample.split('\n').map((line) => line.length);
|
||||
|
||||
const maxSourceWidth = Math.max(...exampleSourceLengths);
|
||||
const maxCSSWidth = Math.max(...cssSourceLengths)
|
||||
//TODO css example doesn't include comments so extend inheritance example can split is wrong
|
||||
|
||||
return Boolean((maxSourceWidth + maxCSSWidth) < 110);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user