diff --git a/packages/cli/bin/resolve-config.js b/packages/cli/bin/resolve-config.js
index f34c5e083..f29918baa 100644
--- a/packages/cli/bin/resolve-config.js
+++ b/packages/cli/bin/resolve-config.js
@@ -4,6 +4,9 @@ const path = require('path');
const error = require('./utils').error;
const readJsonAsync = require('./utils').readJsonAsync;
const wrapAsync = require('./utils').wrapAsync;
+const {
+ findPatternLabConfig,
+} = require('@pattern-lab/core/src/lib/utils/find-config-file');
/**
* @func resolveConfig
@@ -30,8 +33,12 @@ function resolveConfig(configPath) {
* 2. Read the config file
*/
try {
- const absoluteConfigPath = path.resolve(configPath); // 1
- return yield readJsonAsync(absoluteConfigPath); // 2
+ if (configPath) {
+ const absoluteConfigPath = path.resolve(configPath); // 1
+ return yield findPatternLabConfig(absoluteConfigPath);
+ } else {
+ return yield findPatternLabConfig();
+ }
} catch (err) {
error(
'resolveConfig: Got an error during parsing your Pattern Lab config. Please make sure your config file exists.'
diff --git a/packages/core/package.json b/packages/core/package.json
index 802005859..8958cd6f3 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -4,6 +4,7 @@
"version": "5.12.0",
"main": "./src/index.js",
"dependencies": {
+ "cosmiconfig": "^5.2.0",
"@pattern-lab/engine-mustache": "^5.12.0",
"@pattern-lab/live-server": "^5.10.1",
"chalk": "1.1.3",
@@ -21,6 +22,7 @@
"update-notifier": "2.2.0"
},
"devDependencies": {
+ "resolve-pkg": "^1.0.0",
"@babel/core": "^7.5.5",
"@babel/plugin-proposal-decorators": "^7.4.4",
"@babel/plugin-syntax-jsx": "^7.2.0",
diff --git a/packages/core/patternlab-config.js b/packages/core/patternlab-config.js
new file mode 100644
index 000000000..a82d5c5b2
--- /dev/null
+++ b/packages/core/patternlab-config.js
@@ -0,0 +1,122 @@
+const resolvePkg = require('resolve-pkg');
+
+module.exports = {
+ engines: {
+ twig: {
+ namespaces: [
+ {
+ id: 'uikit',
+ recursive: true,
+ paths: [resolvePkg(`@pattern-lab/uikit-workshop/views-twig`)],
+ },
+ {
+ id: 'atoms',
+ recursive: true,
+ paths: ['source/_patterns/00-atoms'],
+ },
+ {
+ id: 'molecules',
+ recursive: true,
+ paths: ['source/_patterns/01-molecules'],
+ },
+ ],
+ alterTwigEnv: [
+ {
+ file: 'alter-twig.php',
+ functions: ['addCustomExtension'],
+ },
+ ],
+ },
+ },
+ cacheBust: true,
+ cleanPublic: true,
+ defaultPattern: 'all',
+ defaultShowPatternInfo: false,
+ ishControlsHide: {
+ s: false,
+ m: false,
+ l: false,
+ full: false,
+ random: false,
+ disco: false,
+ hay: true,
+ mqs: false,
+ find: false,
+ 'views-all': false,
+ 'views-annotations': false,
+ 'views-code': false,
+ 'views-new': false,
+ 'tools-all': false,
+ 'tools-docs': false,
+ },
+ ishViewportRange: {
+ s: [240, 500],
+ m: [500, 800],
+ l: [800, 2600],
+ },
+ logLevel: 'info',
+ outputFileSuffixes: {
+ rendered: '.rendered',
+ rawTemplate: '',
+ markupOnly: '.markup-only',
+ },
+ paths: {
+ source: {
+ root: './source/',
+ patterns: './source/_patterns/',
+ data: './source/_data/',
+ meta: './source/_meta/',
+ annotations: './source/_annotations/',
+ styleguide: 'dist/',
+ patternlabFiles: {
+ 'general-header':
+ '../uikit-workshop/views/partials/general-header.mustache',
+ 'general-footer':
+ '../uikit-workshop/views/partials/general-footer.mustache',
+ patternSection:
+ '../uikit-workshop/views/partials/patternSection.mustache',
+ patternSectionSubtype:
+ '../uikit-workshop/views/partials/patternSectionSubtype.mustache',
+ viewall: '../uikit-workshop/views/viewall.mustache',
+ },
+ js: './source/js',
+ images: './source/images',
+ fonts: './source/fonts',
+ css: './source/css',
+ },
+ public: {
+ root: 'public/',
+ patterns: 'public/patterns/',
+ data: 'public/styleguide/data/',
+ annotations: 'public/annotations/',
+ styleguide: 'public/styleguide/',
+ js: 'public/js',
+ images: 'public/images',
+ fonts: 'public/fonts',
+ css: 'public/css',
+ },
+ },
+ patternExtension: 'twig',
+ patternStateCascade: ['inprogress', 'inreview', 'complete'],
+ patternExportDirectory: './pattern_exports/',
+ patternExportPatternPartials: [],
+ serverOptions: {
+ wait: 1000,
+ },
+ starterkitSubDir: 'dist',
+ styleGuideExcludes: [],
+ theme: {
+ color: 'light',
+ density: 'compact',
+ layout: 'horizontal',
+ },
+ uikits: [
+ {
+ name: 'uikit-workshop',
+ outputDir: '',
+ enabled: true,
+ excludedPatternStates: [],
+ excludedTags: [],
+ },
+ ],
+};
diff --git a/packages/core/patternlab-config.json b/packages/core/patternlab-config.json
deleted file mode 100644
index 519282d2c..000000000
--- a/packages/core/patternlab-config.json
+++ /dev/null
@@ -1,100 +0,0 @@
-{
- "cacheBust": true,
- "cleanPublic" : true,
- "defaultPattern": "all",
- "defaultShowPatternInfo": false,
- "ishControlsHide": {
- "s": false,
- "m": false,
- "l": false,
- "full": false,
- "random": false,
- "disco": false,
- "hay": true,
- "mqs": false,
- "find": false,
- "views-all": false,
- "views-annotations": false,
- "views-code": false,
- "views-new": false,
- "tools-all": false,
- "tools-docs": false
- },
- "ishViewportRange": {
- "s": [240, 500],
- "m": [500, 800],
- "l": [800, 2600]
- },
- "logLevel": "info",
- "outputFileSuffixes": {
- "rendered": ".rendered",
- "rawTemplate": "",
- "markupOnly": ".markup-only"
- },
- "paths" : {
- "source": {
- "root": "./source/",
- "patterns": "./source/_patterns/",
- "data": "./source/_data/",
- "meta": "./source/_meta/",
- "annotations": "./source/_annotations/",
- "styleguide": "dist/",
- "patternlabFiles": {
- "general-header":
- "views/partials/general-header.mustache",
- "general-footer":
- "views/partials/general-footer.mustache",
- "patternSection":
- "views/partials/patternSection.mustache",
- "patternSectionSubtype":
- "views/partials/patternSectionSubtype.mustache",
- "viewall":
- "views/viewall.mustache"
- },
- "js": "./source/js",
- "images": "./source/images",
- "fonts": "./source/fonts",
- "css": "./source/css"
- },
- "public": {
- "root": "public/",
- "patterns": "public/patterns/",
- "data": "public/styleguide/data/",
- "annotations": "public/annotations/",
- "styleguide": "public/styleguide/",
- "js": "public/js",
- "images": "public/images",
- "fonts": "public/fonts",
- "css": "public/css"
- }
- },
- "patternExtension": "mustache",
- "patternStateCascade": ["inprogress", "inreview", "complete"],
- "patternExportAll": false,
- "patternExportDirectory": "pattern_exports",
- "patternExportPatternPartials": [],
- "patternExportPreserveDirectoryStructure": true,
- "patternExportRaw": false,
- "patternMergeVariantArrays": true,
- "renderFlatPatternsOnViewAllPages": false,
- "serverOptions": {
- "wait": 1000
- },
- "starterkitSubDir": "dist",
- "styleGuideExcludes": [
- ],
- "theme": {
- "color": "dark",
- "density": "compact",
- "layout": "horizontal"
- },
- "uikits": [
- {
- "name": "uikit-workshop",
- "outputDir": "",
- "enabled": true,
- "excludedPatternStates": [],
- "excludedTags": []
- }
- ]
-}
diff --git a/packages/core/src/index.js b/packages/core/src/index.js
index 1c575c3ab..b26bf73f4 100644
--- a/packages/core/src/index.js
+++ b/packages/core/src/index.js
@@ -19,7 +19,7 @@ const events = require('./lib/events');
const pe = require('./lib/pattern_exporter');
const pm = require('./lib/plugin_manager');
-const defaultConfig = require('../patternlab-config.json');
+const defaultConfig = require('../patternlab-config.js');
let buildPatterns = require('./lib/buildPatterns'); // eslint-disable-line
let logger = require('./lib/log'); // eslint-disable-line
diff --git a/packages/core/src/lib/patternlab.js b/packages/core/src/lib/patternlab.js
index cd89c64c4..2b00d6f37 100644
--- a/packages/core/src/lib/patternlab.js
+++ b/packages/core/src/lib/patternlab.js
@@ -4,7 +4,6 @@ const dive = require('dive');
const _ = require('lodash');
const path = require('path');
const cleanHtml = require('js-beautify').html;
-
const inherits = require('util').inherits;
const pm = require('./plugin_manager');
const plugin_manager = new pm();
@@ -16,7 +15,7 @@ const loaduikits = require('./loaduikits');
const logger = require('./log');
const processIterative = require('./processIterative');
const processRecursive = require('./processRecursive');
-
+const { findPatternLabConfig } = require('./utils/find-config-file');
const loadPattern = require('./loadPattern');
const sm = require('./starterkit_manager');
@@ -32,21 +31,22 @@ function PatternLabEventEmitter() {
}
inherits(PatternLabEventEmitter, EventEmitter);
-module.exports = class PatternLab {
+class PatternLab {
constructor(config) {
- // Either use the config we were passed, or load one up from the config file ourselves
- this.config =
- config ||
- fs.readJSONSync(path.resolve(__dirname, '../../patternlab-config.json'));
+ // Use the already-resolved config passed in OR auto load one up from the config
+ const getConfigAsync = async () => {
+ this.config = config || (await Promise.resolve(findPatternLabConfig()));
+ };
+ getConfigAsync();
//register our log events
- this.registerLogger(config.logLevel);
+ this.registerLogger(this.config.logLevel);
logger.info(`Pattern Lab Node v${packageInfo.version}`);
// Load up engines please
this.engines = patternEngines;
- this.engines.loadAllEngines(config);
+ this.engines.loadAllEngines(this.config);
this.isBusy = false;
//
@@ -364,4 +364,6 @@ module.exports = class PatternLab {
});
return promiseAllPatternFiles;
}
-};
+}
+
+module.exports = PatternLab;
diff --git a/packages/core/src/lib/utils/find-config-file.js b/packages/core/src/lib/utils/find-config-file.js
new file mode 100644
index 000000000..c41f12c60
--- /dev/null
+++ b/packages/core/src/lib/utils/find-config-file.js
@@ -0,0 +1,57 @@
+const cosmiconfig = require('cosmiconfig');
+
+// find and load up the pattern lab configuration
+async function findPatternLabConfig(configPath) {
+ return new Promise(resolve => {
+ const moduleName = 'patternlab';
+ const explorer = cosmiconfig(moduleName, {
+ searchPlaces: [
+ 'package.json',
+ `.${moduleName}rc`,
+ `.${moduleName}rc.json`,
+ `.${moduleName}rc.yaml`,
+ `.${moduleName}rc.yml`,
+ `.${moduleName}rc.js`,
+ `${moduleName}.config.js`,
+ `${moduleName}.config.json`,
+ ],
+ });
+
+ // if a config path is provided, try to load that up. otherwise recursively search
+ if (configPath) {
+ return explorer
+ .load(configPath)
+ .then(result => {
+ const config = result.config;
+ config.filepath = result.filepath;
+ resolve(config);
+ // result.config is the parsed configuration object.
+ // result.filepath is the path to the config file that was found.
+ // result.isEmpty is true if there was nothing to parse in the config file.
+ })
+ .catch(error => {
+ console.log(error);
+ // Do something constructive.
+ });
+ } else {
+ return explorer
+ .search()
+ .then(result => {
+ const config = result.config;
+ config.filepath = result.filepath;
+ resolve(config);
+ // result.config is the parsed configuration object.
+ // result.filepath is the path to the config file that was found.
+ // result.isEmpty is true if there was nothing to parse in the config file.
+ })
+ .catch(error => {
+ console.log(error);
+ // Do something constructive.
+ });
+ }
+ });
+}
+
+module.exports = {
+ findPatternLabConfig,
+};
diff --git a/packages/docs/php-docs/viewing-patterns.html b/packages/docs/php-docs/viewing-patterns.html
index ebc7461d4..ebbaab455 100644
--- a/packages/docs/php-docs/viewing-patterns.html
+++ b/packages/docs/php-docs/viewing-patterns.html
@@ -4,14 +4,9 @@
- docs
---
-
-
-Pattern Lab utilizes PHP's [built-in web server](http://php.net/manual/en/features.commandline.webserver.php) to let you browse your generated patterns. To start the server do the following:
-
-1. In a terminal window navigate to the root of your project
-2. Type `php core/console --server`
-
-Your local Pattern Lab install should now be available for browsing at [http://localhost:8080](http://localhost:8080).
-
-
-
+Pattern Lab utilizes PHP's [built-in web
+server](http://php.net/manual/en/features.commandline.webserver.php) to let you browse
+your generated patterns. To start the server do the following: 1. In a terminal window
+navigate to the root of your project 2. Type `php core/console --server` Your local
+Pattern Lab install should now be available for browsing at
+[http://localhost:8080](http://localhost:8080).
diff --git a/packages/docs/rollup.config.js b/packages/docs/rollup.config.js
index 7f62e07f4..8d516669e 100644
--- a/packages/docs/rollup.config.js
+++ b/packages/docs/rollup.config.js
@@ -4,16 +4,11 @@ const nodeResolve = require('rollup-plugin-node-resolve');
const json = require('rollup-plugin-json');
export default {
- input: 'src/admin/util',
- output: {
- file: 'dist/admin/util.js',
- format: 'iife',
- name: 'previewUtil',
- },
- plugins: [
- builtins(),
- nodeResolve(),
- commonjs(),
- json(),
- ]
+ input: 'src/admin/util',
+ output: {
+ file: 'dist/admin/util.js',
+ format: 'iife',
+ name: 'previewUtil'
+ },
+ plugins: [builtins(), nodeResolve(), commonjs(), json()]
};
diff --git a/packages/docs/src/_data/global.js b/packages/docs/src/_data/global.js
index 683a0a332..15f4f9ded 100644
--- a/packages/docs/src/_data/global.js
+++ b/packages/docs/src/_data/global.js
@@ -1,9 +1,9 @@
module.exports = {
- random() {
- const segment = () => {
- return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
- };
- return `${segment()}-${segment()}-${segment()}`;
- },
- now: Date.now()
+ random() {
+ const segment = () => {
+ return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+ };
+ return `${segment()}-${segment()}-${segment()}`;
+ },
+ now: Date.now()
};
diff --git a/packages/docs/src/_data/helpers.js b/packages/docs/src/_data/helpers.js
index 9ae9b7883..c12bea921 100644
--- a/packages/docs/src/_data/helpers.js
+++ b/packages/docs/src/_data/helpers.js
@@ -1,10 +1,10 @@
module.exports = {
- getNextHeadingLevel(currentLevel) {
- return parseInt(currentLevel, 10) + 1;
- },
- getReadingTime(text) {
- const wordsPerMinute = 200;
- const numberOfWords = text.split(/\s/g).length;
- return Math.ceil(numberOfWords / wordsPerMinute);
- }
+ getNextHeadingLevel(currentLevel) {
+ return parseInt(currentLevel, 10) + 1;
+ },
+ getReadingTime(text) {
+ const wordsPerMinute = 200;
+ const numberOfWords = text.split(/\s/g).length;
+ return Math.ceil(numberOfWords / wordsPerMinute);
+ }
};
diff --git a/packages/docs/src/_data/styleguide.js b/packages/docs/src/_data/styleguide.js
index 4969bec39..f3ff8c3ec 100644
--- a/packages/docs/src/_data/styleguide.js
+++ b/packages/docs/src/_data/styleguide.js
@@ -1,28 +1,28 @@
const tokens = require('./tokens.json');
module.exports = {
- colors() {
- let response = [];
+ colors() {
+ let response = [];
- Object.keys(tokens.colors).forEach(key => {
- response.push({
- value: tokens.colors[key],
- key
- });
- });
+ Object.keys(tokens.colors).forEach(key => {
+ response.push({
+ value: tokens.colors[key],
+ key
+ });
+ });
- return response;
- },
- sizes() {
- let response = [];
+ return response;
+ },
+ sizes() {
+ let response = [];
- Object.keys(tokens['size-scale']).forEach(key => {
- response.push({
- value: tokens['size-scale'][key],
- key
- });
- });
+ Object.keys(tokens['size-scale']).forEach(key => {
+ response.push({
+ value: tokens['size-scale'][key],
+ key
+ });
+ });
- return response;
- }
+ return response;
+ }
};
diff --git a/packages/docs/src/admin/previews.js b/packages/docs/src/admin/previews.js
index 82dcd1f2c..8f2eddd54 100644
--- a/packages/docs/src/admin/previews.js
+++ b/packages/docs/src/admin/previews.js
@@ -7,82 +7,82 @@ env.addFilter('markdownFilter', markdownFilter);
env.addFilter('dateFilter', dateFilter);
const Preview = ({entry, path, context}) => {
- const data = context(entry.get('data').toJS());
- const html = env.render(path, {...data, helpers});
- return
;
+ const data = context(entry.get('data').toJS());
+ const html = env.render(path, {...data, helpers});
+ return ;
};
const Home = ({entry}) => (
- ({
- title,
- content: markdownFilter(body),
- postsHeading,
- archiveButtonText,
- collections: {
- postFeed: [
- {
- url: 'javascript:void(0)',
- date: new Date(),
- data: {
- title: 'Sample Post'
- }
- }
- ]
- }
- })}
- />
+ ({
+ title,
+ content: markdownFilter(body),
+ postsHeading,
+ archiveButtonText,
+ collections: {
+ postFeed: [
+ {
+ url: 'javascript:void(0)',
+ date: new Date(),
+ data: {
+ title: 'Sample Post'
+ }
+ }
+ ]
+ }
+ })}
+ />
);
const Post = ({entry}) => (
- ({
- title,
- date,
- content: markdownFilter(body || '')
- })}
- />
+ ({
+ title,
+ date,
+ content: markdownFilter(body || '')
+ })}
+ />
);
const Page = ({entry}) => (
- ({
- title,
- content: markdownFilter(body || '')
- })}
- />
+ ({
+ title,
+ content: markdownFilter(body || '')
+ })}
+ />
);
const SiteData = ({entry}) => (
- ({
- site: {
- name,
- shortDesc,
- showThemeCredit
- }
- })}
- />
+ ({
+ site: {
+ name,
+ shortDesc,
+ showThemeCredit
+ }
+ })}
+ />
);
const Nav = ({entry}) => (
- ({
- navigation: {
- items
- }
- })}
- />
+ ({
+ navigation: {
+ items
+ }
+ })}
+ />
);
CMS.registerPreviewTemplate('home', Home);
diff --git a/packages/docs/src/admin/util.js b/packages/docs/src/admin/util.js
index 302b159cf..53db2e8ec 100644
--- a/packages/docs/src/admin/util.js
+++ b/packages/docs/src/admin/util.js
@@ -3,9 +3,4 @@ import dateFilter from '../filters/date-filter';
import markdownFilter from '../filters/markdown-filter';
import w3DateFilter from '../filters/w3-date-filter';
-export {
- helpers,
- dateFilter,
- markdownFilter,
- w3DateFilter,
-};
+export {helpers, dateFilter, markdownFilter, w3DateFilter};
diff --git a/packages/docs/src/filters/date-filter.js b/packages/docs/src/filters/date-filter.js
index 5206da52f..bc9378aa9 100644
--- a/packages/docs/src/filters/date-filter.js
+++ b/packages/docs/src/filters/date-filter.js
@@ -1,15 +1,28 @@
// Stolen from https://stackoverflow.com/a/31615643
const appendSuffix = n => {
- var s = ['th', 'st', 'nd', 'rd'],
- v = n % 100;
- return n + (s[(v - 20) % 10] || s[v] || s[0]);
+ var s = ['th', 'st', 'nd', 'rd'],
+ v = n % 100;
+ return n + (s[(v - 20) % 10] || s[v] || s[0]);
};
module.exports = function dateFilter(value) {
- const dateObject = new Date(value);
+ const dateObject = new Date(value);
- const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
- const dayWithSuffix = appendSuffix(dateObject.getDate());
+ const months = [
+ 'January',
+ 'February',
+ 'March',
+ 'April',
+ 'May',
+ 'June',
+ 'July',
+ 'August',
+ 'September',
+ 'October',
+ 'November',
+ 'December'
+ ];
+ const dayWithSuffix = appendSuffix(dateObject.getDate());
- return `${dayWithSuffix} ${months[dateObject.getMonth()]} ${dateObject.getFullYear()}`;
+ return `${dayWithSuffix} ${months[dateObject.getMonth()]} ${dateObject.getFullYear()}`;
};
diff --git a/packages/docs/src/filters/markdown-filter.js b/packages/docs/src/filters/markdown-filter.js
index 530c2f571..9a0cc89b9 100644
--- a/packages/docs/src/filters/markdown-filter.js
+++ b/packages/docs/src/filters/markdown-filter.js
@@ -1,9 +1,9 @@
const markdownIt = require('markdown-it')({
- html: true,
- breaks: true,
- linkify: true
+ html: true,
+ breaks: true,
+ linkify: true
});
module.exports = function markdown(value) {
- return markdownIt.render(value);
+ return markdownIt.render(value);
};
diff --git a/packages/docs/src/filters/w3-date-filter.js b/packages/docs/src/filters/w3-date-filter.js
index d31538da4..39c0f7ca8 100644
--- a/packages/docs/src/filters/w3-date-filter.js
+++ b/packages/docs/src/filters/w3-date-filter.js
@@ -1,5 +1,5 @@
module.exports = function w3cDate(value) {
- const dateObject = new Date(value);
+ const dateObject = new Date(value);
- return dateObject.toISOString();
+ return dateObject.toISOString();
};
diff --git a/packages/docs/src/js/components/theme-toggle.js b/packages/docs/src/js/components/theme-toggle.js
index 7e93571a2..3f6358b37 100644
--- a/packages/docs/src/js/components/theme-toggle.js
+++ b/packages/docs/src/js/components/theme-toggle.js
@@ -2,97 +2,97 @@
const html = String.raw;
class ThemeToggle extends HTMLElement {
- constructor() {
- super();
-
- this.STORAGE_KEY = 'user-color-scheme';
- this.COLOR_MODE_KEY = '--color-mode';
- }
-
- connectedCallback() {
- this.render();
- }
-
- getCSSCustomProp(propKey) {
- let response = getComputedStyle(document.documentElement).getPropertyValue(propKey);
-
- // Tidy up the string if there’s something to work with
- if (response.length) {
- response = response.replace(/\'|"/g, '').trim();
- }
-
- // Return the string response by default
- return response;
- }
-
- applySetting(passedSetting) {
- let currentSetting = passedSetting || localStorage.getItem(this.STORAGE_KEY);
-
- if (currentSetting) {
- document.documentElement.setAttribute('data-user-color-scheme', currentSetting);
- this.setButtonLabelAndStatus(currentSetting);
- } else {
- this.setButtonLabelAndStatus(this.getCSSCustomProp(this.COLOR_MODE_KEY));
- }
- }
-
- toggleSetting() {
- let currentSetting = localStorage.getItem(this.STORAGE_KEY);
-
- switch (currentSetting) {
- case null:
- currentSetting =
- this.getCSSCustomProp(this.COLOR_MODE_KEY) === 'dark' ? 'light' : 'dark';
- break;
- case 'light':
- currentSetting = 'dark';
- break;
- case 'dark':
- currentSetting = 'light';
- break;
- }
-
- localStorage.setItem(this.STORAGE_KEY, currentSetting);
-
- return currentSetting;
- }
-
- setButtonLabelAndStatus(currentSetting) {
- this.modeToggleButton.innerText = `${
- currentSetting === 'dark' ? 'Light' : 'Dark'
- } theme`;
- this.modeStatusElement.innerText = `Color mode is now "${currentSetting}"`;
- }
-
- render() {
- this.innerHTML = html`
-
- `;
-
- this.afterRender();
- }
-
- afterRender() {
- this.modeToggleButton = document.querySelector('.js-mode-toggle');
- this.modeStatusElement = document.querySelector('.js-mode-status');
-
- this.modeToggleButton.addEventListener('click', evt => {
- evt.preventDefault();
-
- this.applySetting(this.toggleSetting());
- });
-
- this.applySetting();
- }
+ constructor() {
+ super();
+
+ this.STORAGE_KEY = 'user-color-scheme';
+ this.COLOR_MODE_KEY = '--color-mode';
+ }
+
+ connectedCallback() {
+ this.render();
+ }
+
+ getCSSCustomProp(propKey) {
+ let response = getComputedStyle(document.documentElement).getPropertyValue(propKey);
+
+ // Tidy up the string if there’s something to work with
+ if (response.length) {
+ response = response.replace(/\'|"/g, '').trim();
+ }
+
+ // Return the string response by default
+ return response;
+ }
+
+ applySetting(passedSetting) {
+ let currentSetting = passedSetting || localStorage.getItem(this.STORAGE_KEY);
+
+ if (currentSetting) {
+ document.documentElement.setAttribute('data-user-color-scheme', currentSetting);
+ this.setButtonLabelAndStatus(currentSetting);
+ } else {
+ this.setButtonLabelAndStatus(this.getCSSCustomProp(this.COLOR_MODE_KEY));
+ }
+ }
+
+ toggleSetting() {
+ let currentSetting = localStorage.getItem(this.STORAGE_KEY);
+
+ switch (currentSetting) {
+ case null:
+ currentSetting =
+ this.getCSSCustomProp(this.COLOR_MODE_KEY) === 'dark' ? 'light' : 'dark';
+ break;
+ case 'light':
+ currentSetting = 'dark';
+ break;
+ case 'dark':
+ currentSetting = 'light';
+ break;
+ }
+
+ localStorage.setItem(this.STORAGE_KEY, currentSetting);
+
+ return currentSetting;
+ }
+
+ setButtonLabelAndStatus(currentSetting) {
+ this.modeToggleButton.innerText = `${
+ currentSetting === 'dark' ? 'Light' : 'Dark'
+ } theme`;
+ this.modeStatusElement.innerText = `Color mode is now "${currentSetting}"`;
+ }
+
+ render() {
+ this.innerHTML = html`
+
+ `;
+
+ this.afterRender();
+ }
+
+ afterRender() {
+ this.modeToggleButton = document.querySelector('.js-mode-toggle');
+ this.modeStatusElement = document.querySelector('.js-mode-status');
+
+ this.modeToggleButton.addEventListener('click', evt => {
+ evt.preventDefault();
+
+ this.applySetting(this.toggleSetting());
+ });
+
+ this.applySetting();
+ }
}
if ('customElements' in window) {
- customElements.define('theme-toggle', ThemeToggle);
+ customElements.define('theme-toggle', ThemeToggle);
}
export default ThemeToggle;
diff --git a/packages/docs/src/transforms/html-min-transform.js b/packages/docs/src/transforms/html-min-transform.js
index 7d0c8f99b..aec1a5676 100644
--- a/packages/docs/src/transforms/html-min-transform.js
+++ b/packages/docs/src/transforms/html-min-transform.js
@@ -1,14 +1,14 @@
const htmlmin = require('html-minifier');
module.exports = function htmlMinTransform(value, outputPath) {
- if (outputPath.indexOf('.html') > -1) {
- let minified = htmlmin.minify(value, {
- useShortDoctype: true,
- removeComments: true,
- collapseWhitespace: true,
- minifyCSS: true
- });
- return minified;
- }
- return value;
+ if (outputPath.indexOf('.html') > -1) {
+ let minified = htmlmin.minify(value, {
+ useShortDoctype: true,
+ removeComments: true,
+ collapseWhitespace: true,
+ minifyCSS: true
+ });
+ return minified;
+ }
+ return value;
};
diff --git a/packages/docs/src/transforms/parse-transform.js b/packages/docs/src/transforms/parse-transform.js
index 541f04cf7..a7d75788c 100644
--- a/packages/docs/src/transforms/parse-transform.js
+++ b/packages/docs/src/transforms/parse-transform.js
@@ -4,76 +4,75 @@ const minify = require('../utils/minify.js');
const slugify = require('slugify');
module.exports = function(value, outputPath) {
- if (outputPath.endsWith('.html')) {
- const DOM = new JSDOM(value, {
- resources: 'usable'
- });
-
- const document = DOM.window.document;
- const articleImages = [...document.querySelectorAll('main article img')];
- const articleHeadings = [
- ...document.querySelectorAll('main article h2, main article h3')
- ];
- const articleEmbeds = [...document.querySelectorAll('main article iframe')];
-
- if (articleImages.length) {
- articleImages.forEach(image => {
- image.setAttribute('loading', 'lazy');
-
- // If an image has a title it means that the user added a caption
- // so replace the image with a figure containing that image and a caption
- if (image.hasAttribute('title')) {
- const figure = document.createElement('figure');
- const figCaption = document.createElement('figcaption');
-
- figCaption.innerHTML = image.getAttribute('title');
-
- image.removeAttribute('title');
-
- figure.appendChild(image.cloneNode(true));
- figure.appendChild(figCaption);
-
- image.replaceWith(figure);
- }
-
- });
- }
-
- if (articleHeadings.length) {
- // Loop each heading and add a little anchor and an ID to each one
- articleHeadings.forEach(heading => {
- const headingSlug = slugify(heading.textContent.toLowerCase());
- const anchor = document.createElement('a');
-
- anchor.setAttribute('href', `#heading-${headingSlug}`);
- anchor.classList.add('heading-permalink');
- anchor.innerHTML = minify(`
+ if (outputPath.endsWith('.html')) {
+ const DOM = new JSDOM(value, {
+ resources: 'usable'
+ });
+
+ const document = DOM.window.document;
+ const articleImages = [...document.querySelectorAll('main article img')];
+ const articleHeadings = [
+ ...document.querySelectorAll('main article h2, main article h3')
+ ];
+ const articleEmbeds = [...document.querySelectorAll('main article iframe')];
+
+ if (articleImages.length) {
+ articleImages.forEach(image => {
+ image.setAttribute('loading', 'lazy');
+
+ // If an image has a title it means that the user added a caption
+ // so replace the image with a figure containing that image and a caption
+ if (image.hasAttribute('title')) {
+ const figure = document.createElement('figure');
+ const figCaption = document.createElement('figcaption');
+
+ figCaption.innerHTML = image.getAttribute('title');
+
+ image.removeAttribute('title');
+
+ figure.appendChild(image.cloneNode(true));
+ figure.appendChild(figCaption);
+
+ image.replaceWith(figure);
+ }
+ });
+ }
+
+ if (articleHeadings.length) {
+ // Loop each heading and add a little anchor and an ID to each one
+ articleHeadings.forEach(heading => {
+ const headingSlug = slugify(heading.textContent.toLowerCase());
+ const anchor = document.createElement('a');
+
+ anchor.setAttribute('href', `#heading-${headingSlug}`);
+ anchor.classList.add('heading-permalink');
+ anchor.innerHTML = minify(`
permalink
`);
- heading.setAttribute('id', `heading-${headingSlug}`);
- heading.appendChild(anchor);
- });
- }
+ heading.setAttribute('id', `heading-${headingSlug}`);
+ heading.appendChild(anchor);
+ });
+ }
- // Look for videos are wrap them in a container element
- if (articleEmbeds.length) {
- articleEmbeds.forEach(embed => {
- if (embed.hasAttribute('allowfullscreen')) {
- const player = document.createElement('div');
+ // Look for videos are wrap them in a container element
+ if (articleEmbeds.length) {
+ articleEmbeds.forEach(embed => {
+ if (embed.hasAttribute('allowfullscreen')) {
+ const player = document.createElement('div');
- player.classList.add('video-player');
+ player.classList.add('video-player');
- player.appendChild(embed.cloneNode(true));
+ player.appendChild(embed.cloneNode(true));
- embed.replaceWith(player);
- }
- });
- }
+ embed.replaceWith(player);
+ }
+ });
+ }
- return '\r\n' + document.documentElement.outerHTML;
- }
- return value;
+ return '\r\n' + document.documentElement.outerHTML;
+ }
+ return value;
};
diff --git a/packages/docs/src/utils/minify.js b/packages/docs/src/utils/minify.js
index dd80e240c..19248c5d8 100644
--- a/packages/docs/src/utils/minify.js
+++ b/packages/docs/src/utils/minify.js
@@ -1,3 +1,3 @@
module.exports = function minify(input) {
- return input.replace(/\s{2,}/g, '').replace(/\'/g, '"');
+ return input.replace(/\s{2,}/g, '').replace(/\'/g, '"');
};
diff --git a/packages/edition-twig/package.json b/packages/edition-twig/package.json
index fd9a68f91..ff6a9d3c1 100644
--- a/packages/edition-twig/package.json
+++ b/packages/edition-twig/package.json
@@ -14,10 +14,10 @@
"main": "patternlab-config.json",
"scripts": {
"build:uikit": "cross-env-shell PL_CONFIG_PATH='${INIT_CWD}/.patternlabrc.js' npm run build --prefix node_modules/@pattern-lab/uikit-workshop -- --patternlabrc '$PL_CONFIG_PATH'",
- "build": "patternlab build --config ./patternlab-config.json",
+ "build": "patternlab build --config ./patternlab-config.js",
"help": "patternlab --help",
- "install": "patternlab install --config ./patternlab-config.json",
- "serve": "patternlab serve --config ./patternlab-config.json",
+ "install": "patternlab install --config ./patternlab-config.js",
+ "serve": "patternlab serve --config ./patternlab-config.js",
"start": "npm run serve",
"version": "patternlab --version",
"dev": "node ./node_modules/@pattern-lab/uikit-workshop/build-tools.js"
diff --git a/packages/edition-twig/patternlab-config.default.js b/packages/edition-twig/patternlab-config.default.js
new file mode 100644
index 000000000..a82d5c5b2
--- /dev/null
+++ b/packages/edition-twig/patternlab-config.default.js
@@ -0,0 +1,122 @@
+const resolvePkg = require('resolve-pkg');
+
+module.exports = {
+ engines: {
+ twig: {
+ namespaces: [
+ {
+ id: 'uikit',
+ recursive: true,
+ paths: [resolvePkg(`@pattern-lab/uikit-workshop/views-twig`)],
+ },
+ {
+ id: 'atoms',
+ recursive: true,
+ paths: ['source/_patterns/00-atoms'],
+ },
+ {
+ id: 'molecules',
+ recursive: true,
+ paths: ['source/_patterns/01-molecules'],
+ },
+ ],
+ alterTwigEnv: [
+ {
+ file: 'alter-twig.php',
+ functions: ['addCustomExtension'],
+ },
+ ],
+ },
+ },
+ cacheBust: true,
+ cleanPublic: true,
+ defaultPattern: 'all',
+ defaultShowPatternInfo: false,
+ ishControlsHide: {
+ s: false,
+ m: false,
+ l: false,
+ full: false,
+ random: false,
+ disco: false,
+ hay: true,
+ mqs: false,
+ find: false,
+ 'views-all': false,
+ 'views-annotations': false,
+ 'views-code': false,
+ 'views-new': false,
+ 'tools-all': false,
+ 'tools-docs': false,
+ },
+ ishViewportRange: {
+ s: [240, 500],
+ m: [500, 800],
+ l: [800, 2600],
+ },
+ logLevel: 'info',
+ outputFileSuffixes: {
+ rendered: '.rendered',
+ rawTemplate: '',
+ markupOnly: '.markup-only',
+ },
+ paths: {
+ source: {
+ root: './source/',
+ patterns: './source/_patterns/',
+ data: './source/_data/',
+ meta: './source/_meta/',
+ annotations: './source/_annotations/',
+ styleguide: 'dist/',
+ patternlabFiles: {
+ 'general-header':
+ '../uikit-workshop/views/partials/general-header.mustache',
+ 'general-footer':
+ '../uikit-workshop/views/partials/general-footer.mustache',
+ patternSection:
+ '../uikit-workshop/views/partials/patternSection.mustache',
+ patternSectionSubtype:
+ '../uikit-workshop/views/partials/patternSectionSubtype.mustache',
+ viewall: '../uikit-workshop/views/viewall.mustache',
+ },
+ js: './source/js',
+ images: './source/images',
+ fonts: './source/fonts',
+ css: './source/css',
+ },
+ public: {
+ root: 'public/',
+ patterns: 'public/patterns/',
+ data: 'public/styleguide/data/',
+ annotations: 'public/annotations/',
+ styleguide: 'public/styleguide/',
+ js: 'public/js',
+ images: 'public/images',
+ fonts: 'public/fonts',
+ css: 'public/css',
+ },
+ },
+ patternExtension: 'twig',
+ patternStateCascade: ['inprogress', 'inreview', 'complete'],
+ patternExportDirectory: './pattern_exports/',
+ patternExportPatternPartials: [],
+ serverOptions: {
+ wait: 1000,
+ },
+ starterkitSubDir: 'dist',
+ styleGuideExcludes: [],
+ theme: {
+ color: 'light',
+ density: 'compact',
+ layout: 'horizontal',
+ },
+ uikits: [
+ {
+ name: 'uikit-workshop',
+ outputDir: '',
+ enabled: true,
+ excludedPatternStates: [],
+ excludedTags: [],
+ },
+ ],
+};
diff --git a/packages/edition-twig/patternlab-config.js b/packages/edition-twig/patternlab-config.js
new file mode 100644
index 000000000..a82d5c5b2
--- /dev/null
+++ b/packages/edition-twig/patternlab-config.js
@@ -0,0 +1,122 @@
+const resolvePkg = require('resolve-pkg');
+
+module.exports = {
+ engines: {
+ twig: {
+ namespaces: [
+ {
+ id: 'uikit',
+ recursive: true,
+ paths: [resolvePkg(`@pattern-lab/uikit-workshop/views-twig`)],
+ },
+ {
+ id: 'atoms',
+ recursive: true,
+ paths: ['source/_patterns/00-atoms'],
+ },
+ {
+ id: 'molecules',
+ recursive: true,
+ paths: ['source/_patterns/01-molecules'],
+ },
+ ],
+ alterTwigEnv: [
+ {
+ file: 'alter-twig.php',
+ functions: ['addCustomExtension'],
+ },
+ ],
+ },
+ },
+ cacheBust: true,
+ cleanPublic: true,
+ defaultPattern: 'all',
+ defaultShowPatternInfo: false,
+ ishControlsHide: {
+ s: false,
+ m: false,
+ l: false,
+ full: false,
+ random: false,
+ disco: false,
+ hay: true,
+ mqs: false,
+ find: false,
+ 'views-all': false,
+ 'views-annotations': false,
+ 'views-code': false,
+ 'views-new': false,
+ 'tools-all': false,
+ 'tools-docs': false,
+ },
+ ishViewportRange: {
+ s: [240, 500],
+ m: [500, 800],
+ l: [800, 2600],
+ },
+ logLevel: 'info',
+ outputFileSuffixes: {
+ rendered: '.rendered',
+ rawTemplate: '',
+ markupOnly: '.markup-only',
+ },
+ paths: {
+ source: {
+ root: './source/',
+ patterns: './source/_patterns/',
+ data: './source/_data/',
+ meta: './source/_meta/',
+ annotations: './source/_annotations/',
+ styleguide: 'dist/',
+ patternlabFiles: {
+ 'general-header':
+ '../uikit-workshop/views/partials/general-header.mustache',
+ 'general-footer':
+ '../uikit-workshop/views/partials/general-footer.mustache',
+ patternSection:
+ '../uikit-workshop/views/partials/patternSection.mustache',
+ patternSectionSubtype:
+ '../uikit-workshop/views/partials/patternSectionSubtype.mustache',
+ viewall: '../uikit-workshop/views/viewall.mustache',
+ },
+ js: './source/js',
+ images: './source/images',
+ fonts: './source/fonts',
+ css: './source/css',
+ },
+ public: {
+ root: 'public/',
+ patterns: 'public/patterns/',
+ data: 'public/styleguide/data/',
+ annotations: 'public/annotations/',
+ styleguide: 'public/styleguide/',
+ js: 'public/js',
+ images: 'public/images',
+ fonts: 'public/fonts',
+ css: 'public/css',
+ },
+ },
+ patternExtension: 'twig',
+ patternStateCascade: ['inprogress', 'inreview', 'complete'],
+ patternExportDirectory: './pattern_exports/',
+ patternExportPatternPartials: [],
+ serverOptions: {
+ wait: 1000,
+ },
+ starterkitSubDir: 'dist',
+ styleGuideExcludes: [],
+ theme: {
+ color: 'light',
+ density: 'compact',
+ layout: 'horizontal',
+ },
+ uikits: [
+ {
+ name: 'uikit-workshop',
+ outputDir: '',
+ enabled: true,
+ excludedPatternStates: [],
+ excludedTags: [],
+ },
+ ],
+};
diff --git a/packages/engine-twig-php/lib/engine_twig_php.js b/packages/engine-twig-php/lib/engine_twig_php.js
index f675e94d1..cb3149f35 100644
--- a/packages/engine-twig-php/lib/engine_twig_php.js
+++ b/packages/engine-twig-php/lib/engine_twig_php.js
@@ -45,7 +45,12 @@ const engine_twig_php = {
process.exit(1);
}
- const { namespaces, alterTwigEnv, relativeFrom, ...rest } = config.engines.twig;
+ const {
+ namespaces,
+ alterTwigEnv,
+ relativeFrom,
+ ...rest
+ } = config.engines.twig;
// Schema on config object being passed in:
// https://github.com/basaltinc/twig-renderer/blob/master/config.schema.json
diff --git a/packages/plugin-tab/src/snippet.js b/packages/plugin-tab/src/snippet.js
index 337f00fec..968ae163f 100644
--- a/packages/plugin-tab/src/snippet.js
+++ b/packages/plugin-tab/src/snippet.js
@@ -1,13 +1,15 @@
window.patternlab.panels.add({
id: 'sg-panel-<>',
name: '<>',
- default: window.config.defaultPatternInfoPanelCode && window.config.defaultPatternInfoPanelCode === "<>",
+ default:
+ window.config.defaultPatternInfoPanelCode &&
+ window.config.defaultPatternInfoPanelCode === '<>',
templateID: 'pl-panel-template-code',
httpRequest: true,
httpRequestReplace: '.<>',
httpRequestCompleted: false,
prismHighlight: true,
- language: '<>'//,
+ language: '<>', //,
/* TODO: We would need to find a way to enable keyCombo for multiple panels
keyCombo: 'ctrl+shift+z',*/
});
diff --git a/packages/uikit-workshop/src/scripts/components/panels.js b/packages/uikit-workshop/src/scripts/components/panels.js
index 5c5739870..f4ad404a2 100644
--- a/packages/uikit-workshop/src/scripts/components/panels.js
+++ b/packages/uikit-workshop/src/scripts/components/panels.js
@@ -68,9 +68,10 @@ function init(event) {
Panels.add({
id: 'pl-panel-pattern',
name: window.config.patternExtension.toUpperCase(),
- default: !window.config.defaultPatternInfoPanelCode ||
- window.config.defaultPatternInfoPanelCode ===
- window.config.patternExtension,
+ default:
+ !window.config.defaultPatternInfoPanelCode ||
+ window.config.defaultPatternInfoPanelCode ===
+ window.config.patternExtension,
templateID: 'pl-panel-template-code',
httpRequest: true,
httpRequestReplace: fileSuffixPattern,