more semantic class names, option to globalize CSS
This commit is contained in:
parent
9bb9632913
commit
692bfa8660
46
bin/globalize-css.js
Executable file
46
bin/globalize-css.js
Executable file
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env node
|
||||
// Change all the Svelte CSS to just use globals everywhere,
|
||||
// to reduce CSS size and complexity.
|
||||
|
||||
const argv = require('yargs').argv
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const pify = require('pify')
|
||||
const writeFile = pify(fs.writeFile.bind(fs))
|
||||
const readFile = pify(fs.readFile.bind(fs))
|
||||
const glob = pify(require('glob'))
|
||||
const rimraf = pify(require('rimraf'))
|
||||
|
||||
const selectorRegex = /\n[ \t]*([0-9\w\- \t\.:#,]+?)[ \t]*\{/g
|
||||
const styleRegex = /<style>[\s\S]+?<\/style>/
|
||||
|
||||
async function main() {
|
||||
if (argv.reverse) { // reverse the operation we just did
|
||||
let tmpComponents = await glob('./routes/**/.tmp-*.html')
|
||||
for (let filename of tmpComponents) {
|
||||
let text = await readFile(filename, 'utf8')
|
||||
await rimraf(filename)
|
||||
let originalFilename = path.join(path.dirname(filename), path.basename(filename).substring(5))
|
||||
await writeFile(originalFilename, text, 'utf8')
|
||||
}
|
||||
} else { // read all files, copy to tmp files, rewrite files to include global CSS everywhere
|
||||
let components = await glob('./routes/**/*.html')
|
||||
for (let filename of components) {
|
||||
let text = await readFile(filename, 'utf8')
|
||||
let newText = text.replace(styleRegex, style => {
|
||||
return style.replace(selectorRegex, selectorMatch => {
|
||||
return selectorMatch.replace(/\S[^\{]+/, selector => `:global(${selector})`)
|
||||
})
|
||||
})
|
||||
let newFilename = path.join(path.dirname(filename), '.tmp-' + path.basename(filename))
|
||||
|
||||
await writeFile(newFilename, text, 'utf8')
|
||||
await writeFile(filename, newText, 'utf8')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Promise.resolve().then(main).catch(err => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
|
@ -10,7 +10,9 @@
|
|||
"build-sass-watch": "node ./bin/build-sass --watch",
|
||||
"cy:run": "cypress run",
|
||||
"cy:open": "cypress open",
|
||||
"test": "run-p --race dev cy:run"
|
||||
"test": "run-p --race dev cy:run",
|
||||
"globalize-css": "node ./bin/globalize-css.js",
|
||||
"deglobalize-css": "node ./bin/globalize-css.js --reverse"
|
||||
},
|
||||
"dependencies": {
|
||||
"chokidar": "^2.0.0",
|
||||
|
@ -36,6 +38,7 @@
|
|||
"performance-now": "^2.1.0",
|
||||
"pify": "^3.0.0",
|
||||
"requestidlecallback": "^0.3.0",
|
||||
"rimraf": "^2.6.2",
|
||||
"sapper": "^0.3.2",
|
||||
"serve-static": "^1.13.1",
|
||||
"style-loader": "^0.19.1",
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<svg class="{{maskStyle ? 'mask-style' : ''}}">
|
||||
<svg class="loading-spinner-icon {{maskStyle ? 'mask-style' : ''}}">
|
||||
<use xlink:href="#fa-spinner" />
|
||||
</svg>
|
||||
<style>
|
||||
svg {
|
||||
.loading-spinner-icon {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
fill: var(--svg-fill);
|
||||
animation: spin 2s infinite linear;
|
||||
}
|
||||
|
||||
svg.mask-style {
|
||||
.loading-spinner-icon.mask-style {
|
||||
fill: var(--mask-svg-fill);
|
||||
}
|
||||
|
||||
|
|
Before Width: | Height: | Size: 543 B After Width: | Height: | Size: 600 B |
|
@ -1,4 +1,4 @@
|
|||
<nav>
|
||||
<nav class="main-nav">
|
||||
<ul>
|
||||
<li>
|
||||
<NavItem :page name="home" href="/" svg="#pinafore-logo" label="Home" />
|
||||
|
@ -19,7 +19,7 @@
|
|||
</nav>
|
||||
|
||||
<style>
|
||||
nav {
|
||||
.main-nav {
|
||||
border-bottom: 1px solid var(--nav-border);
|
||||
background: var(--nav-bg);
|
||||
position: fixed;
|
||||
|
@ -29,7 +29,7 @@
|
|||
z-index: 10;
|
||||
}
|
||||
|
||||
ul {
|
||||
.main-nav ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
@ -38,7 +38,7 @@
|
|||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
li {
|
||||
.main-nav li {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class='{{page === name ? "selected" : ""}}'
|
||||
<a class='main-nav-link {{page === name ? "selected" : ""}}'
|
||||
aria-label='{{page === name ? `${label} (current page)` : label}}'
|
||||
aria-current="{{page === name}}"
|
||||
href='{{href}}'>
|
||||
|
@ -8,7 +8,7 @@
|
|||
<span>{{label}}</span>
|
||||
</a>
|
||||
<style>
|
||||
a {
|
||||
.main-nav-link {
|
||||
border-bottom: 1px solid var(--nav-a-border);
|
||||
text-decoration: none;
|
||||
padding: 25px 20px;
|
||||
|
@ -17,46 +17,46 @@
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
a.selected {
|
||||
.main-nav-link.selected {
|
||||
border-bottom: 1px solid var(--nav-a-selected-border);
|
||||
background: var(--nav-a-selected-bg);
|
||||
}
|
||||
|
||||
a.selected:hover {
|
||||
.main-nav-link.selected:hover {
|
||||
border-bottom: 1px solid var(--nav-a-selected-border-hover);
|
||||
background: var(--nav-a-selected-bg-hover);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
.main-nav-link:hover {
|
||||
background-color: var(--nav-a-bg-hover);
|
||||
border-bottom: 1px solid var(--nav-a-border-hover);
|
||||
}
|
||||
|
||||
a:hover span {
|
||||
.main-nav-link:hover span {
|
||||
color: var(--nav-text-color-hover);
|
||||
}
|
||||
a:hover svg {
|
||||
.main-nav-link:hover svg {
|
||||
fill: var(--nav-svg-fill-hover);
|
||||
}
|
||||
|
||||
svg {
|
||||
.main-nav-link svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
fill: var(--nav-svg-fill);
|
||||
}
|
||||
|
||||
span {
|
||||
.main-nav-link span {
|
||||
font-size: 16px;
|
||||
color: var(--nav-text-color);
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
span {
|
||||
.main-nav-link span {
|
||||
display: none;
|
||||
}
|
||||
svg {
|
||||
.main-nav-link svg {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
|
|
|
@ -17,18 +17,18 @@
|
|||
.not-logged-in-home {
|
||||
margin: 10px;
|
||||
}
|
||||
.banner {
|
||||
.not-logged-in-home .banner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 0 30px;
|
||||
}
|
||||
svg {
|
||||
.not-logged-in-home svg {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
fill: royalblue;
|
||||
display: inline-block;
|
||||
}
|
||||
h1 {
|
||||
.not-logged-in-home h1 {
|
||||
color: royalblue;
|
||||
display: inline-block;
|
||||
font-size: 3em;
|
||||
|
@ -36,7 +36,7 @@
|
|||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
h1 {
|
||||
.not-logged-in-home h1 {
|
||||
font-size: 2.7em;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
pointer-events: none;
|
||||
/* will-change: transform; */ /* causes jank in mobile Firefox */
|
||||
}
|
||||
.shown {
|
||||
.virtual-list-item.shown {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<ul>
|
||||
<ul class="settings-list">
|
||||
<slot></slot>
|
||||
</ul>
|
||||
<style>
|
||||
ul {
|
||||
ul.settings-list {
|
||||
list-style: none;
|
||||
width: 100%;
|
||||
border: 1px solid var(--settings-list-item-border);
|
||||
|
@ -10,7 +10,7 @@
|
|||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
ul {
|
||||
ul.settings-list {
|
||||
max-width: 80%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<li>
|
||||
<li class="settings-list-item">
|
||||
<a :href>
|
||||
{{#if icon}}
|
||||
<svg>
|
||||
|
@ -11,36 +11,36 @@
|
|||
</a>
|
||||
</li>
|
||||
<style>
|
||||
li {
|
||||
li.settings-list-item {
|
||||
border: 1px solid var(--settings-list-item-border);
|
||||
font-size: 1.3em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
a {
|
||||
.settings-list-item a {
|
||||
display: flex;
|
||||
padding: 20px;
|
||||
background: var(--settings-list-item-bg);
|
||||
}
|
||||
a, a:visited {
|
||||
.settings-list-item a, .settings-list-item a:visited {
|
||||
color: var(--settings-list-item-text);
|
||||
}
|
||||
a:hover {
|
||||
.settings-list-item a:hover {
|
||||
text-decoration: none;
|
||||
background: var(--settings-list-item-bg-hover);
|
||||
color: var(--settings-list-item-text-hover);
|
||||
}
|
||||
a:active {
|
||||
.settings-list-item a:active {
|
||||
background: var(--settings-list-item-bg-active);
|
||||
}
|
||||
svg {
|
||||
.settings-list-item svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: inline-block;
|
||||
margin-right: 20px;
|
||||
fill: var(--svg-fill);
|
||||
}
|
||||
.offset-for-icon {
|
||||
.settings-list-item .offset-for-icon {
|
||||
margin-left: 44px;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<nav>
|
||||
<nav class="settings-nav">
|
||||
<ul>
|
||||
{{#each navItems as navItem}}
|
||||
<li>
|
||||
|
@ -12,25 +12,25 @@
|
|||
</nav>
|
||||
|
||||
<style>
|
||||
ul {
|
||||
.settings-nav ul {
|
||||
margin: 5px 20px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
li {
|
||||
.settings-nav li {
|
||||
margin: 5px 0;
|
||||
font-size: 1em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
li::after {
|
||||
.settings-nav li::after {
|
||||
content: '>';
|
||||
margin: 0 15px;
|
||||
color: var(--anchor-text);
|
||||
}
|
||||
|
||||
li:last-child::after {
|
||||
.settings-nav li:last-child::after {
|
||||
content: '';
|
||||
margin-left: 0;
|
||||
font-size: 1em;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<a class='{{getCurrentClass(page, name)}}' aria-label='{{getAriaLabel(page, name, label)}}' href='{{href}}'>
|
||||
<a class='settings-nav-item {{getCurrentClass(page, name)}}' aria-label='{{getAriaLabel(page, name, label)}}' href='{{href}}'>
|
||||
{{label}}
|
||||
</a>
|
||||
<style>
|
||||
a {
|
||||
a.settings-nav-item {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
a.selected {
|
||||
a.settings-nav-item.selected {
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
<form class="add-new-instance" on:submit='onSubmit(event)' aria-labelledby="add-an-instance-h1">
|
||||
<label for="instanceInput">Instance:</label>
|
||||
<input type="text" id="instanceInput" bind:value='$instanceNameInSearch' placeholder=''>
|
||||
<input class="new-instance-input" type="text" id="instanceInput" bind:value='$instanceNameInSearch' placeholder=''>
|
||||
<button class="primary" type="submit" id="submitButton" disabled="{{!$instanceNameInSearch}}">Add instance</button>
|
||||
</form>
|
||||
|
||||
|
@ -27,12 +27,12 @@
|
|||
</Layout>
|
||||
<style>
|
||||
@media (max-width: 767px) {
|
||||
input {
|
||||
input.new-instance-input {
|
||||
max-width: 90%;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
input.new-instance-input {
|
||||
min-width: 50%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue