Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add single and holy-grail layout component, update site #582

Merged
merged 14 commits into from
Nov 28, 2023
5 changes: 5 additions & 0 deletions .changeset/cuddly-turkeys-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@microsoft/atlas-site': minor
---

Document the layout component in /components/layout.
5 changes: 5 additions & 0 deletions .changeset/grumpy-parents-think.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@microsoft/atlas-site': minor
---

Add new code fense label html-no-example which does not render an example.
5 changes: 5 additions & 0 deletions .changeset/rich-swans-divide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@microsoft/atlas-site': minor
---

Add a mobile navigation menu.
5 changes: 5 additions & 0 deletions .changeset/short-glasses-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@microsoft/atlas-css': minor
---

Add a layout component to provide a flexible way of specifying a site's layout with minimal nesting.
5 changes: 5 additions & 0 deletions .changeset/strange-shrimps-sip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@microsoft/parcel-transformer-markdown-html': minor
---

Update to allow a hero element to be rendered if yaml front matter containers `hero: true`.
5 changes: 5 additions & 0 deletions .changeset/sweet-pants-agree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@microsoft/atlas-site': minor
---

Apply the holy grail layout from the new layout component to the site.
1 change: 1 addition & 0 deletions css/src/components/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@
@import './toggle.scss';
@import './scroll.scss';
@import './stretched-link.scss';
@import './layout.scss';
112 changes: 112 additions & 0 deletions css/src/components/layout.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
@use 'sass:math';

.layout {
display: flex;
flex-direction: column;
max-inline-size: 100vw;
overflow-x: hidden;
BenDMyers marked this conversation as resolved.
Show resolved Hide resolved
BenDMyers marked this conversation as resolved.
Show resolved Hide resolved

// --layout-gutter by default, see tokens/layout.scss
#{$layout-gap-custom-property-name}: $layout-gap;
#{$layout-gap-scalable-custom-property-name}: $layout-gap;

@include widescreen {
#{$layout-gap-scalable-custom-property-name}: $layout-widescreen-gap;
}
}

.layout-body {
display: grid;
width: 100%;
max-width: 100%;
}

// grid-area values

.layout-body-header {
grid-area: header;
}

.layout-body-hero {
grid-area: hero;
}

.layout-body-menu {
grid-area: menu;
}

.layout-body-main {
grid-area: main;
}

.layout-body-aside {
grid-area: aside;
}

.layout-body-footer {
grid-area: footer;
}

.layout,
.layout.layout-single {
.layout-body {
grid-template: auto auto auto 1fr auto auto / 1fr;
grid-template-areas: 'header' 'hero' 'menu' 'main' 'aside' 'footer';
}
}

.layout.layout-holy-grail {
.layout-body {
grid-template: auto auto auto 1fr auto auto / 1fr;
grid-template-areas: 'header' 'hero' 'menu' 'main' 'aside' 'footer';

@include tablet {
grid-template: auto auto 1fr auto auto / 1fr 2fr;
grid-template-areas:
'header header'
'hero hero'
'menu main'
'menu aside'
'footer footer';
}

@include desktop {
grid-template: auto auto 1fr auto / 1fr 2fr 1fr;
grid-template-areas:
'header header header'
'hero hero hero'
'menu main aside'
'footer footer footer';
}

$widescreen-side-columns-width: math.div($breakpoint-widescreen, 4);
$widescreen-main-width: math.div($breakpoint-widescreen, 2);

@include widescreen {
grid-template: auto auto 1fr auto / auto #{$widescreen-side-columns-width} #{$widescreen-main-width} #{$widescreen-side-columns-width} auto;
grid-template-areas:
'header header header header header'
'hero hero hero hero hero'
'. menu main aside .'
'footer footer footer footer footer';
}
}
}

.layout-padding {
padding-inline: var(#{$layout-gap-custom-property-name}) !important;
}

.layout-margin {
margin-inline: var(#{$layout-gap-scalable-custom-property-name}) !important;
}

.layout-body-hero,
.layout-body-main,
.layout-body-footer,
.layout-body-aside,
.layout-body-menu {
&:empty {
display: none;
}
}
11 changes: 8 additions & 3 deletions css/src/tokens/layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
// Layout
$column-gap: 0.75rem !default;
$large-column-gap: 1.5rem !default;
$reading-max-width: 50rem;
$reading-max-width: 50rem !default;

$layout-gap: 16px !default;
$layout-gap: 24px !default;
$layout-widescreen-width: $breakpoint-widescreen - $layout-gap * 2 !default;
$layout-widescreen-gap: calc(50% - #{$layout-widescreen-width} / 2) !default;
$layout-widescreen-gap: calc(
50% - #{$layout-widescreen-width} / 2
) !default; // $layout-widescreen-gap is a naming error, keeping for backwards compat

$layout-gap-custom-property-name: '--layout-gap' !default;
$layout-gap-scalable-custom-property-name: '--layout-gap-scalable' !default;
//@end-sass-export-section
1 change: 1 addition & 0 deletions integration/tests/accessibility.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const pathnames = [
'/components/image.html',
'/components/input.html',
'/components/label.html',
'/components/layout.html',
'/components/link-button.html',
'/components/markdown.html',
'/components/media.html',
Expand Down
52 changes: 45 additions & 7 deletions plugins/parcel-transformer-markdown-html/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ const languageDisplayNames = {
'atomics-filter': 'Atomics',
atomics: 'Atomics',
'abut-html': 'HTML',
'html-no-indent': 'HTML'
'html-no-indent': 'HTML',
'html-no-example': 'HTML'
};

let filterIds = 0;
Expand Down Expand Up @@ -50,25 +51,34 @@ const markedOptions = {
heading(text, level) {
const id = text.toLowerCase().replace(/[^\w]+/g, '-');

return `<div class="markdown">
return `
<!-- heading-capture-outer-begin -->
<div class="markdown">
<a href="#${id}" aria-label="Section titled: ${text}">
<span class="heading-anchor"></span>
</a>
<h${level} id="${id}">
${text}
<!-- heading-capture-text-begin -->${text}<!-- heading-capture-text-end -->
</h${level}>
</div>`;
</div>
<!-- heading-capture-outer-end -->
`;
},
code(code, language) {
const fullWidth = language === 'html-no-indent';
let provideExample = true;
if (language === 'html-no-example') {
language = 'html';
provideExample = false;
}
let spacing = 'margin-top-sm';
if (language === 'abut-html' || language === 'html-no-indent') {
language = 'html';
}
if (language === 'abut-html') {
spacing = '';
}
const elementExample = createExample(language, code, fullWidth);
const elementExample = provideExample ? createExample(language, code, fullWidth) : '';

const displayName =
language in languageDisplayNames ? languageDisplayNames[language] : language;
Expand Down Expand Up @@ -161,7 +171,7 @@ module.exports = new Transformer({
const code = await asset.getCode();
const { body, attributes } = frontMatter(code);

const parsedCode = attributes.import
let parsedCode = attributes.import
? await options.inputFS
.readFile(path.join(process.cwd(), attributes.import), 'utf-8')
.then(content => marked(content))
Expand Down Expand Up @@ -213,6 +223,13 @@ module.exports = new Transformer({
asset.invalidateOnFileChange(tocFilename);
}

let hero = false;
if (attributes.hero) {
const { h1, p, html } = extractH1AndFirstP(parsedCode);
parsedCode = html;
hero = { h1, description: p };
}

asset.invalidateOnFileChange(templateFilename);
const githubLink = buildGithubLink(asset.filePath);
asset.setCode(
Expand All @@ -224,7 +241,8 @@ module.exports = new Transformer({
...attributes,
tokens,
cssTokenSource,
figmaEmbed
figmaEmbed,
hero
})
);
} else {
Expand All @@ -244,3 +262,23 @@ function createExample(language, code, noIndent = false) {
}
return '';
}

function extractH1AndFirstP(htmlString) {
const entireH1Regexp =
/<!-- heading-capture-outer-begin -->\s*([\s\S]*?)\s*<!-- heading-capture-outer-end -->/i;
const entireH1 = htmlString.match(entireH1Regexp);
const entireh1Match = entireH1 ? entireH1[1].toString() : null;

// For now, only matchin the text in the first full paragraph.
const pMatch = htmlString.match(/<p>(.*?)<\/p>/);
const p = pMatch ? pMatch[1] : null;

const h1Match = htmlString.match(
/<!-- heading-capture-text-begin -->\s*([\s\S]*?)\s*<!-- heading-capture-text-end -->/i
);
const h1 = h1Match ? h1Match[1].toString() : null;
const html = htmlString
.replaceAll(entireh1Match, '')
.replace(p, '<div class="h1-inverse-spacer"></div>');
return { h1, p, html };
}
Loading
Loading