Skip to content

Commit

Permalink
feat: getting started content, docs nav
Browse files Browse the repository at this point in the history
  • Loading branch information
DanWebb committed Oct 7, 2024
1 parent e04fe69 commit cdd1464
Show file tree
Hide file tree
Showing 13 changed files with 227 additions and 20 deletions.
Empty file removed dist/.gitkeep
Empty file.
18 changes: 17 additions & 1 deletion eleventy.config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import browserslist from 'browserslist';
import { transform, browserslistToTargets } from 'lightningcss';
import markdownIt from 'markdown-it';
import { eleventyImagePlugin } from '@11ty/eleventy-img';
import webc from '@11ty/eleventy-plugin-webc';
import syntaxHighlight from '@11ty/eleventy-plugin-syntaxhighlight';
import renderSvg from './lib/renderSvg.js';
import findCollectionItem from './lib/findCollectionItem.js';

async function transformCSS(content) {
if (this.type !== 'css') {
Expand All @@ -28,9 +30,23 @@ export default function(eleventyConfig) {
eleventyConfig.addWatchTarget('src/styles/*.css');
// make functions available globally in templates
eleventyConfig.addJavaScriptFunction('renderSvg', renderSvg);
eleventyConfig.addJavaScriptFunction('findCollectionItem', findCollectionItem);
// support eleventy-image https://www.11ty.dev/docs/plugins/image
eleventyConfig.addPlugin(eleventyImagePlugin, {
formats: ['webp'],
widths: [800, 1600],
urkPath: '/assets/images/',
defaultAttributes: {
sizes: '100vw',
loading: 'lazy',
},
});
// load all components added to the src/components directory
eleventyConfig.addPlugin(webc, {
components: 'src/components/**/*.webc',
components: [
'src/components/**/*.webc',
'npm:@11ty/eleventy-img/*.webc',
],
bundlePluginOptions: {
transforms: [transformCSS],
},
Expand Down
9 changes: 9 additions & 0 deletions lib/findCollectionItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Find an item within a collection by it’s url
* @param {Array} collection the collection to search
* @param {String} url the url of the item to search for
* @returns A collection item or undefined
*/
export default function findCollectionItem(collection = [], url = '') {
return collection.find(post => post.url === url);
}
11 changes: 0 additions & 11 deletions src/docs/index.webc

This file was deleted.

Binary file added src/docs/the-problem/hero.webp
Binary file not shown.
110 changes: 110 additions & 0 deletions src/docs/the-problem/index.webc
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
layout: docs.webc
tags: ['docs', 'Getting started']
title: The problem
description: How do you create and organise components in a way that is scalable and maintainable over time?
icon: warning
permalink: /docs/index.html
next: /docs/the-solution/
---

<template webc:type="11ty" 11ty:type="md">

Imagine you’ve been tasked with designing a page hero. Having no other context or information to go on, you came up with the most conventional design ever.

<img
webc:is="eleventy-image"
src="./src/docs/the-problem/hero.webp"
alt="A conventional page hero UI"
/>

Excellent work! Now using a component-first mindset, you create a button component and a hero component.

The hero takes some props:

- title
- intro
- button text
- button url

This is awesome! It’s turned a bunch of HTML into a simple one-liner.

```html
<page-hero
title="Page title"
intro="Lorem ipsum dolor [...etc]"
button-text="Main action"
button-url="/page-slug"
/>
```

A little while later a new request comes in for a slightly different hero &ndash; a yellow variant with a new button style.

<img
webc:is="eleventy-image"
src="./src/docs/the-problem/yellow-hero.webp"
alt="The page hero with a yellow background"
/>

Easy, you add a prop to the hero to control the background colour and another one to pass the new button variant to the CTA.

It’s a couple more props, but it’s not too bad.

```html
<page-hero
title="Page title"
intro="Lorem ipsum dolor [...etc]"
cta="Main action"
url="/page-slug"
cta-style="secondary"
theme="yellow"
/>
```

This component is pretty neat, now it’s getting more powerful and can support more variations!

Over the months, more requirements come in and more props get added. Different teams have different requirements and they all need to use the component.

- Eyebrow text is added above the page title.
- A second smaller paragraph gets added below the intro (this one has links in it too).
- The Marketing team wanted a way to feature multiple CTAs of different types (sometimes they are buttons, sometimes links).
- The SEO team decide the eyebrow needs to be the `h1` and the “page title” text actually needs to be a `p` for maximum search power.

<img
webc:is="eleventy-image"
src="./src/docs/the-problem/max-hero.webp"
alt="The hero component with all the possible features"
/>

```html
<page-hero
title="Page title"
intro="Lorem ipsum dolor [...etc]"
cta="Main action"
url="https://another.site/page-slug"
cta-target="_blank"
cta-rel="noopener noreferrer"
cta-style="secondary"
theme="grey"
eyebrow="Eyebrow text"
eyebrow-tag="h1"
title-tag="p"
secondary-cta="Secondary action"
secondary-cta-type="button"
secondary-cta-style="secondary"
on-secondary-cta-click="handleCtaClick()"
>
<p slot="secondary-text">
Suspendisse sed dictum dolor, at hendrerit nibh. Curabitur euismod
ipsum ut mi <a href="#">elementum interdum</a>.
</p>
</page-hero>
```

This component is getting out of hand.

It’s riddled with conditional statements and testing the different combinations of props gets increasingly awkward. We would have done better just writing this out with HTML!

There must be a better way!

</template>
Binary file added src/docs/the-problem/max-hero.webp
Binary file not shown.
Binary file added src/docs/the-problem/yellow-hero.webp
Binary file not shown.
7 changes: 0 additions & 7 deletions src/docs/the-solution.webc

This file was deleted.

67 changes: 67 additions & 0 deletions src/docs/the-solution/index.webc
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
layout: docs.webc
tags: ['docs', 'Getting started']
title: The solution
description: Diamond UI is a method of organising and grouping components to cleanly separate their responsibilities.
icon: tick
previous: /docs/
next: /docs/content/
---

<template webc:type="11ty" 11ty:type="md">

When you think about it, a component is a function that takes some parameters and returns some HTML.

When writing code a generally agreed-on principle is that a function should *do one thing*. This makes functions more readable, modular and easy to maintain.

Here’s our page hero component as a function:

```js
function pageHero(
title,
intro,
cta,
url,
ctaTarget,
ctaRel,
ctaStyle,
theme,
eyebrow,
eyebrowTag,
titleTag,
secondaryCta,
secondaryCtaType,
secondaryCtaStyle,
onSecondaryCtaClick,
secondaryText
) {
let result = `<header class="page-hero page-hero--${theme}">`;

if (eyebrow) {
result += `<${eyebrowTag} class="page-hero__eyebrow">${eyebrow}</${eyebrowTag}>`;
}

result += `<${titleTag} class="page-hero__title">${title}</${titleTag}>`;

// ...horror continues...

return result;
}
```

If there was a function that looked like this, it would set off some serious alarm bells, why is it OK in components?

How do we stop our codebase from heading down this path? How can we define components from the start with clean boundaries to prevent the props from getting out of hand?

Diamond UI sets strict rules for component responsibilities that solve future maintenance problems **now.**

Components are grouped into one of the 4 Cs of UI, aiming to be concerned with fulfilling a single area of responsibility:

- Content
- Controls
- Canvas
- Composition

Let’s dive in.

</template>
20 changes: 19 additions & 1 deletion src/layouts/docs.webc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,25 @@ layout: default.webc

<d-separator class="diamond-spacing-bottom-xl"></d-separator>

<div @raw="content"></div>
<div @raw="content" class="diamond-spacing-bottom-xl"></div>

<diamond-grid>
<diamond-grid-item small-mobile="6" webc:for="direction of ['previous', 'next']">
<a :href="$data[direction]" webc:if="$data[direction]">
<diamond-card border radius>
<h3 class="diamond-text-size-base text-title-case" @text="direction"></h3>
<p>
<d-icon
webc:if="findCollectionItem($data.collections.docs, $data[direction]).data.icon"
:@icon="findCollectionItem($data.collections.docs, $data[direction]).data.icon"
class="text-color-blue"
></d-icon>
<span @text="findCollectionItem($data.collections.docs, $data[direction]).data.title"></span>
</p>
</diamond-card>
</a>
</diamond-grid-item>
</diamond-grid>
</diamond-section>
</d-sidebar-layout>
</diamond-wrap>
1 change: 1 addition & 0 deletions src/styles/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
--diamond-theme-link-color: var(--color-blue-light);
--diamond-theme-border-color: var(--color-blue-dark);
--diamond-theme-background-muted: var(--color-blue-dark);
--diamond-theme-border-color-hover: var(--color-blue-light);
}

.theme-medium {
Expand Down
4 changes: 4 additions & 0 deletions src/styles/util.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@
.fill {
display: grid;
height: 100%;
}

.text-title-case {
text-transform: capitalize;
}

0 comments on commit cdd1464

Please sign in to comment.