diff --git a/.storybook/preview.ts b/.storybook/preview.ts
index 8a1994c1..adf18fe4 100644
--- a/.storybook/preview.ts
+++ b/.storybook/preview.ts
@@ -54,13 +54,13 @@ export const parameters = {
[
'Intro',
'Typography', [
- 'Classes',
+ 'Main',
'Intro',
'Using the type system',
'*',
],
'Layout', [
- 'Classes',
+ 'Main',
'Spacers',
'Flexbox',
'*',
diff --git a/src/docs/docs-components/CopyColourTable/Table.jsx b/src/docs/docs-components/CopyColourTable/Table.jsx
new file mode 100644
index 00000000..32635488
--- /dev/null
+++ b/src/docs/docs-components/CopyColourTable/Table.jsx
@@ -0,0 +1,72 @@
+import React, { useEffect, useState } from 'react';
+
+import { Unstyled } from '@storybook/blocks';
+// @ts-ignore
+import classes from './styles.module.scss';
+
+const Copyable = (props) => {
+ const handleClick = async(props) => {
+ const copyText = props.wrap ? `var(${props.children})` : props.children;
+ await navigator.clipboard.writeText(copyText);
+ props.setCopied(true);
+ }
+
+ return (
+
+ );
+}
+
+const Cell = (props) => {
+ const [copied, setCopied] = useState(false);
+
+ let timeout;
+
+ useEffect(() => {
+ if(timeout) clearTimeout(timeout);
+ timeout = setTimeout(() => { setCopied(false); }, 1000);
+ }, [copied]);
+
+ const copyProps = {...props, ...{ copied, setCopied } };
+
+ return props.column === 0 ?
+
+
+
+ {props.children}
+
+
+ : props.children.map(css => (
+
+ {css}
+
+ ));
+}
+
+ const TD = (props) => | {props.children} | |
+const TR = (props) => {props.children.map((c, i) => (| {c} | ))}
+const TH = (props) => {props.children} | ;
+
+const CopyTable = ({ title = null, header, body, copyable, mdnLink = null }) => {
+ return (
+
+
+ {title}
+
+
+
+
+ {header.map(h => (| {h} | ))}
+
+
+
+ {body.map(b => ({b}
))}
+
+
+
+ )
+};
+
+export default CopyTable;
\ No newline at end of file
diff --git a/src/docs/docs-components/CopyColourTable/styles.module.scss b/src/docs/docs-components/CopyColourTable/styles.module.scss
new file mode 100644
index 00000000..7bce150e
--- /dev/null
+++ b/src/docs/docs-components/CopyColourTable/styles.module.scss
@@ -0,0 +1,131 @@
+$copyable: #0071a1;
+$header: #5e81ac;
+
+.title {
+ font-size: 18px;
+ color: #666;
+ margin-bottom: 5px;
+ font-weight: 400;
+ a span {
+ font-size: 18px;
+ line-height: 18px;
+ margin-left: 2px;
+ vertical-align: middle;
+ font-weight: bold;
+ opacity: 0.6;
+ &:hover {
+ opacity: 1;
+ }
+ }
+}
+
+.table :global {
+ min-height: 100px;
+ margin: 0 0 3rem;
+ width: 100%;
+ max-width: 600px;
+ border-collapse: collapse;
+ border-radius: 4px;
+ overflow: hidden;
+ th,
+ td {
+ padding: 6px 13px;
+ font-family: 'Nunito Sans', Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 24px;
+ }
+ thead tr {
+ // background-color: #5e81ac;
+ color: #333;
+ text-align: left;
+ th {
+ font-weight: bold;
+ color: #2e3438;
+ border: 1px solid hsla(203, 50%, 30%, 0.15);
+ margin: 0;
+
+ border-collapse: collapse;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ }
+ }
+ thead {
+ display: block;
+ width: 100%;
+ tr {
+ display: table;
+ table-layout: fixed;
+ width: 100%;
+ }
+ }
+ tbody {
+ display: block;
+ max-height: 605px;
+ overflow-y: scroll;
+ border-bottom: 1px solid hsla(203, 50%, 30%, 0.15);
+ }
+ tbody tr {
+ display: table;
+ table-layout: fixed;
+ width: 100%;
+ border: 1px solid hsla(203, 50%, 30%, 0.15);
+ border-radius: 4px;
+ font-size: 0.9rem;
+ font-weight: 400;
+ color: #404040;
+ td {
+ border-right: 1px solid #eee;
+ vertical-align: middle;
+ color: #2e3438;
+ position: relative;
+ button {
+ text-align: left;
+ padding: 0;
+ border: 0;
+ background-color: transparent;
+ cursor: pointer;
+ color: $copyable;
+
+ span {
+ font-size: 1rem;
+ color: inherit;
+ margin-right: 5px;
+ vertical-align: bottom;
+ }
+ div.copy-tag {
+ position: absolute;
+ right: 4px;
+ top: 50%;
+ transform: translate(0, -50%);
+ background-color: #333;
+ pointer-events: none;
+ color: white;
+ padding: 4px 6px;
+ border-radius: 4px;
+ font-size: 12px;
+ }
+ &:active {
+ transform: translate(1px, 1px);
+ }
+ }
+ }
+ }
+
+ tbody tr:nth-of-type(even) {
+ background-color: #f7fafc;
+ }
+
+ div.swatch-container {
+ display: flex;
+ align-items: center;
+ }
+
+ div.swatch {
+ width: 40px;
+ height: 40px;
+ border: 1px solid hsla(203, 50%, 30%, 0.15);
+ border-radius: 10px;
+ display: inline-block;
+ margin-right: 10px;
+ }
+}
diff --git a/src/docs/styles/borders/classes.stories.mdx b/src/docs/styles/borders/main.stories.mdx
similarity index 95%
rename from src/docs/styles/borders/classes.stories.mdx
rename to src/docs/styles/borders/main.stories.mdx
index a90831b4..b3f91907 100644
--- a/src/docs/styles/borders/classes.stories.mdx
+++ b/src/docs/styles/borders/main.stories.mdx
@@ -15,7 +15,7 @@ import borderStyle from '$lib/scss/borders/\_border-style.scss?raw';
{/* @ts-ignore */}
import borderWidth from '$lib/scss/borders/\_border-width.scss?raw';
-
+

diff --git a/src/docs/styles/colours/thematic.stories.mdx b/src/docs/styles/colours/thematic.stories.mdx
new file mode 100644
index 00000000..e7746305
--- /dev/null
+++ b/src/docs/styles/colours/thematic.stories.mdx
@@ -0,0 +1,39 @@
+import { Meta } from '@storybook/addon-docs';
+import { parameters } from '$docs/utils/docsPage.js';
+import CopyColourTable from '../../docs-components/CopyColourTable/Table.jsx';
+import { extractCssColourVariables } from '../../utils/parseCss';
+
+{/* @ts-ignore */}
+import greyScheme from '$lib/scss/colours/thematic/\_grey.scss?raw';
+
+{/* @ts-ignore */}
+import trScheme from '$lib/scss/colours/thematic/\_tr.scss?raw';
+
+{/* @ts-ignore */}
+import nordScheme from '$lib/scss/colours/thematic/\_nord.scss?raw';
+
+
+
+
+
+# Colours
+
+Several colour schemes are accessible through CSS variables in the tables below.
+
+
+
+
+
+
diff --git a/src/docs/styles/layout/utilities.stories.mdx b/src/docs/styles/layout/main.stories.mdx
similarity index 93%
rename from src/docs/styles/layout/utilities.stories.mdx
rename to src/docs/styles/layout/main.stories.mdx
index e483eef0..0fe6b4a4 100644
--- a/src/docs/styles/layout/utilities.stories.mdx
+++ b/src/docs/styles/layout/main.stories.mdx
@@ -12,7 +12,7 @@ import display from '$lib/scss/layout/\_display.scss?raw';
{/* @ts-ignore */}
import floats from '$lib/scss/layout/\_floats.scss?raw';
-
+

diff --git a/src/docs/styles/typography/classes.stories.mdx b/src/docs/styles/typography/main.stories.mdx
similarity index 97%
rename from src/docs/styles/typography/classes.stories.mdx
rename to src/docs/styles/typography/main.stories.mdx
index b43f7322..b31968bb 100644
--- a/src/docs/styles/typography/classes.stories.mdx
+++ b/src/docs/styles/typography/main.stories.mdx
@@ -35,7 +35,7 @@ import wordBreak from '$lib/scss/text/\_word-break.scss?raw';
import './styles.scss';
-
+

diff --git a/src/docs/utils/parseCss.js b/src/docs/utils/parseCss.js
index abeb2281..f450b091 100644
--- a/src/docs/utils/parseCss.js
+++ b/src/docs/utils/parseCss.js
@@ -17,3 +17,20 @@ export const cssStringToTableArray = (cssString) => {
return [className, properties];
});
};
+
+export const extractCssColourVariables = (cssString) => {
+ const variableRegexp = /(--[a-zA-Z][a-zA-Z0-9-]+):\s*(.+);/g;
+ const cssVariables = [...cssString.matchAll(variableRegexp)].map(
+ ([all, g1, g2]) => [g2, g1]
+ );
+ const colours = {};
+ for (const variable of cssVariables) {
+ const [colour, css] = variable;
+ if (colours[colour]) {
+ colours[colour].push(css);
+ } else {
+ colours[colour] = [css];
+ }
+ }
+ return Object.keys(colours).map((key) => [key, colours[key]]);
+};
diff --git a/src/scss/colours/thematic/_grey.scss b/src/scss/colours/thematic/_grey.scss
new file mode 100644
index 00000000..91ed365b
--- /dev/null
+++ b/src/scss/colours/thematic/_grey.scss
@@ -0,0 +1,13 @@
+:root {
+ --grey-50: #f9fafb;
+ --grey-100: #f3f4f6;
+ --grey-200: #e5e7eb;
+ --grey-300: #d1d5db;
+ --grey-400: #9ca3af;
+ --grey-500: #6b7280;
+ --grey-600: #4b5563;
+ --grey-700: #374151;
+ --grey-800: #1f2937;
+ --grey-900: #111827;
+ --grey-950: #030712;
+}