Initial Commit

This commit is contained in:
2024-06-13 00:00:00 -04:00
commit b5e421761f
762 changed files with 41771 additions and 0 deletions

BIN
src/pg/.DS_Store vendored Normal file

Binary file not shown.

243
src/pg/_color-samples.pug Normal file
View File

@@ -0,0 +1,243 @@
//- sample color-samples array. You can call it anything, you'll just substitute the
//- appropriate array name and id in the mixin call.
//-
//- The mixin call is
//- +color-samples([color array], [id])
//-
//- This will generate two cards: Blue and OJ. Note that as this functions on a loop, the
//- order of colors in the array and the colors in the dark and light shades matters.
//-
//- var colors = [
//- { name: "Blue",
//- color: "rgb( 46, 81, 161)",
//- grad:{
//- d: [
//- { n: "blue-d", c: "rgb( 19, 49,118)", d:""},
//- { n: "blue-xd", c: "rgb( 3, 18, 53)", d:""},
//- ],
//- l: [
//- { n: "blue-l", c: "rgb( 92,122,191)", d:""},
//- { n: "blue-xl", c: "rgb(178,195,236)", d:""},
//- ]
//- },
//- note: "This is my primary color."
//- },
//- { name: "OJ",
//- color: "rgb(240, 176, 49)",
//- grad:{
//- d: [
//- { n: "oj-d", c: "rgb(203,137, 6)", d: "Dark" },
//- { n: "oj-xd", c: "rgb(157,105, 0)", d: "Darker" },
//- ],
//- l: [
//- { n: "oj-l", c: "rgb(255,204,103)", d: "Light" },
//- { n: "oj-xl", c: "rgb(255,228,173)", d: "Lighter" },
//- ]
//- },
//- },
//-
//- ...
//-
//- ]
- function splitrgba (c) {
- c = c.substring(c.indexOf("(")+1,c.indexOf(")")).split(",");
- for (let i = 0; i < c.length; i++) {
- c[i] = c[i].trim();
- }
- let a = (c.length == 3 ? 1 : c[4])
- return { "rgb": [c[0],c[1],c[2],a.toString()], "r": c[0], "g": c[1], "b": c[2], "a": a.toString()}
- }
- function getLuminance (rgb) {
- for (let i =0; i<rgb.length; i++) {
- if (rgb[i] <= 0.03928) {
- rgb[i] = rgb[i] / 12.92;
- } else {
- rgb[i] = Math.pow( ((rgb[i]+0.055)/1.055), 2.4 );
- }
- }
- let l = (0.2126 * rgb[0]) + (0.7152 * rgb[1]) + (0.0722 * rgb[2]);
- return l;
- };
- function getContrastRatio (f, b) {
- f = splitrgba(f);
- b = splitrgba(b);
- let ratio = 1;
- let fl = getLuminance([f.r/255, f.g/255, f.b/255]);
- let bl = getLuminance([b.r/255, b.g/255, b.b/255]);
-
- if (fl >= bl) {
- ratio = (fl + .05) / (bl + .05);
- } else {
- ratio = (bl + .05) / (fl + .05);
- }
-
- return Math.round(ratio * 10) / 10;
-
- }
-
- function rgb2hex (c) {
- c = splitrgba(c);
- c.r = ( Number( c.r ) ).toString(16);
- c.g = ( Number( c.g ) ).toString(16);
- c.b = ( Number( c.b ) ).toString(16);
- return "#"+ (c.r.length===1 ? "0" : "") + c.r + (c.g.length===1 ? "0" : "") + c.g + (c.b.length===1 ? "0" : "") + c.b ;
- };
-
- function hex2rgb (h) {
- if (h.length == 3 || h.length == 4) {
- h = h.replace(/#([A-Za-z0-9])([A-Za-z0-9])([A-Za-z0-9])/,"#$1$1$2$2$3$3")
- }
- return "rgb(" + parseInt(((h.charAt(0) == "#") ? h.substring(1, 7) : h).substring(0, 2), 16) + ", " + parseInt(((h.charAt(0) == "#") ? h.substring(1, 7) : h).substring(2, 4), 16) + ", " + parseInt(((h.charAt(0) == "#") ? h.substring(1, 7) : h).substring(4, 6), 16) + ")";
- };
-
- function color (c, t) {
- if ((t == "hex" && c[0] == "#") || (t == "rgb" && c.substring(0,3) == "rgb")) {
- return c;
- } else if (t = "hex" && c.substring(0,3) == "rgb") {
- return rgb2hex(c);
- } else if (t = "rgb" && c[0] == "#") {
- return hex2rgb(c);
- } else {
- return false;
- }
- }
-
- String.prototype.toTitleCase = function() {
- return this.replace(/\w\S*/g, function(txt) {
- return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
- });
- }
mixin accessibility-info(c)
div.acchb
span color & black
small= getContrastRatio(color(c, "rgb"), "rgb(0,0,0)") + ":1"
div.acchw
span color & white
small= getContrastRatio(color(c, "rgb"), "rgb(255,255,255)") + ":1"
div.aa WCAG 2.0 AA
div.accbaa.result
- if (getContrastRatio(color(c, "rgb"), "rgb(0,0,0)") >= 4.5) {
span(style="color: " + c ) &#x2713;
- } else {
span &#x2717;
- } if (getContrastRatio(color(c, "rgb"), "rgb(0,0,0)") >= 3) {
span(style="color: " + c ) &#x2713;
- } else {
span &#x2717;
- }
div.accwaa.result
- if (getContrastRatio(color(c, "rgb"), "rgb(255,255,255)") >= 4.5) {
span(style="color: " + c ) &#x2713;
- } else {
span &#x2717;
- } if (getContrastRatio(color(c, "rgb"), "rgb(255,255,255)") >= 3) {
span(style="color: " + c ) &#x2713;
- } else {
span &#x2717;
- }
div.aaa WCAG 2.0 AAA
div.accbaaa.result
- if (getContrastRatio(color(c, "rgb"), "rgb(0,0,0)") >= 7) {
span(style="color: " + c ) &#x2713;
- } else {
span &#x2717;
- } if (getContrastRatio(color(c, "rgb"), "rgb(0,0,0)") >= 4.5) {
span(style="color: " + c ) &#x2713;
- } else {
span &#x2717;
- }
div.accwaaa.result
- if (getContrastRatio(color(c, "rgb"), "rgb(255,255,255)") >= 7) {
span(style="color: " + c ) &#x2713;
- } else {
span &#x2717;
- } if (getContrastRatio(color(c, "rgb"), "rgb(255,255,255)") >= 4.5) {
span(style="color: " + c ) &#x2713;
- } else {
span &#x2717;
- }
mixin color-samples(colors, theid)
color-samples
- let css = [];
- let scss = [];
- for (var i = 0; i < colors.length; ++i) {
- let fgcolor = ( getContrastRatio(color(colors[i].color, "rgb"), "rgb(0,0,0)") <= 4.5 ? "#FFF" : "#000" );
- css.push("");
- scss.push("");
- css.push("--" + colorpfx + "-" + colors[i].name.toLowerCase() + ": " + color(colors[i].color, "hex") + ";");
- scss.push(colorpfx + "-" + colors[i].name.toLowerCase() + ": " + color(colors[i].color, "hex") + ",");
color-sample( data-color= colors[i].color style="background-color: "+ colors[i].color + "; color: " + fgcolor)
name(data-hex= color(colors[i].color, "hex") data-rgb= color(colors[i].color, "rgb") data-token= "--" + colorpfx + "-" + colors[i].name.toLowerCase() )
span= colors[i].name.toTitleCase()
hex= color(colors[i].color, "hex")
rgb= color(colors[i].color, "rgb").replace(/\s+/g, "")
accessibility
+accessibility-info(colors[i].color)
- if (colors[i].grad.l.length > 0 || colors[i].grad.d.length > 0 ) {
sample-block
- for ( var ii = 0; ii < colors[i].grad.l.length; ++ii ) {
- css.push("--" + colorpfx + "-" + colors[i].grad.l[ii].n.toLowerCase() +": "+ color( colors[i].grad.l[ii].c, "hex") + ";");
- scss.push(colorpfx + "-" + colors[i].grad.l[ii].n.toLowerCase() +": "+ color( colors[i].grad.l[ii].c, "hex") + ",");
color-pill(data-hex= color( colors[i].grad.l[ii].c, "hex") data-rgb= color(colors[i].grad.l[ii].c, "rgb") data-token= "--" + colorpfx + "-" + colors[i].grad.l[ii].n)
span(style="background-color: " + colors[i].grad.l[ii].c )
div.tooltip-tc.color-accessibility(role="tooltip" inert tip-position="bottom")
+accessibility-info(color(colors[i].grad.l[ii].c, "rgb"))
if colors[i].grad.l[ii].d
span #{colors[i].grad.l[ii].d}
else
span #{colors[i].grad.l[ii].n}
- }
sample-block
- for ( var ii = 0; ii < colors[i].grad.d.length; ++ii ) {
- css.push("--" + colorpfx + "-" + colors[i].grad.d[ii].n.toLowerCase() +": "+ color( colors[i].grad.d[ii].c, "hex") + ";");
- scss.push(colorpfx + "-" + colors[i].grad.d[ii].n.toLowerCase() +": "+ color( colors[i].grad.d[ii].c, "hex") + ",");
color-pill(data-hex= color(colors[i].grad.d[ii].c, "hex") data-rgb= color(colors[i].grad.d[ii].c, "rgb") data-token= "--" + colorpfx + "-" + colors[i].grad.d[ii].n)
span(style="background-color: " + colors[i].grad.d[ii].c )
div.tooltip-tc.color-accessibility(role="tooltip" inert tip-position="bottom")
+accessibility-info(color(colors[i].grad.d[ii].c, "rgb"))
if colors[i].grad.d[ii].d
span #{colors[i].grad.d[ii].d}
else
span #{colors[i].grad.d[ii].n}
- }
- }
if colors[i].note
notes= colors[i].note
- }
div.tab-group(id= theid )
- csstab = csstab == undefined ? "css" : csstab
- scsstab = scsstab == undefined ? "scss" : scsstab
div(data-tab= csstab )
- let cssStr = ":root {"
- for (i = 0; i < css.length; i++) {
- cssStr += "\t" + css[i] + "\n";
- }
- cssStr += "}"
pre.language-css= cssStr
div(data-tab= scsstab )
- let scssStr = "$" + colorpfx + ": ("
- for (i = 0; i < scss.length; i++) {
- scssStr += "\t" + scss[i] + "\n";
- }
- scssStr += ");\n:root {\n\t@each $name, $color in $" + colorpfx + " {\n\t\t--#{$name}: #{$color};\n\t}\n}"
pre.language-css= scssStr

92
src/pg/_config.pug Normal file
View File

@@ -0,0 +1,92 @@
- var site = "DS2 core"
- var lang = "en"
- var colorpfx = "colour"
- var root = "."
-
var content = [
{
name: "colours",
status: "complete",
core: true,
},
{
name: "components",
status: "in-progress",
template: "none",
files: [
{
name: "switch",
status: "in-progress",
core: true,
},
]
},
{
name: "layouts",
status: "complete",
template: "none",
files: [
{
name: "breakpoints",
status: "complete",
core: true,
},
{
name: "header",
status: "complete",
core: true,
},
{
name: "tabs",
status: "complete",
core: true,
},
]
},
{
name: "status",
status: "complete",
core: true,
}
]
-
var colours = [
{ name: "Blue",
color: "rgb( 46, 81, 161)",
grad:{
d: [
{ n: "blue-d", c: "rgb( 19, 49,118)", d:""},
{ n: "blue-xd", c: "rgb( 3, 18, 53)", d:""},
],
l: [
{ n: "blue-l", c: "rgb( 92,122,191)", d:""},
{ n: "blue-xl", c: "rgb(178,195,236)", d:""},
]
},
// note: "This is my primary color"
},
{ name: "Grey",
color: "rgb(127, 127, 127)",
grad: {
d: [
{ n: "grey-d", c:"#4c4c4c", d:"Dark" },
{ n: "grey-xd", c:"#4c4c4c", d:"Darker" },
{ n: "black", c:"#000", d: "Black" },
{ n: "dark", c: "#000", d: "Dark"},
],
l: [
{ n: "grey-l", c:"#b2b2b2", d:"Light" },
{ n: "grey-xl", c:"#d8d8d8", d:"Lighter" },
{ n: "grey-xxl", c:"#f0f0f0", d:"Lightest" },
{ n: "white", c:"#FFF", d:"White" },
{ n: "page", c:"#FFF", d:"Default page" },
{ n: "light", c:"#FFF", d:"Light" },
]
},
}
]

80
src/pg/_master-index.pug Normal file
View File

@@ -0,0 +1,80 @@
include _config
block config
- var getDate = function(){
- var d = new Date();
- return d.toLocaleDateString(lang, {day: "numeric", month: "long", year: "numeric"});
- }
- String.prototype.toTitleCase = function() {
- return this.replace(/\w\S*/g, function(txt) {
- return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
- });
- }
- String.prototype.toSentenceCase = function() {
- return this.charAt(0).toUpperCase() + this.substr(1).toLowerCase();
- }
- String.prototype.toContent = function() {
- return this.replace(/-/g, " ");
- }
mixin show-content(items, path)
- path = (path == "" ? "" : path + "/") + items.name
- if (items.status == "deprecated") {
- articlestatus = "status-deprecated"
- } else {
- articlestatus = ""
- }
article(id=path.replace(/\//g, "-")
class=articlestatus
data-path=path
data-template=(items.template == undefined ? "pug" : items.template)
data-pattern=items.name
data-status=items.status
data-core= (items.core ? "true" : "false")
)
if items.files
each item in items.files
+show-content(item, path)
doctype html
html(lang= lang )
head
meta(charset="utf-8")
meta(http-equiv="X-UA-Compatible" content="IE=edge")
meta(name="viewport" content="width=device-width, initial-scale=1")
title(data-site= site )= site
block head
link( href="assets/scaffolding.css" rel="stylesheet" )
script(src="assets/jquery-min.js")
body
a.skip(href="#main") Skip to main content
div.container
block header
main#main
h1= site
each category in content
+show-content(category, "")
script(src="assets/scaffolding-min.js")

View File

@@ -0,0 +1,28 @@
include _config
block config
- var getDate = function(){
- var d = new Date();
- return d.toLocaleDateString(lang, {day: "numeric", month: "long", year: "numeric"});
- }
- String.prototype.toTitleCase = function() {
- return this.replace(/\w\S*/g, function(txt) {
- return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
- });
- }
- String.prototype.toSentenceCase = function() {
- return this.charAt(0).toUpperCase() + this.substr(1).toLowerCase();
- }
- String.prototype.toContent = function() {
- return this.replace(/-/g, " ");
- }
html
head
title Pattern
body(data-assetpath= assetpath data-prismjs-copy-timeout="1500")
block content

20
src/pg/index.pug Normal file
View File

@@ -0,0 +1,20 @@
extends _master-index.pug
block config
- var site = "DS2 core"
block head
link(rel="icon" href="https://assets.gamv.ca/favicon.svg" media="(prefers-color-scheme:no-preference),(prefers-color-scheme:light)")
link(rel="icon" href="https://assets.gamv.ca/favicon-dark.svg" media="(prefers-color-scheme:dark)")
block header
include patterns/layouts/header-core/_header.pug
nav
ul
li
a(href="./") Home
each first in content
li(class= navClass)
a(href="./?p=" + first.name )= first.name.toContent().toSentenceCase()

BIN
src/pg/patterns/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,6 @@
extends ../../_master-pattern
block content
include ../../_color-samples
+color-samples(colours, "colours")

BIN
src/pg/patterns/components/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,26 @@
function flip(e) {
let sw = e.currentTarget;
switch(sw.getAttribute("aria-checked")) {
case "true":
sw.setAttribute("aria-checked", "false");
break;
case "false":
sw.setAttribute("aria-checked", "true");
break;
}
};
function init(callback){
let sw = document.querySelectorAll("[role='switch']");
for (let i=0; i < sw.length; i++) {
sw[i].innerHTML = "<span></span>";
sw[i].setAttribute("aria-checked", "false");
sw[i].setAttribute("tabindex", "0");
sw[i].addEventListener("click", flip, false);
sw[i].addEventListener("keypress", flip, false);
}
}
export {init};

View File

@@ -0,0 +1 @@
span#example-id(role="switch")

View File

@@ -0,0 +1,33 @@
@use "sass:math";
$switch-accent: #2e51a1 !default; // switch background when switched right (on/ true)
$switch-background: #e9e9ea !default; // switch background when switched left (off / false)
$switch-color: #ffffff !default; // the colour of the switch
$switch-height: 1.5rem !default;
@mixin switch {
[role='switch'] {
display: inline-grid;
border: 1px solid $switch-accent;
background-color: $switch-background;
border-radius: math.div($switch-height, 2);
height: $switch-height;
width: #{$switch-height * 2};
transition: all 500ms;
> span {
display: inline-block;
background-color: white;
border-radius: 50%;
margin: 2%;
width: calc(#{$switch-height} - 2%);
transition: all 500ms;
}
&[aria-checked="true"] {
background-color: $switch-accent;
> span {
margin-left: calc(#{$switch-height} - 5%);
}
}
}
}

View File

@@ -0,0 +1,21 @@
extends ../../../_master-pattern.pug
block content
h2 Example
p.switch
label(for="example-switch") Switch label
span#example-switch(role="switch")
div#switches.tab-group
pre.language-html(data-tab="html")
include _switch.pug
pre.language-pug(data-tab="pug")
include switch.pug
pre.language-css(data-tab="css")
include switch.css
pre.language-css(data-tab="scss")
include _switch.scss
pre.language-js(data-tab="js")
include _switch.js

View File

@@ -0,0 +1,26 @@
[role=switch] {
display: -ms-inline-grid;
display: inline-grid;
border: 1px solid #2e51a1;
background-color: #e9e9ea;
border-radius: 0.75rem;
height: 1.5rem;
width: 3rem;
-webkit-transition: all 500ms;
transition: all 500ms;
}
[role=switch] > span {
display: inline-block;
background-color: white;
border-radius: 50%;
margin: 2%;
width: calc(1.5rem - 2%);
-webkit-transition: all 500ms;
transition: all 500ms;
}
[role=switch][aria-checked=true] {
background-color: #2e51a1;
}
[role=switch][aria-checked=true] > span {
margin-left: calc(1.5rem - 5%);
}

View File

@@ -0,0 +1,2 @@
.
span#example-id(role="switch")

View File

@@ -0,0 +1,2 @@
@import "_switch.scss";
@include switch;

BIN
src/pg/patterns/layouts/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,83 @@
$grid-breakpoints: ( xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px ) !default;
@mixin breakpoint-debug {
body::before, body::after {
background-color: #555;
color: white;
content: "bigger than extra large";
display: grid;
font-size: 25px;
grid-template-columns: auto;
padding: 25px;
place-content: center;
// text-align: center;
@include break(-xl) {
content: "extra large";
}
@include break(-lg) {
content: "large";
}
@include break(-md) {
content: "medium";
}
@include break(-sm) {
content: "small";
}
}
}
@mixin break($bps, $points: $grid-breakpoints) {
@each $bp in $bps {
$min: 0;
$max: 0;
@if str-length($bp) == 2 {
// only a single break point was received
$min: map-get($points, $bp);
$max: map-get($points, nth(map-keys($points), index(map-keys($points), $bp) + 1));
} @else {
@if str-slice($bp, 0, 1) == "-" {
// no lower breakpoint was received
$min: null;
$max: map-get($points, str-slice($bp, 2, 3));
} @else {
$min: map-get($points, unquote(str-slice($bp, 0, 2)));
@if str-length($bp) == 3 {
// no upper break point was received
$max: null;
} @else {
$max: map-get($points, str-slice($bp, 4, 5));
}
}
}
@if $min != null and $max != null {
// Makes the @content apply between the min and max breakpoints
@media (min-width: $min) and (max-width: $max) {
@content;
}
} @else if $min == null {
// Makes the @content apply to the given breakpoint and narrower.
@media (max-width: $max) {
@content;
}
} @else if $max == null {
// Makes the @content apply to the given breakpoint and wider.
@media (min-width: $min) {
@content;
}
} @else {
@content;
}
}
}

View File

@@ -0,0 +1,13 @@
extends ../../../_master-pattern.pug
block content
+h(0)
+h(1)
+h(2)
p When using this, use the default break points as they are set to the same as the Bootstrap framework. The grid for the design system at large break point has been widened to accompdate 3 colour cards across.
div.tab-group#breakpoints
pre.language-css(data-tab="scss")
include _breakpoints.scss

View File

@@ -0,0 +1,13 @@
//- required variables
//- site - the site name that goes in the site title
//- root - the path to the root of the site
header
// The headline banner area
svg(height='5.5rem' width='100%' xmlns='http://www.w3.org/2000/svg' aria-hidden='true')
text= site
div
div.header-title
h1
a(href= root )= site
// Other sections can go here, such as search and directory

View File

@@ -0,0 +1,51 @@
$header-bg-color: var(--color-grey-xl) !default;
$font-heading: sans-serif !default;
$font-weight: 700 !default;
@mixin header {
header {
display: grid;
grid-template-rows: 1.75rem 3.5rem;
grid-column: 2 / 4;
overflow: hidden;
svg {
grid-column: 1 / -1;
grid-row: 1 / -1;
place-self: stretch;
text {
transform: translate(-1rem, 7.25rem);
font-size: 10rem;
font-weight: 1000;
font-family: $font-heading;
fill: $header-bg-color;
}
}
> div {
grid-row: 2;
grid-column: 1 / -1;
display: grid;
grid-column-gap: 1rem;
grid-template-columns: auto max-content max-content;
.header-title {
h1 {
margin: 0;
padding: 0 1rem;
a, a:visited {
border-bottom: none;
color: var(--colour-black);
font-family: $font-heading;
font-size: 2.5rem;
font-size: 32px;
font-weight: $font-weight;
margin: 0;
padding: 0;
text-decoration: none;
}
}
}
}
}
}

View File

@@ -0,0 +1 @@
header{display:-ms-grid;display:grid;-ms-grid-rows:1.75rem 3.5rem;grid-template-rows:1.75rem 3.5rem;-ms-grid-column:2;-ms-grid-column-span:2;grid-column:2/4;overflow:hidden}header svg{grid-column:1/-1;grid-row:1/-1;-ms-grid-row-align:stretch;-ms-grid-column-align:stretch;place-self:stretch}header svg text{-webkit-transform:translate(-1rem,7.25rem);-ms-transform:translate(-1rem,7.25rem);transform:translate(-1rem,7.25rem);font-size:10rem;font-weight:1000;font-family:sans-serif;fill:var(--color-grey-xl)}header>div{-ms-grid-row:2;grid-row:2;grid-column:1/-1;display:-ms-grid;display:grid;grid-column-gap:1rem;-ms-grid-columns:auto -webkit-max-content -webkit-max-content;-ms-grid-columns:auto max-content max-content;grid-template-columns:auto -webkit-max-content -webkit-max-content;grid-template-columns:auto max-content max-content}header>div .header-title h1{margin:0;padding:0 1rem}header>div .header-title h1 a,header>div .header-title h1 a:visited{border-bottom:none;color:var(--colour-black);font-family:sans-serif;font-size:2.5rem;font-size:32px;font-weight:700;margin:0;padding:0;text-decoration:none}

View File

@@ -0,0 +1,6 @@
// this file imports and generates the css for inclusion
// this file should not be minified
@import "_header.scss";
@include header;

View File

@@ -0,0 +1,23 @@
extends ../../../_master-pattern.pug
block content
div.tab-group#header
pre.language-html(data-tab="html")
// create temp variables and store the design system values
- var tmpsite= site
- var tmproot= root
- site = "[site name]"
- root = "[site root]"
include _header.pug
//- reset variables to original values
- site= tmpsite
- root= tmproot
pre.language-sass(data-tab="scss")
include _header.scss
pre.language-css(data-tab="css")
include header.css

View File

@@ -0,0 +1,24 @@
export function tabs($) {
$(".tab-group").each(function(){
let tabgroup = $(this).attr("id"),
tablist = "";
$(this).children("*").each(function(){
let tab = $(this).attr("data-tab");
if (typeof tab !== 'undefined' && tab !== false) {
let tabID = tab.replace(/\W+/g,"-").toLowerCase();
$(this).wrap(`<div id="tab-panel-${tabgroup + "-" + tabID }" ${(tablist == "" ? "class='open'" : "")} role="tabpanel" tabindex="0" aria-labeledby="tab-${tabgroup + "-" + tabID }"></div>`);
tablist += `<li tabindex="0" role="tab" ${(tablist == "" ? "class='selected'" : "")} id="tab-${tabgroup + "-" + tab.replace(/\W+/g,"-").toLowerCase()}"><span>${tab}</span></li>`;
} else {
$(this).addClass("tab-hidden");
}
})
$(this).prepend(`<ul role="tablist">${tablist}<li role="separator" class="separator"></li></ul>`);
})
$('[role="tab"]').on("click", function(){
$(this).parent().children('[role="tab"]').removeClass("selected");
$(this).addClass("selected");
$(this).parent().parent().children('[role="tabpanel"]').removeClass("open");
$("#" + $(this).attr("id").replace("tab", "tab-panel")).addClass("open");
})
}

View File

@@ -0,0 +1,61 @@
@mixin tabs {
.tab-group {
margin: 2rem 0 1rem 0;
> ul {
display: flex;
margin: 0;
padding: 0;
li.separator {
border-bottom: 1px solid var(--color-grey);
border-left: 1px solid var(--color-grey);
display: inline-block;
margin: .45rem 0 0 0;
width: 100%;
}
}
.tab-hidden {
display: none;
}
[role="tab"] {
background-color: var(--color-white);
border-left: 1px solid var(--color-grey);
border-top: 1px solid var(--color-grey);
border-radius: .5rem .5rem 0 0;
margin: 0;
display: inline;
padding: 1rem 1.5rem .14rem 1.5rem;
z-index: 2;
&:last-of-type {
border-right: 1px solid var(--color-grey);
}
&:not(.selected) {
background-color: var(--color-grey-xxl);
border-bottom: 1px solid var(--color-grey);
}
span {
display: block;
margin: 0 0 .5rem 0;
}
}
[role="tabpanel"] {
background-color: var(--color-white);
border: 1px solid var(--color-grey);
border-top: none;
padding: 1rem;
z-index: 1;
&:not(.open) {
display: none;
}
@content;
}
}
}

View File

@@ -0,0 +1,34 @@
extends ../../../_master-pattern.pug
block content
p The tabbed user interface enables users to jump to their target section quickly. Tabs present like logically group information on the same page. Information should
ul
li be logically chunked and ordered
li be arallel in nature
li show user's context
li obvious where they begin and end
p Users should not need to see content of multiple tabs simultaneously and the user should be able to easily recognise where they are within the content.
p The tab module is untested, but contains a modularized version of the jQuery code, so that it can be called on demand. It is what is used in the design system so that the JavaScript can be called at run time (after loading content).
div#tabs.tab-group
pre.language-html(data-tab="html").
<div class="tab-group" id="[unique name]">
<div data-tab="[tab title]"></div>
<div data-tab="[tab title]"></div>
...
</div>
pre.language-css(data-tab="css")
include tabs.css
pre.language-css(data-tab="scss")
include _tabs.scss
pre.language-css(data-tab="js")
include _tabs.js

View File

@@ -0,0 +1,51 @@
.tab-group {
margin: 2rem 0 1rem 0;
}
.tab-group > ul {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
margin: 0;
padding: 0;
}
.tab-group > ul li.separator {
border-bottom: 1px solid var(--color-grey);
border-left: 1px solid var(--color-grey);
display: inline-block;
margin: 0.45rem 0 0 0;
width: 100%;
}
.tab-group .tab-hidden {
display: none;
}
.tab-group [role=tab] {
background-color: var(--color-white);
border-left: 1px solid var(--color-grey);
border-top: 1px solid var(--color-grey);
border-radius: 0.5rem 0.5rem 0 0;
margin: 0;
display: inline;
padding: 1rem 1.5rem 0.14rem 1.5rem;
z-index: 2;
}
.tab-group [role=tab]:last-of-type {
border-right: 1px solid var(--color-grey);
}
.tab-group [role=tab]:not(.selected) {
background-color: var(--color-grey-xxl);
border-bottom: 1px solid var(--color-grey);
}
.tab-group [role=tab] span {
display: block;
margin: 0 0 0.5rem 0;
}
.tab-group [role=tabpanel] {
background-color: var(--color-white);
border: 1px solid var(--color-grey);
border-top: none;
padding: 1rem;
z-index: 1;
}
.tab-group [role=tabpanel]:not(.open) {
display: none;
}

View File

@@ -0,0 +1,24 @@
jQuery(document).ready(function($){
$(".tab-group").each(function(){
let tabgroup = $(this).attr("id"),
tablist = "";
$(this).children("*").each(function(){
let tab = $(this).attr("data-tab");
if (typeof tab !== 'undefined' && tab !== false) {
let tabID = tab.replace(/\W+/g,"-").toLowerCase();
$(this).wrap(`<div id="tab-panel-${tabgroup + "-" + tabID }" ${(tablist == "" ? "class='open'" : "")} role="tabpanel" tabindex="0" aria-labeledby="tab-${tabgroup + "-" + tabID }"></div>`);
tablist += `<li tabindex="0" role="tab" ${(tablist == "" ? "class='selected'" : "")} id="tab-${tabgroup + "-" + tab.replace(/\W+/g,"-").toLowerCase()}"><span>${tab}</span></li>`;
} else {
$(this).addClass("tab-hidden");
}
})
$(this).prepend(`<ul role="tablist">${tablist}<li role="separator" class="separator"></li></ul>`);
})
$('[role="tab"]').on("click", function(){
$(this).parent().children('[role="tab"]').removeClass("selected");
$(this).addClass("selected");
$(this).parent().parent().children('[role="tabpanel"]').removeClass("open");
$("#" + $(this).attr("id").replace("tab", "tab-panel")).addClass("open");
})
})

View File

@@ -0,0 +1,6 @@
// this file imports and generates the css for inclusion
// this file should not be minified
@import "_tabs.scss";
@include tabs;

View File

@@ -0,0 +1,60 @@
@mixin status {
div.status-report {
p.heading, td[colspan="2"] {
font-size: 1.125rem;
font-weight: bolder !important;
grid-column: 1 / -1;
margin: 2rem 0 .5rem 0;
padding-top: 1.5rem !important;
}
td:not([colspan="2"]) {
span {
display: grid;
grid-template-columns: auto 1rem;
margin: 0 1rem 0 0;
span[class^="status"]::after {
height: 1rem !important;
width: 1rem !important;
margin-right: 1rem;
}
}
}
.contain {
max-width: 100%;
width: 30rem;
ul {
margin: 0 0 1rem 0;
padding: 0;
li {
ul {
padding: .5rem 0 0 1rem;
}
list-style-type: none;
margin: 0 0 .25rem 0;
> span {
float: right;
margin: 0 1rem 0 0;
width: 8rem;
span[class^="status"]::after {
height: 1rem !important;
width: 1rem !important;
float: right
}
}
// > span {
// // display: inline-block;
// float: right;
// // width: 10rem;
// > span::after {
// height: 1rem !important;
// width: 1rem !important;
// margin-right: 1rem;
// }
// }
}
}
}
}
}

View File

@@ -0,0 +1,114 @@
extends ../../../_master-pattern.pug
//- extends ../../_master-pattern.pug
block content
-
- let list = []
- for(let i = 0; i < content.length; i++) {
- list.push({ "name": content[i].name, "path": content[i].name, "status": content[i].status } )
- if (content[i].files != undefined) {
- for (let ii = 0; ii < content[i].files.length; ii++) {
- list.push({ "name": content[i].files[ii].name, "path": content[i].name +"."+ content[i].files[ii].name, "status": content[i].files[ii].status } )
- if (content[i].files[ii].files != undefined) {
- for (let iii = 0; iii < content[i].files[ii].files.length; iii++) {
- list.push({ "name": content[i].files[ii].files[iii].name, "path": content[i].name +"."+ content[i].files[ii].name + "." + content[i].files[ii].files[iii].name, "status": content[i].files[ii].files[iii].status } )
- }
- }
- }
- }
- }
- list.sort((a, b) => {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- });
- function createURL(p) {
- p = p.split(".")
// - return p.length
- return "./?p=" + p[0] + (p.length >= 2 ? "/" + p[1] : "") + (p.length >= 3 ? "/" + p[2] : "")
- }
- function getCategory(p) {
- p = p.split(".")
// - return p.length
- return (p.length > 1 ? p[0].toContent().toSentenceCase() : "") + (p.length > 2 ? " / " + p[1].toContent().toSentenceCase() : "") + (p.length > 3 ? " / " + p[2].toContent().toSentenceCase() : "")
- }
- function getCount(obj) {
- console.log(obj.name)
- let count = 0;
- if (obj.files != undefined) {
- for(let i=0; i<obj.files.length; i++) {
- count = count + getCount(obj.files[i])
- }
- }
- count++;
- return count;
- }
div.tab-group#status-report
div.status-report.status-report-structure(data-tab="by&nbsp;structure")
div.contain
each category in content
p.heading= category.name.toContent().toSentenceCase() + " (" + getCount(category) + ")"
ul
li
a(href="./?p=" + category.name)= category.name.toContent().toSentenceCase()
span
span(class="status-" + category.status)= category.status.toContent().toSentenceCase()
//- pre.language-js= JSON.stringify(category).replace(/,/g, ",\n")
if category.files
each pattern in category.files
li
a(href="./?p=" + category.name + "/" + pattern.name )= pattern.name.toContent().toSentenceCase()
span
span(class="status-" + pattern.status)= pattern.status.toContent().toSentenceCase()
if pattern.files
ul
each sub in pattern.files
li
a(href="./?p=" + category.name + "/" + pattern.name + "/" + sub.name )= sub.name.toContent().toSentenceCase()
span
span(class="status-" + sub.status)= sub.status.toContent().toSentenceCase()
div.status-report.status-report-status(data-tab="by&nbsp;status")
- let statuses = ["not-started", "in-progress", "complete", "needs-review", "deprecated"];
table
thead
tr
td Pattern
td Path
tbody
each status in statuses
- out = list.filter(list => list.status === status)
tr
td(colspan="2")
span(class="status-" + status)= status.toContent().toSentenceCase() + " (" + out.length + ")"
each item in out
tr
td
a(href= createURL(item.path) )= item.name.toContent().toSentenceCase()
td= getCategory(item.path)
div.status-report.status-report-alpha(data-tab="alphabetical")
table
thead
tr
td Pattern
td Status
td Path
tbody
each item in list
tr
td
a(href= createURL(item.path) )= item.name.toContent().toSentenceCase()
td
span
span(class="status-" + item.status)= item.status.toContent().toTitleCase()
td= getCategory(item.path)