@yafnet/theme-kit 0.0.0-stage → 4.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +201 -0
- package/README.md +103 -2
- package/bin/yafnet-theme.js +409 -0
- package/email/bootstrap-email/bootstrap-email.scss +26 -0
- package/email/bootstrap-email/bootstrap-head.scss +169 -0
- package/email/bootstrap-email/layout.html.erb +12 -0
- package/email/bootstrap-email/scss/_helpers.scss +3 -0
- package/email/bootstrap-email/scss/_reboot_email.scss +54 -0
- package/email/bootstrap-email/scss/_reboot_head.scss +59 -0
- package/email/bootstrap-email/scss/_variables.scss +7 -0
- package/email/bootstrap-email/scss/components/_alert.scss +21 -0
- package/email/bootstrap-email/scss/components/_badge.scss +61 -0
- package/email/bootstrap-email/scss/components/_button.scss +47 -0
- package/email/bootstrap-email/scss/components/_card.scss +19 -0
- package/email/bootstrap-email/scss/components/_container.scss +18 -0
- package/email/bootstrap-email/scss/components/_grid.scss +43 -0
- package/email/bootstrap-email/scss/components/_hr.scss +8 -0
- package/email/bootstrap-email/scss/components/_image.scss +6 -0
- package/email/bootstrap-email/scss/components/_preview.scss +5 -0
- package/email/bootstrap-email/scss/components/_stack.scss +39 -0
- package/email/bootstrap-email/scss/components/_table.scss +137 -0
- package/email/bootstrap-email/scss/helpers/_functions.scss +29 -0
- package/email/bootstrap-email/scss/helpers/_mixins.scss +21 -0
- package/email/bootstrap-email/scss/helpers/_selectors_for_utils.scss +124 -0
- package/email/bootstrap-email/scss/utilities/_background.scss +5 -0
- package/email/bootstrap-email/scss/utilities/_border-radius.scss +21 -0
- package/email/bootstrap-email/scss/utilities/_border.scss +13 -0
- package/email/bootstrap-email/scss/utilities/_color.scss +9 -0
- package/email/bootstrap-email/scss/utilities/_display.scss +7 -0
- package/email/bootstrap-email/scss/utilities/_sizing.scss +35 -0
- package/email/bootstrap-email/scss/utilities/_spacing.scss +18 -0
- package/email/bootstrap-email/scss/utilities/_text-decoration.scss +9 -0
- package/email/bootstrap-email/scss/utilities/_typography.scss +56 -0
- package/email/bootstrap-email/scss/utilities/_valign.scss +5 -0
- package/email/bootstrap-email/scss/variables/_body.scss +2 -0
- package/email/bootstrap-email/scss/variables/_borders.scss +6 -0
- package/email/bootstrap-email/scss/variables/_buttons.scss +47 -0
- package/email/bootstrap-email/scss/variables/_colors.scss +161 -0
- package/email/bootstrap-email/scss/variables/_tables.scss +4 -0
- package/email/bootstrap-email/scss/variables/_typography.scss +26 -0
- package/email/bootstrap-email/scss/variables/_utilities.scss +154 -0
- package/email/bootstrap-email/templates/body.html +8 -0
- package/email/bootstrap-email/templates/button.html +9 -0
- package/email/bootstrap-email/templates/container.html +29 -0
- package/email/bootstrap-email/templates/div.html +3 -0
- package/email/bootstrap-email/templates/table-left.html +9 -0
- package/email/bootstrap-email/templates/table-to-tbody.html +5 -0
- package/email/bootstrap-email/templates/table-to-tr.html +7 -0
- package/email/bootstrap-email/templates/table.html +9 -0
- package/email/bootstrap-email/templates/td.html +3 -0
- package/email/bootstrap-email/templates/tr.html +5 -0
- package/email/prebuilt/brite/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/brite/EmailTemplate.html +116 -0
- package/email/prebuilt/cerulean/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/cerulean/EmailTemplate.html +116 -0
- package/email/prebuilt/cosmo/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/cosmo/EmailTemplate.html +116 -0
- package/email/prebuilt/cyborg/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/cyborg/EmailTemplate.html +116 -0
- package/email/prebuilt/darkly/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/darkly/EmailTemplate.html +116 -0
- package/email/prebuilt/flatly/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/flatly/EmailTemplate.html +116 -0
- package/email/prebuilt/journal/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/journal/EmailTemplate.html +116 -0
- package/email/prebuilt/litera/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/litera/EmailTemplate.html +116 -0
- package/email/prebuilt/lumen/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/lumen/EmailTemplate.html +116 -0
- package/email/prebuilt/lux/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/lux/EmailTemplate.html +116 -0
- package/email/prebuilt/materia/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/materia/EmailTemplate.html +116 -0
- package/email/prebuilt/minty/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/minty/EmailTemplate.html +116 -0
- package/email/prebuilt/morph/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/morph/EmailTemplate.html +116 -0
- package/email/prebuilt/pulse/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/pulse/EmailTemplate.html +116 -0
- package/email/prebuilt/quartz/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/quartz/EmailTemplate.html +116 -0
- package/email/prebuilt/sandstone/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/sandstone/EmailTemplate.html +116 -0
- package/email/prebuilt/simplex/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/simplex/EmailTemplate.html +116 -0
- package/email/prebuilt/sketchy/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/sketchy/EmailTemplate.html +116 -0
- package/email/prebuilt/slate/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/slate/EmailTemplate.html +116 -0
- package/email/prebuilt/solar/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/solar/EmailTemplate.html +116 -0
- package/email/prebuilt/spacelab/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/spacelab/EmailTemplate.html +116 -0
- package/email/prebuilt/superhero/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/superhero/EmailTemplate.html +116 -0
- package/email/prebuilt/united/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/united/EmailTemplate.html +116 -0
- package/email/prebuilt/vapor/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/vapor/EmailTemplate.html +116 -0
- package/email/prebuilt/yaf/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/yaf/EmailTemplate.html +116 -0
- package/email/prebuilt/yeti/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/yeti/EmailTemplate.html +116 -0
- package/email/prebuilt/zephyr/DigestTopicTemplate.html +57 -0
- package/email/prebuilt/zephyr/EmailTemplate.html +116 -0
- package/email/resources/DigestTopicTemplate.html +23 -0
- package/email/resources/EmailTemplate.html +27 -0
- package/package.json +41 -5
- package/scss/choices/bs-theme.scss +47 -0
- package/scss/choices/choices.scss +376 -0
- package/scss/forum/chat.scss +99 -0
- package/scss/netStack.scss +32 -0
- package/themes/brite/LICENSE.md +21 -0
- package/themes/brite/_bootswatch.scss +381 -0
- package/themes/brite/_variables.scss +236 -0
- package/themes/brite/bootstrap-email.scss +35 -0
- package/themes/brite/bootstrap-forum.scss +8 -0
- package/themes/brite/bootstrap_email-digest.json +5 -0
- package/themes/brite/bootstrap_email.json +4 -0
- package/themes/cerulean/LICENSE.md +21 -0
- package/themes/cerulean/_bootswatch.scss +116 -0
- package/themes/cerulean/_variables.scss +64 -0
- package/themes/cerulean/bootstrap-email.scss +35 -0
- package/themes/cerulean/bootstrap-forum.scss +8 -0
- package/themes/cerulean/bootstrap_email-digest.json +5 -0
- package/themes/cerulean/bootstrap_email.json +4 -0
- package/themes/cosmo/LICENSE.md +21 -0
- package/themes/cosmo/_bootswatch.scss +53 -0
- package/themes/cosmo/_variables.scss +73 -0
- package/themes/cosmo/bootstrap-email.scss +35 -0
- package/themes/cosmo/bootstrap-forum.scss +8 -0
- package/themes/cosmo/bootstrap_email-digest.json +5 -0
- package/themes/cosmo/bootstrap_email.json +4 -0
- package/themes/cyborg/LICENSE.md +21 -0
- package/themes/cyborg/_bootswatch.scss +146 -0
- package/themes/cyborg/_variables.scss +185 -0
- package/themes/cyborg/bootstrap-email.scss +35 -0
- package/themes/cyborg/bootstrap-forum.scss +8 -0
- package/themes/cyborg/bootstrap_email-digest.json +5 -0
- package/themes/cyborg/bootstrap_email.json +4 -0
- package/themes/darkly/LICENSE.md +21 -0
- package/themes/darkly/_bootswatch.scss +78 -0
- package/themes/darkly/_variables.scss +184 -0
- package/themes/darkly/bootstrap-email.scss +35 -0
- package/themes/darkly/bootstrap-forum.scss +8 -0
- package/themes/darkly/bootstrap_email-digest.json +5 -0
- package/themes/darkly/bootstrap_email.json +4 -0
- package/themes/flatly/LICENSE.md +21 -0
- package/themes/flatly/_bootswatch.scss +65 -0
- package/themes/flatly/_variables.scss +120 -0
- package/themes/flatly/bootstrap-email.scss +35 -0
- package/themes/flatly/bootstrap-forum.scss +8 -0
- package/themes/flatly/bootstrap_email-digest.json +5 -0
- package/themes/flatly/bootstrap_email.json +4 -0
- package/themes/journal/LICENSE.md +21 -0
- package/themes/journal/_bootswatch.scss +57 -0
- package/themes/journal/_variables.scss +64 -0
- package/themes/journal/bootstrap-email.scss +35 -0
- package/themes/journal/bootstrap-forum.scss +8 -0
- package/themes/journal/bootstrap_email-digest.json +5 -0
- package/themes/journal/bootstrap_email.json +4 -0
- package/themes/litera/LICENSE.md +21 -0
- package/themes/litera/_bootswatch.scss +98 -0
- package/themes/litera/_variables.scss +97 -0
- package/themes/litera/bootstrap-email.scss +35 -0
- package/themes/litera/bootstrap-forum.scss +8 -0
- package/themes/litera/bootstrap_email-digest.json +5 -0
- package/themes/litera/bootstrap_email.json +4 -0
- package/themes/lumen/LICENSE.md +21 -0
- package/themes/lumen/_bootswatch.scss +339 -0
- package/themes/lumen/_variables.scss +98 -0
- package/themes/lumen/bootstrap-email.scss +35 -0
- package/themes/lumen/bootstrap-forum.scss +8 -0
- package/themes/lumen/bootstrap_email-digest.json +5 -0
- package/themes/lumen/bootstrap_email.json +4 -0
- package/themes/lux/LICENSE.md +21 -0
- package/themes/lux/_bootswatch.scss +304 -0
- package/themes/lux/_variables.scss +124 -0
- package/themes/lux/bootstrap-email.scss +35 -0
- package/themes/lux/bootstrap-forum.scss +8 -0
- package/themes/lux/bootstrap_email-digest.json +5 -0
- package/themes/lux/bootstrap_email.json +4 -0
- package/themes/materia/LICENSE.md +21 -0
- package/themes/materia/_bootswatch.scss +654 -0
- package/themes/materia/_variables.scss +126 -0
- package/themes/materia/bootstrap-email.scss +35 -0
- package/themes/materia/bootstrap-forum.scss +8 -0
- package/themes/materia/bootstrap_email-digest.json +5 -0
- package/themes/materia/bootstrap_email.json +4 -0
- package/themes/minty/LICENSE.md +21 -0
- package/themes/minty/_bootswatch.scss +142 -0
- package/themes/minty/_variables.scss +100 -0
- package/themes/minty/bootstrap-email.scss +35 -0
- package/themes/minty/bootstrap-forum.scss +8 -0
- package/themes/minty/bootstrap_email-digest.json +5 -0
- package/themes/minty/bootstrap_email.json +4 -0
- package/themes/morph/LICENSE.md +21 -0
- package/themes/morph/_bootswatch.scss +562 -0
- package/themes/morph/_variables.scss +223 -0
- package/themes/morph/bootstrap-email.scss +35 -0
- package/themes/morph/bootstrap-forum.scss +8 -0
- package/themes/morph/bootstrap_email-digest.json +5 -0
- package/themes/morph/bootstrap_email.json +4 -0
- package/themes/pulse/LICENSE.md +21 -0
- package/themes/pulse/_bootswatch.scss +155 -0
- package/themes/pulse/_variables.scss +92 -0
- package/themes/pulse/bootstrap-email.scss +35 -0
- package/themes/pulse/bootstrap-forum.scss +8 -0
- package/themes/pulse/bootstrap_email-digest.json +5 -0
- package/themes/pulse/bootstrap_email.json +4 -0
- package/themes/quartz/_bootswatch.scss +297 -0
- package/themes/quartz/_variables.scss +226 -0
- package/themes/quartz/bootstrap-email.scss +35 -0
- package/themes/quartz/bootstrap-forum.scss +8 -0
- package/themes/quartz/bootstrap_email-digest.json +5 -0
- package/themes/quartz/bootstrap_email.json +4 -0
- package/themes/sandstone/LICENSE.md +21 -0
- package/themes/sandstone/_bootswatch.scss +242 -0
- package/themes/sandstone/_variables.scss +139 -0
- package/themes/sandstone/bootstrap-email.scss +35 -0
- package/themes/sandstone/bootstrap-forum.scss +8 -0
- package/themes/sandstone/bootstrap_email-digest.json +5 -0
- package/themes/sandstone/bootstrap_email.json +4 -0
- package/themes/simplex/LICENSE.md +21 -0
- package/themes/simplex/_bootswatch.scss +150 -0
- package/themes/simplex/_variables.scss +105 -0
- package/themes/simplex/bootstrap-email.scss +35 -0
- package/themes/simplex/bootstrap-forum.scss +8 -0
- package/themes/simplex/bootstrap_email-digest.json +5 -0
- package/themes/simplex/bootstrap_email.json +4 -0
- package/themes/sketchy/LICENSE.md +21 -0
- package/themes/sketchy/_bootswatch.scss +557 -0
- package/themes/sketchy/_variables.scss +156 -0
- package/themes/sketchy/bootstrap-email.scss +35 -0
- package/themes/sketchy/bootstrap-forum.scss +8 -0
- package/themes/sketchy/bootstrap_email-digest.json +5 -0
- package/themes/sketchy/bootstrap_email.json +4 -0
- package/themes/slate/LICENSE.md +21 -0
- package/themes/slate/_bootswatch.scss +340 -0
- package/themes/slate/_variables.scss +187 -0
- package/themes/slate/bootstrap-email.scss +35 -0
- package/themes/slate/bootstrap-forum.scss +8 -0
- package/themes/slate/bootstrap_email-digest.json +5 -0
- package/themes/slate/bootstrap_email.json +4 -0
- package/themes/solar/LICENSE.md +21 -0
- package/themes/solar/_bootswatch.scss +66 -0
- package/themes/solar/_variables.scss +193 -0
- package/themes/solar/bootstrap-email.scss +35 -0
- package/themes/solar/bootstrap-forum.scss +8 -0
- package/themes/solar/bootstrap_email-digest.json +5 -0
- package/themes/solar/bootstrap_email.json +4 -0
- package/themes/spacelab/LICENSE.md +21 -0
- package/themes/spacelab/_bootswatch.scss +107 -0
- package/themes/spacelab/_variables.scss +65 -0
- package/themes/spacelab/bootstrap-email.scss +35 -0
- package/themes/spacelab/bootstrap-forum.scss +8 -0
- package/themes/spacelab/bootstrap_email-digest.json +5 -0
- package/themes/spacelab/bootstrap_email.json +4 -0
- package/themes/superhero/LICENSE.md +21 -0
- package/themes/superhero/_bootswatch.scss +153 -0
- package/themes/superhero/_variables.scss +202 -0
- package/themes/superhero/bootstrap-email.scss +35 -0
- package/themes/superhero/bootstrap-forum.scss +8 -0
- package/themes/superhero/bootstrap_email-digest.json +5 -0
- package/themes/superhero/bootstrap_email.json +4 -0
- package/themes/united/LICENSE.md +21 -0
- package/themes/united/_bootswatch.scss +30 -0
- package/themes/united/_variables.scss +56 -0
- package/themes/united/bootstrap-email.scss +35 -0
- package/themes/united/bootstrap-forum.scss +8 -0
- package/themes/united/bootstrap_email-digest.json +5 -0
- package/themes/united/bootstrap_email.json +4 -0
- package/themes/vapor/_bootswatch.scss +337 -0
- package/themes/vapor/_variables.scss +176 -0
- package/themes/vapor/bootstrap-email.scss +35 -0
- package/themes/vapor/bootstrap-forum.scss +8 -0
- package/themes/vapor/bootstrap_email-digest.json +5 -0
- package/themes/vapor/bootstrap_email.json +4 -0
- package/themes/yaf/_variables-email.scss +39 -0
- package/themes/yaf/_variables.scss +10 -0
- package/themes/yaf/bootstrap-email.scss +35 -0
- package/themes/yaf/bootstrap-forum.scss +8 -0
- package/themes/yaf/bootstrap_email-digest.json +5 -0
- package/themes/yaf/bootstrap_email.json +4 -0
- package/themes/yeti/LICENSE.md +21 -0
- package/themes/yeti/_bootswatch.scss +344 -0
- package/themes/yeti/_variables.scss +107 -0
- package/themes/yeti/bootstrap-email.scss +35 -0
- package/themes/yeti/bootstrap-forum.scss +8 -0
- package/themes/yeti/bootstrap_email-digest.json +5 -0
- package/themes/yeti/bootstrap_email.json +4 -0
- package/themes/zephyr/_bootswatch.scss +221 -0
- package/themes/zephyr/_variables.scss +157 -0
- package/themes/zephyr/bootstrap-email.scss +35 -0
- package/themes/zephyr/bootstrap-forum.scss +8 -0
- package/themes/zephyr/bootstrap_email-digest.json +5 -0
- package/themes/zephyr/bootstrap_email.json +4 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* yafnet-theme: creates and builds custom themes for YetAnotherForum.NET.
|
|
5
|
+
*
|
|
6
|
+
* The kit contains the theme sources and the forum styles of the YAF.NET version with the same version number,
|
|
7
|
+
* so a theme can be built without the YAF.NET source code.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const { spawnSync } = require('node:child_process');
|
|
11
|
+
const fs = require('node:fs');
|
|
12
|
+
const os = require('node:os');
|
|
13
|
+
const path = require('node:path');
|
|
14
|
+
const { parseArgs } = require('node:util');
|
|
15
|
+
|
|
16
|
+
const kit = path.resolve(__dirname, '..');
|
|
17
|
+
const kitPackage = require('../package.json');
|
|
18
|
+
|
|
19
|
+
const kitThemes = path.join(kit, 'themes');
|
|
20
|
+
const kitScss = path.join(kit, 'scss');
|
|
21
|
+
const kitEmail = path.join(kit, 'email');
|
|
22
|
+
|
|
23
|
+
const themeConfigFile = 'yafnet-theme.json';
|
|
24
|
+
|
|
25
|
+
const usage = `yafnet-theme ${kitPackage.version} - custom themes for YetAnotherForum.NET ${kitPackage.version}
|
|
26
|
+
|
|
27
|
+
Usage:
|
|
28
|
+
yafnet-theme list list the themes of the kit, to start from
|
|
29
|
+
yafnet-theme new <name> [--from <theme>] create the theme <name> in the themes folder (default from: yaf)
|
|
30
|
+
yafnet-theme build [<name>...] build all themes in the themes folder (or the named ones)
|
|
31
|
+
yafnet-theme watch [<name>...] build the css again when a file in the themes folder changes
|
|
32
|
+
|
|
33
|
+
Options:
|
|
34
|
+
--themes <folder> folder with the theme sources (default: themes)
|
|
35
|
+
--out <folder> output folder (default: dist), e.g. the wwwroot/css/themes folder of a forum
|
|
36
|
+
--from <theme> new: the theme of the kit to start from (default: yaf)
|
|
37
|
+
--no-email build: only the css, not the email templates
|
|
38
|
+
-v, --version show the version
|
|
39
|
+
-h, --help show this help
|
|
40
|
+
|
|
41
|
+
A built theme is a folder <out>/<name> with bootstrap-forum.min.css, EmailTemplate.html and
|
|
42
|
+
DigestTopicTemplate.html. Copy it to the wwwroot/css/themes folder of the forum.
|
|
43
|
+
|
|
44
|
+
The email templates are built with the .NET tool bootstrap-email
|
|
45
|
+
(dotnet tool install --global BootstrapEmail.Net.Cli). Without it the prebuilt email templates of the
|
|
46
|
+
theme you started from are used.`;
|
|
47
|
+
|
|
48
|
+
const sassOptions = {
|
|
49
|
+
silenceDeprecations: ['color-functions', 'global-builtin', 'import', 'legacy-js-api', 'if-function'],
|
|
50
|
+
// the themes import "bootstrap/scss/bootstrap" and the forum styles ("forum/chat.scss", ...) from here
|
|
51
|
+
loadPaths: [path.dirname(path.dirname(require.resolve('bootstrap/package.json'))), kitScss]
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
class UserError extends Error {}
|
|
55
|
+
|
|
56
|
+
const isThemeFolder = folder => fs.existsSync(path.join(folder, 'bootstrap-forum.scss'));
|
|
57
|
+
|
|
58
|
+
function listFolders(folder) {
|
|
59
|
+
return fs.readdirSync(folder, { withFileTypes: true })
|
|
60
|
+
.filter(entry => entry.isDirectory())
|
|
61
|
+
.map(entry => entry.name)
|
|
62
|
+
.sort();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function kitThemeNames() {
|
|
66
|
+
return listFolders(kitThemes);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The themes to build: the named ones, or every theme folder in the themes folder.
|
|
71
|
+
*/
|
|
72
|
+
function selectThemes(themesFolder, names) {
|
|
73
|
+
if (!fs.existsSync(themesFolder)) {
|
|
74
|
+
throw new UserError(`The themes folder ${themesFolder} doesn't exist. Create a theme with: yafnet-theme new <name>`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (names.length > 0) {
|
|
78
|
+
for (const name of names) {
|
|
79
|
+
if (!isThemeFolder(path.join(themesFolder, name))) {
|
|
80
|
+
throw new UserError(`${path.join(themesFolder, name)} is not a theme (bootstrap-forum.scss is missing).`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return names;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const themes = listFolders(themesFolder).filter(name => isThemeFolder(path.join(themesFolder, name)));
|
|
88
|
+
|
|
89
|
+
if (themes.length === 0) {
|
|
90
|
+
throw new UserError(`No themes found in ${themesFolder}. Create a theme with: yafnet-theme new <name>`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return themes;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The theme of the kit a theme was created from, its prebuilt email templates are used without bootstrap-email.
|
|
98
|
+
*/
|
|
99
|
+
function baseTheme(themeFolder, name) {
|
|
100
|
+
const configFile = path.join(themeFolder, themeConfigFile);
|
|
101
|
+
|
|
102
|
+
if (fs.existsSync(configFile)) {
|
|
103
|
+
const { from } = JSON.parse(fs.readFileSync(configFile, 'utf8'));
|
|
104
|
+
|
|
105
|
+
if (from && fs.existsSync(path.join(kitEmail, 'prebuilt', from))) {
|
|
106
|
+
return from;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return fs.existsSync(path.join(kitEmail, 'prebuilt', name)) ? name : 'yaf';
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* The theme name in the paths of the email sass files and the bootstrap-email configs.
|
|
115
|
+
*/
|
|
116
|
+
function renameEmailPaths(themeFolder, name) {
|
|
117
|
+
const replacements = [
|
|
118
|
+
['bootstrap-email.scss', /(@import\s+['"]\.\.\/themes\/)[^/'"]+\//g],
|
|
119
|
+
['bootstrap_email.json', /("sass_email_location"\s*:\s*"[^"]*themes\/)[^/"]+\//gi],
|
|
120
|
+
['bootstrap_email-digest.json', /("sass_email_location"\s*:\s*"[^"]*themes\/)[^/"]+\//gi]
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
for (const [file, pattern] of replacements) {
|
|
124
|
+
const fullName = path.join(themeFolder, file);
|
|
125
|
+
|
|
126
|
+
if (fs.existsSync(fullName)) {
|
|
127
|
+
fs.writeFileSync(fullName, fs.readFileSync(fullName, 'utf8').replace(pattern, `$1${name}/`));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function newTheme(name, { themes, from }) {
|
|
133
|
+
if (!name) {
|
|
134
|
+
throw new UserError('Missing theme name: yafnet-theme new <name> [--from <theme>]');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (!/^[a-z0-9][a-z0-9_-]*$/i.test(name)) {
|
|
138
|
+
throw new UserError(`"${name}" is not a valid theme name, use letters, digits, - and _ only.`);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (!kitThemeNames().includes(from)) {
|
|
142
|
+
throw new UserError(`The kit has no theme "${from}". Available: ${kitThemeNames().join(', ')}`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const destination = path.join(themes, name);
|
|
146
|
+
|
|
147
|
+
if (fs.existsSync(destination)) {
|
|
148
|
+
throw new UserError(`${destination} already exists.`);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
fs.cpSync(path.join(kitThemes, from), destination, { recursive: true });
|
|
152
|
+
|
|
153
|
+
renameEmailPaths(destination, name);
|
|
154
|
+
|
|
155
|
+
fs.writeFileSync(
|
|
156
|
+
path.join(destination, themeConfigFile),
|
|
157
|
+
`${JSON.stringify({ from, kitVersion: kitPackage.version }, null, '\t')}\n`);
|
|
158
|
+
|
|
159
|
+
console.log(`Created ${destination} from the theme ${from}.
|
|
160
|
+
|
|
161
|
+
Next steps:
|
|
162
|
+
1. Change the variables in ${path.join(destination, '_variables.scss')}
|
|
163
|
+
(Bootstrap variables, e.g. $primary, $font-family-sans-serif, $border-radius)
|
|
164
|
+
2. Build the theme: npx yafnet-theme build ${name}
|
|
165
|
+
3. Copy the folder dist/${name} to the wwwroot/css/themes folder of your forum`);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async function buildCss(themesFolder, name, out) {
|
|
169
|
+
const sass = require('sass');
|
|
170
|
+
const postcss = require('postcss');
|
|
171
|
+
const autoprefixer = require('autoprefixer');
|
|
172
|
+
const CleanCSS = require('clean-css');
|
|
173
|
+
|
|
174
|
+
const source = path.join(themesFolder, name, 'bootstrap-forum.scss');
|
|
175
|
+
const destination = path.join(out, name, 'bootstrap-forum.min.css');
|
|
176
|
+
|
|
177
|
+
// themes created in the source of YAF.NET 4.0.10 and older import Bootstrap and the forum styles with relative paths
|
|
178
|
+
if (/@import\s+["'](\.\.\/)+(node_modules\/bootstrap|forum\/|choices\/|netStack)/.test(fs.readFileSync(source, 'utf8'))) {
|
|
179
|
+
throw new UserError(`${source} imports Bootstrap or the forum styles with a relative path (../../...).
|
|
180
|
+
Change these imports to:
|
|
181
|
+
@import "bootstrap/scss/bootstrap";
|
|
182
|
+
@import "forum/chat.scss";
|
|
183
|
+
@import "choices/bs-theme.scss";
|
|
184
|
+
@import "netStack.scss";`);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const compiled = await sass.compileAsync(source, sassOptions);
|
|
188
|
+
const prefixed = await postcss([autoprefixer({ overrideBrowserslist: 'defaults' })])
|
|
189
|
+
.process(compiled.css, { from: destination, to: destination, map: false });
|
|
190
|
+
|
|
191
|
+
for (const warning of prefixed.warnings()) {
|
|
192
|
+
console.warn(`${name}: ${warning}`);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
fs.mkdirSync(path.dirname(destination), { recursive: true });
|
|
196
|
+
fs.writeFileSync(destination, prefixed.css);
|
|
197
|
+
|
|
198
|
+
const minified = new CleanCSS().minify([destination]);
|
|
199
|
+
|
|
200
|
+
if (minified.errors.length > 0) {
|
|
201
|
+
throw new Error(`${destination}: ${minified.errors.join(', ')}`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// the Bootswatch themes import their web fonts from Google Fonts, these imports are kept on purpose
|
|
205
|
+
for (const warning of minified.warnings.filter(w => !w.startsWith('Skipping remote @import'))) {
|
|
206
|
+
console.warn(`${name}: ${warning}`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
fs.writeFileSync(destination, minified.styles);
|
|
210
|
+
|
|
211
|
+
const license = path.join(themesFolder, name, 'LICENSE.md');
|
|
212
|
+
|
|
213
|
+
if (fs.existsSync(license)) {
|
|
214
|
+
fs.copyFileSync(license, path.join(out, name, 'LICENSE.md'));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
console.log(`${destination} (${Math.round(minified.styles.length / 1024)} KB)`);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* The command of the bootstrap-email tool: the global tool, or the local tool of a dotnet tool manifest.
|
|
222
|
+
*/
|
|
223
|
+
function findBootstrapEmail() {
|
|
224
|
+
for (const [command, args] of [['bootstrap-email', []], ['dotnet', ['bootstrap-email']]]) {
|
|
225
|
+
const result = spawnSync(command, [...args, '--version'], { encoding: 'utf8' });
|
|
226
|
+
|
|
227
|
+
if (!result.error && result.status === 0) {
|
|
228
|
+
return { command, args, version: result.stdout.trim() };
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const emailTemplates = [
|
|
236
|
+
['EmailTemplate.html', {}],
|
|
237
|
+
['DigestTopicTemplate.html', { CompileOnlyBody: true }]
|
|
238
|
+
];
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* bootstrap-email resolves the theme import (../themes/[name]/variables) from its sass folder, so the
|
|
242
|
+
* theme is compiled in a temporary folder with the same layout as the YAF.NET source.
|
|
243
|
+
*/
|
|
244
|
+
function buildEmailTemplates(themesFolder, name, out, tool) {
|
|
245
|
+
const work = fs.mkdtempSync(path.join(os.tmpdir(), 'yafnet-theme-'));
|
|
246
|
+
const slash = folder => `${folder.replaceAll('\\', '/')}/`;
|
|
247
|
+
|
|
248
|
+
try {
|
|
249
|
+
const sassFolder = path.join(work, 'bootstrap-email');
|
|
250
|
+
const themeFolder = path.join(work, 'themes', name);
|
|
251
|
+
|
|
252
|
+
fs.cpSync(path.join(kitEmail, 'bootstrap-email'), sassFolder, { recursive: true });
|
|
253
|
+
fs.cpSync(path.join(themesFolder, name), themeFolder, { recursive: true });
|
|
254
|
+
renameEmailPaths(themeFolder, name);
|
|
255
|
+
|
|
256
|
+
for (const [template, options] of emailTemplates) {
|
|
257
|
+
const config = path.join(work, `${template}.json`);
|
|
258
|
+
const destination = path.join(out, name, template);
|
|
259
|
+
|
|
260
|
+
fs.writeFileSync(config, JSON.stringify({
|
|
261
|
+
sass_email_location: slash(themeFolder),
|
|
262
|
+
sass_location: slash(sassFolder),
|
|
263
|
+
...options
|
|
264
|
+
}));
|
|
265
|
+
|
|
266
|
+
// bootstrap-email writes its .sass-cache into the working folder
|
|
267
|
+
const result = spawnSync(
|
|
268
|
+
tool.command,
|
|
269
|
+
[...tool.args, '-f', path.join(kitEmail, 'resources', template), '-d', destination, '-c', config],
|
|
270
|
+
{ cwd: work, encoding: 'utf8' });
|
|
271
|
+
|
|
272
|
+
if (result.error || result.status !== 0 || !fs.existsSync(destination)) {
|
|
273
|
+
const output = `${result.stdout ?? ''}${result.stderr ?? ''}`.split('\n').slice(0, 5).join('\n');
|
|
274
|
+
const hint = tool.version.startsWith('1.')
|
|
275
|
+
? `\nbootstrap-email ${tool.version} can't be used, update it: dotnet tool update --global BootstrapEmail.Net.Cli`
|
|
276
|
+
: '';
|
|
277
|
+
|
|
278
|
+
throw new UserError(`bootstrap-email failed for ${name}/${template}:\n${result.error?.message ?? output}${hint}`);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
console.log(destination);
|
|
282
|
+
}
|
|
283
|
+
} finally {
|
|
284
|
+
fs.rmSync(work, { recursive: true, force: true });
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function copyPrebuiltEmailTemplates(themesFolder, name, out) {
|
|
289
|
+
const from = baseTheme(path.join(themesFolder, name), name);
|
|
290
|
+
|
|
291
|
+
for (const [template] of emailTemplates) {
|
|
292
|
+
fs.copyFileSync(path.join(kitEmail, 'prebuilt', from, template), path.join(out, name, template));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
console.log(`${path.join(out, name)}: email templates of the theme ${from} copied`);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async function build(names, { themes, out, 'no-email': noEmail }) {
|
|
299
|
+
const selected = selectThemes(themes, names);
|
|
300
|
+
|
|
301
|
+
for (const name of selected) {
|
|
302
|
+
await buildCss(themes, name, out);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (noEmail) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const tool = findBootstrapEmail();
|
|
310
|
+
|
|
311
|
+
if (!tool) {
|
|
312
|
+
console.warn(`
|
|
313
|
+
bootstrap-email was not found, the prebuilt email templates are used instead: they have the colors of the
|
|
314
|
+
theme you started from. To build the email templates with the colors of your theme, install the .NET SDK and
|
|
315
|
+
dotnet tool install --global BootstrapEmail.Net.Cli
|
|
316
|
+
`);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
for (const name of selected) {
|
|
320
|
+
if (tool) {
|
|
321
|
+
buildEmailTemplates(themes, name, out, tool);
|
|
322
|
+
} else {
|
|
323
|
+
copyPrebuiltEmailTemplates(themes, name, out);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async function watch(names, options) {
|
|
329
|
+
const selected = selectThemes(options.themes, names);
|
|
330
|
+
const pending = new Set();
|
|
331
|
+
let timer;
|
|
332
|
+
|
|
333
|
+
async function rebuild() {
|
|
334
|
+
const themes = [...pending];
|
|
335
|
+
pending.clear();
|
|
336
|
+
|
|
337
|
+
for (const name of themes) {
|
|
338
|
+
try {
|
|
339
|
+
await buildCss(options.themes, name, options.out);
|
|
340
|
+
} catch (error) {
|
|
341
|
+
console.error(error.formatted ?? error.message ?? error);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
await build(selected, { ...options, 'no-email': true });
|
|
347
|
+
|
|
348
|
+
fs.watch(options.themes, { recursive: true }, (_event, file) => {
|
|
349
|
+
const name = file?.split(/[\\/]/)[0];
|
|
350
|
+
|
|
351
|
+
if (name && selected.includes(name)) {
|
|
352
|
+
pending.add(name);
|
|
353
|
+
clearTimeout(timer);
|
|
354
|
+
timer = setTimeout(rebuild, 200);
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
console.log(`Watching ${options.themes} for changes of ${selected.join(', ')} (Ctrl+C to stop)`);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
async function main() {
|
|
362
|
+
const { values, positionals } = parseArgs({
|
|
363
|
+
allowPositionals: true,
|
|
364
|
+
options: {
|
|
365
|
+
themes: { type: 'string', default: 'themes' },
|
|
366
|
+
out: { type: 'string', default: 'dist' },
|
|
367
|
+
from: { type: 'string', default: 'yaf' },
|
|
368
|
+
'no-email': { type: 'boolean', default: false },
|
|
369
|
+
version: { type: 'boolean', short: 'v' },
|
|
370
|
+
help: { type: 'boolean', short: 'h' }
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
const [command, ...args] = positionals;
|
|
375
|
+
|
|
376
|
+
if (values.version) {
|
|
377
|
+
console.log(kitPackage.version);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
if (values.help || !command) {
|
|
382
|
+
console.log(usage);
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
const options = { ...values, themes: path.resolve(values.themes), out: path.resolve(values.out) };
|
|
387
|
+
|
|
388
|
+
switch (command) {
|
|
389
|
+
case 'list':
|
|
390
|
+
console.log(kitThemeNames().join('\n'));
|
|
391
|
+
break;
|
|
392
|
+
case 'new':
|
|
393
|
+
newTheme(args[0], options);
|
|
394
|
+
break;
|
|
395
|
+
case 'build':
|
|
396
|
+
await build(args, options);
|
|
397
|
+
break;
|
|
398
|
+
case 'watch':
|
|
399
|
+
await watch(args, options);
|
|
400
|
+
break;
|
|
401
|
+
default:
|
|
402
|
+
throw new UserError(`Unknown command "${command}".\n\n${usage}`);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
main().catch(error => {
|
|
407
|
+
console.error(error instanceof UserError ? error.message : (error.formatted ?? error.message ?? error));
|
|
408
|
+
process.exitCode = 1;
|
|
409
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
@import 'scss/helpers';
|
|
2
|
+
@import 'scss/variables';
|
|
3
|
+
@import 'scss/reboot_email';
|
|
4
|
+
|
|
5
|
+
@import 'scss/components/alert';
|
|
6
|
+
@import 'scss/components/badge';
|
|
7
|
+
@import 'scss/components/button';
|
|
8
|
+
@import 'scss/components/card';
|
|
9
|
+
@import 'scss/components/container';
|
|
10
|
+
@import 'scss/components/grid';
|
|
11
|
+
@import 'scss/components/hr';
|
|
12
|
+
@import 'scss/components/image';
|
|
13
|
+
@import 'scss/components/preview';
|
|
14
|
+
@import 'scss/components/table';
|
|
15
|
+
@import 'scss/components/stack';
|
|
16
|
+
|
|
17
|
+
@import 'scss/utilities/background';
|
|
18
|
+
@import 'scss/utilities/border';
|
|
19
|
+
@import 'scss/utilities/border-radius';
|
|
20
|
+
@import 'scss/utilities/color';
|
|
21
|
+
@import 'scss/utilities/display';
|
|
22
|
+
@import 'scss/utilities/sizing';
|
|
23
|
+
@import 'scss/utilities/spacing';
|
|
24
|
+
@import 'scss/utilities/text-decoration';
|
|
25
|
+
@import 'scss/utilities/typography';
|
|
26
|
+
@import 'scss/utilities/valign';
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
//
|
|
2
|
+
// This file will be placed in the head of the document and will not be inlined
|
|
3
|
+
//
|
|
4
|
+
@import 'scss/helpers';
|
|
5
|
+
@import 'scss/variables';
|
|
6
|
+
|
|
7
|
+
@if $font-faces {
|
|
8
|
+
@each $font-face in $font-faces {
|
|
9
|
+
// @font-face has the least quirks in email clients: https://www.litmus.com/blog/the-ultimate-guide-to-web-fonts
|
|
10
|
+
@font-face {
|
|
11
|
+
font-family: map-get($font-face, "font-family");
|
|
12
|
+
font-style: map-get($font-face, "font-style");
|
|
13
|
+
font-weight: map-get($font-face, "font-weight");
|
|
14
|
+
src: map-get($font-face, "src");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@import 'scss/reboot_head';
|
|
20
|
+
|
|
21
|
+
/*! allow_purge_after */
|
|
22
|
+
|
|
23
|
+
@media screen and (max-width: 600px) {
|
|
24
|
+
// Row Gap
|
|
25
|
+
@each $space, $value in $spacers {
|
|
26
|
+
.gap-#{$space}.row,
|
|
27
|
+
.gap-x-#{$space}.row {
|
|
28
|
+
margin-right: -1 * $value !important;
|
|
29
|
+
& > table > tbody > tr > td {
|
|
30
|
+
padding-right: $value !important;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
.gap-#{$space}.row,
|
|
34
|
+
.gap-y-#{$space}.row {
|
|
35
|
+
margin-bottom: -1 * $value !important;
|
|
36
|
+
& > table > tbody > tr > td {
|
|
37
|
+
padding-bottom: $value !important;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
.row-responsive.row {
|
|
42
|
+
margin-right: 0 !important;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Stack Gap
|
|
46
|
+
@each $space, $value in $spacers {
|
|
47
|
+
table.gap-lg-#{$space}.stack-x > tbody > tr > td {
|
|
48
|
+
padding-right: 0 !important;
|
|
49
|
+
}
|
|
50
|
+
table.gap-lg-#{$space}.stack-y > tbody > tr > td {
|
|
51
|
+
padding-bottom: 0 !important;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
@each $space, $value in $spacers {
|
|
55
|
+
table.gap-#{$space}.stack-x > tbody > tr > td {
|
|
56
|
+
padding-right: $value !important;
|
|
57
|
+
}
|
|
58
|
+
table.gap-#{$space}.stack-y > tbody > tr > td {
|
|
59
|
+
padding-bottom: $value !important;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Grid
|
|
64
|
+
@each $key, $value in $grid-cols {
|
|
65
|
+
td.col-lg-#{$key} {
|
|
66
|
+
display: block;
|
|
67
|
+
width: 100% !important;
|
|
68
|
+
padding-left: 0 !important;
|
|
69
|
+
padding-right: 0 !important;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
td.col-lg {
|
|
73
|
+
display: block;
|
|
74
|
+
width: 100% !important;
|
|
75
|
+
padding-left: 0 !important;
|
|
76
|
+
padding-right: 0 !important;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Display
|
|
80
|
+
@each $display in $display-type {
|
|
81
|
+
.d-lg-#{$display} {
|
|
82
|
+
display: unset !important;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
@each $display in $display-type {
|
|
86
|
+
.d-#{$display} {
|
|
87
|
+
display: $display !important;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Sizing Max Width / Height
|
|
92
|
+
@each $name, $property in $sizing-types {
|
|
93
|
+
@include sizing-util('.max-#{$name}-lg-full') {
|
|
94
|
+
max-#{$property}: unset !important;
|
|
95
|
+
#{$property}: auto !important;
|
|
96
|
+
}
|
|
97
|
+
@each $size, $value in $sizing {
|
|
98
|
+
@include sizing-util('.max-#{$name}-lg-#{$size}') {
|
|
99
|
+
max-#{$property}: unset !important;
|
|
100
|
+
#{$property}: auto !important;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
@each $name, $property in $sizing-types {
|
|
105
|
+
@include sizing-util('.max-#{$name}-full') {
|
|
106
|
+
max-#{$property}: 100% !important;
|
|
107
|
+
#{$property}: 100% !important;
|
|
108
|
+
}
|
|
109
|
+
@each $size, $value in $sizing {
|
|
110
|
+
@include sizing-util('.max-#{$name}-#{$size}') {
|
|
111
|
+
max-#{$property}: $value !important;
|
|
112
|
+
#{$property}: 100% !important;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Sizing Width / Height
|
|
118
|
+
@each $name, $property in $sizing-types {
|
|
119
|
+
@include sizing-util('.#{$name}-lg-full') {
|
|
120
|
+
#{$property}: auto !important;
|
|
121
|
+
}
|
|
122
|
+
@include sizing-util('.#{$name}-lg-auto') {
|
|
123
|
+
#{$property}: auto !important;
|
|
124
|
+
}
|
|
125
|
+
@each $size, $value in $sizing {
|
|
126
|
+
@include sizing-util('.#{$name}-lg-#{$size}') {
|
|
127
|
+
#{$property}: auto !important;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
@each $name, $property in $sizing-types {
|
|
132
|
+
@include sizing-util('.#{$name}-full') {
|
|
133
|
+
#{$property}: 100% !important;
|
|
134
|
+
}
|
|
135
|
+
@include sizing-util('.#{$name}-auto') {
|
|
136
|
+
#{$property}: auto !important;
|
|
137
|
+
}
|
|
138
|
+
@each $size, $value in $sizing {
|
|
139
|
+
@include sizing-util('.#{$name}-#{$size}') {
|
|
140
|
+
#{$property}: $value !important;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Spacing
|
|
146
|
+
// Reset large padding to 0 on small device
|
|
147
|
+
@each $size, $value in $spacers {
|
|
148
|
+
@include padding-group('lg-', $size, unquote('0 !important'));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Set proper padding on small devices
|
|
152
|
+
@each $size, $value in $spacers {
|
|
153
|
+
@include padding-group('', $size, unquote('#{$value} !important'));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Spacers
|
|
157
|
+
@include spacer-util('*[class*=s-lg-]') {
|
|
158
|
+
font-size: 0 !important;
|
|
159
|
+
line-height: 0 !important;
|
|
160
|
+
height: 0 !important;
|
|
161
|
+
}
|
|
162
|
+
@each $size, $value in $spacers {
|
|
163
|
+
@include spacer-util('.s-#{$size}') {
|
|
164
|
+
font-size: $value !important;
|
|
165
|
+
line-height: $value !important;
|
|
166
|
+
height: $value !important;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
5
|
+
<meta name="x-apple-disable-message-reformatting">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
7
|
+
<meta name="format-detection" content="telephone=no, date=no, address=no, email=no">
|
|
8
|
+
</head>
|
|
9
|
+
<body style="" bgcolor="">
|
|
10
|
+
<%= contents %>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Based on https://templates.mailchimp.com/development/css/reset-styles/ by Mailchimp
|
|
2
|
+
body, .body {
|
|
3
|
+
margin: 0;
|
|
4
|
+
padding: 0;
|
|
5
|
+
border: 0;
|
|
6
|
+
outline: 0;
|
|
7
|
+
width: 100%;
|
|
8
|
+
min-width: 100%;
|
|
9
|
+
height: 100%;
|
|
10
|
+
-webkit-text-size-adjust: 100%;
|
|
11
|
+
-ms-text-size-adjust: 100%;
|
|
12
|
+
font-family: $font-family-base;
|
|
13
|
+
line-height: $line-height-base * $font-size-base;
|
|
14
|
+
font-weight: $font-weight-base;
|
|
15
|
+
font-size: $font-size-base;
|
|
16
|
+
-moz-box-sizing: border-box;
|
|
17
|
+
-webkit-box-sizing: border-box;
|
|
18
|
+
box-sizing: border-box;
|
|
19
|
+
background-color: $body-bg;
|
|
20
|
+
color: $body-color;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
img {
|
|
24
|
+
border: 0 none;
|
|
25
|
+
height: auto;
|
|
26
|
+
line-height: 100%;
|
|
27
|
+
outline: none;
|
|
28
|
+
text-decoration: none;
|
|
29
|
+
display: block;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
table {
|
|
33
|
+
-premailer-border: 0;
|
|
34
|
+
-premailer-cellpadding: 0;
|
|
35
|
+
-premailer-cellspacing: 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// to fix centering in yahoo
|
|
39
|
+
table[align=center] {
|
|
40
|
+
margin: 0 auto;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
th,
|
|
44
|
+
td,
|
|
45
|
+
p {
|
|
46
|
+
text-align: left;
|
|
47
|
+
line-height: $line-height-base * $font-size-base;
|
|
48
|
+
font-size: $font-size-base;
|
|
49
|
+
margin: 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
a {
|
|
53
|
+
color: $link-color;
|
|
54
|
+
}
|