├── .editorconfig
├── lib
├── outputTemplate.mustache
└── engine_react.js
├── .gitignore
├── LICENSE
├── package.json
├── README.md
└── .eslintrc
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | tab_width = 2
8 | end_of_line = lf
9 | charset = utf-8
10 | trim_trailing_whitespace = true
11 | insert_final_newline = true
12 |
--------------------------------------------------------------------------------
/lib/outputTemplate.mustache:
--------------------------------------------------------------------------------
1 |
2 | {{{htmlOutput}}}
3 |
4 |
5 |
6 |
9 |
10 |
11 |
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 |
33 | # Optional npm cache directory
34 | .npm
35 |
36 | # Optional REPL history
37 | .node_repl_history
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Pattern Lab
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "patternengine-node-react",
3 | "description": "The React engine for Pattern Lab / Node",
4 | "version": "0.1.0",
5 | "main": "lib/engine_react.js",
6 | "dependencies": {
7 | "babel-core": "^6.17.0",
8 | "babel-plugin-module-alias": "^1.6.0",
9 | "babel-plugin-transform-es2015-modules-commonjs": "^6.16.0",
10 | "babel-plugin-transform-es2015-modules-umd": "^6.12.0",
11 | "babel-preset-react": "^6.16.0",
12 | "cheerio": "^0.22.0",
13 | "hogan": "^1.0.2",
14 | "js-beautify": "^1.6.4",
15 | "react": "^15.3.2",
16 | "react-dom": "^15.3.2"
17 | },
18 | "devDependencies": {},
19 | "keywords": [
20 | "Pattern Lab",
21 | "Atomic Web Design",
22 | "Node",
23 | "Gulp",
24 | "Javascript",
25 | "React"
26 | ],
27 | "repository": {
28 | "type": "git",
29 | "url": "https://github.com/pattern-lab/patternengine-node-react.git"
30 | },
31 | "bugs": "https://github.com/pattern-lab/patternlab-node/issues",
32 | "author": "Brian Muenzenmeyer & Geoffrey Pursell",
33 | "license": "MIT",
34 | "scripts": {
35 | "test": "grunt travis --verbose"
36 | },
37 | "engines": {
38 | "node": ">=4.4"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [📢 Archived in favor of https://github.com/pattern-lab/patternlab-node](https://github.com/pattern-lab/patternlab-node)
2 |
3 | # The React engine for Pattern Lab / Node
4 | This is the **very preliminary barely worth mentioning** React engine for Patternlab/Node. It's more or less a proof of concept.
5 |
6 | ## Status
7 | You can author standalone React components that include only the main React module, which I know isn't much yet. We're still working out how React components will resolve and load the modules they depend on, including other patterns. We believe this is tricky, but doable.
8 |
9 | ## Supported features
10 | Kind of nothing works yet. **Very early in development.**
11 |
12 | - [ ] [Includes](http://patternlab.io/docs/pattern-including.html)
13 | - [ ] Lineage
14 | - [ ] [Hidden Patterns](http://patternlab.io/docs/pattern-hiding.html)
15 | - [ ] [Pseudo-Patterns](http://patternlab.io/docs/pattern-pseudo-patterns.html)
16 | - [ ] [Pattern States](http://patternlab.io/docs/pattern-states.html)
17 | - [ ] [Pattern Parameters](http://patternlab.io/docs/pattern-parameters.html)
18 | - [ ] [Style Modifiers](http://patternlab.io/docs/pattern-stylemodifier.html)
19 |
20 | ## Usage
21 | * `*.jsx` files are detected as patterns.
22 | * Standard pattern JSON is passed into React components as props.
23 |
24 | ## Notes
25 | * Components are rendered statically to markup at build time using ReactDOMServer.renderToStaticMarkup(), but also transpiled and inlined as scripts in the pattern code to execute at runtime.
26 | * We currently assume the React include (and others, once we figure that out) are written using es2015 module syntax.
27 | * The Babel transforms are currently hard-coded into the engine, but we hope to make this configurable in the future.
28 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "node": true,
4 | "builtin": true
5 | },
6 | "parserOptions": {
7 | "ecmaVersion": 6,
8 | "sourceType": "module",
9 | "ecmaFeatures": {
10 | "jsx": true
11 | }
12 | },
13 | "globals": {},
14 | "rules": {
15 | "block-scoped-var": 0,
16 | "camelcase": 0,
17 | "comma-spacing": [1, {"before": false, "after": true}],
18 | "consistent-return": 2,
19 | "curly": [2, "all"],
20 | "dot-notation": [1, { "allowKeywords": true }],
21 | "eqeqeq": [2, "allow-null"],
22 | "global-strict": [0, "never"],
23 | "guard-for-in": 2,
24 | "indent": [1, 2, {"SwitchCase": 1, "VariableDeclarator": 1}],
25 | "lines-around-comment": [1, {
26 | "beforeBlockComment": true,
27 | "beforeLineComment": true,
28 | "allowBlockStart": true,
29 | "allowObjectStart": true,
30 | "allowArrayStart": true
31 | }],
32 | "key-spacing": 0,
33 | "keyword-spacing": 1,
34 | "new-cap": 0,
35 | "no-alert": 2,
36 | "no-bitwise": 2,
37 | "no-caller": 2,
38 | "no-cond-assign": [2, "except-parens"],
39 | "no-debugger": 2,
40 | "no-dupe-args": 2,
41 | "no-dupe-keys": 2,
42 | "no-empty": 2,
43 | "no-eval": 2,
44 | "no-extend-native": 2,
45 | "no-extra-bind": 2,
46 | "no-extra-parens": 0,
47 | "no-extra-semi": 2,
48 | "no-func-assign": 2,
49 | "no-implied-eval": 2,
50 | "no-invalid-regexp": 2,
51 | "no-irregular-whitespace": 1,
52 | "no-iterator": 2,
53 | "no-loop-func": 2,
54 | "no-mixed-requires": 0,
55 | "no-multi-str": 2,
56 | "no-multi-spaces": 1,
57 | "no-native-reassign": 2,
58 | "no-new": 2,
59 | "no-param-reassign": 1,
60 | "no-proto": 2,
61 | "no-redeclare": 0,
62 | "no-script-url": 2,
63 | "no-self-assign": 2,
64 | "no-self-compare": 2,
65 | "no-sequences": 2,
66 | "no-shadow": 2,
67 | "no-undef": 2,
68 | "no-underscore-dangle": 0,
69 | "no-unreachable": 1,
70 | "no-unused-vars": 1,
71 | "no-use-before-define": 1,
72 | "no-useless-call": 2,
73 | "no-useless-concat": 2,
74 | "no-with": 2,
75 | "quotes": [0, "single"],
76 | "radix": 2,
77 | "semi": [0, "never"],
78 | "strict": 0,
79 | "space-before-blocks": 1,
80 | "space-before-function-paren": [1, {
81 | "anonymous": "always",
82 | "named": "never"
83 | }],
84 | "space-in-parens": [1, "never"],
85 | "space-infix-ops": 1,
86 | "valid-typeof": 2,
87 | "vars-on-top": 0,
88 | "wrap-iife": [2, "inside"]
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/lib/engine_react.js:
--------------------------------------------------------------------------------
1 | /*
2 | * react pattern engine for patternlab-node - v0.1.0 - 2016
3 | *
4 | * Geoffrey Pursell, Brian Muenzenmeyer, and the web community.
5 | * Licensed under the MIT license.
6 | *
7 | * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.
8 | *
9 | */
10 |
11 |
12 | "use strict";
13 |
14 | const fs = require('fs');
15 | const path = require('path');
16 | const React = require('react');
17 | const ReactDOMServer = require('react-dom/server');
18 | const Babel = require('babel-core');
19 | const Hogan = require('hogan.js');
20 | const beautify = require('js-beautify');
21 | const cheerio = require('cheerio');
22 |
23 | const outputTemplate = Hogan.compile(
24 | fs.readFileSync(
25 | path.join(__dirname, './outputTemplate.mustache'),
26 | 'utf8'
27 | )
28 | );
29 |
30 | var engine_react = {
31 | engine: React,
32 | engineName: 'react',
33 | engineFileExtension: '.jsx',
34 |
35 | // hell no
36 | expandPartials: false,
37 |
38 | // regexes, stored here so they're only compiled once
39 | findPartialsRE: null,
40 | findPartialsWithStyleModifiersRE: null,
41 | findPartialsWithPatternParametersRE: null,
42 | findListItemsRE: null,
43 | findPartialRE: null,
44 |
45 | // render it
46 | renderPattern(pattern, data, partials) {
47 | try {
48 | /* eslint-disable no-eval */
49 | const componentString = pattern.template || pattern.extendedTemplate;
50 | const nodeComponent = Babel.transform(componentString, {
51 | presets: [ require('babel-preset-react') ],
52 | plugins: [ require('babel-plugin-transform-es2015-modules-commonjs') ]
53 | });
54 | const runtimeComponent = Babel.transform(componentString, {
55 | presets: [ require('babel-preset-react') ],
56 | plugins: [[require('babel-plugin-transform-es2015-modules-umd'), {
57 | globals: {
58 | "react": "React"
59 | }
60 | }]]
61 | });
62 | const Component = React.createFactory(eval(nodeComponent.code));
63 |
64 | return outputTemplate.render({
65 | patternPartial: pattern.patternPartial,
66 | json: JSON.stringify(data),
67 | htmlOutput: ReactDOMServer.renderToStaticMarkup(Component(data)),
68 | runtimeCode: runtimeComponent.code
69 | });
70 | }
71 | catch (e) {
72 | console.log("Error rendering React pattern.", e);
73 | return "";
74 | }
75 | },
76 |
77 | /**
78 | * Find regex matches within both pattern strings and pattern objects.
79 | *
80 | * @param {string|object} pattern Either a string or a pattern object.
81 | * @param {object} regex A JavaScript RegExp object.
82 | * @returns {array|null} An array if a match is found, null if not.
83 | */
84 | patternMatcher(pattern, regex) {
85 | var matches;
86 | if (typeof pattern === 'string') {
87 | matches = pattern.match(regex);
88 | } else if (typeof pattern === 'object' && typeof pattern.template === 'string') {
89 | matches = pattern.template.match(regex);
90 | }
91 | return matches;
92 | },
93 |
94 | // find and return any {{> template-name }} within pattern
95 | findPartials(pattern) {
96 | return [];
97 | },
98 | findPartialsWithStyleModifiers(pattern) {
99 | return [];
100 | },
101 |
102 | // returns any patterns that match {{> value(foo:"bar") }} or {{>
103 | // value:mod(foo:"bar") }} within the pattern
104 | findPartialsWithPatternParameters(pattern) {
105 | return [];
106 | },
107 | findListItems(pattern) {
108 | return [];
109 | },
110 |
111 | // given a pattern, and a partial string, tease out the "pattern key" and
112 | // return it.
113 | findPartial(partialString) {
114 | return [];
115 | },
116 |
117 | rawTemplateCodeFormatter(unformattedString) {
118 | return beautify(unformattedString, {e4x: true, indent_size: 2});
119 | },
120 |
121 | renderedCodeFormatter(unformattedString) {
122 | return unformattedString;
123 | },
124 |
125 | markupOnlyCodeFormatter(unformattedString, pattern) {
126 | const $ = cheerio.load(unformattedString);
127 | return beautify.html($('.reactPatternContainer').html(), {indent_size: 2});
128 | },
129 |
130 | /**
131 | * Add custom output files to the pattern output
132 | * @param {object} patternlab - the global state object
133 | * @returns {(object|object[])} - an object or array of objects,
134 | * each with two properties: path, and content
135 | */
136 | addOutputFiles(paths, patternlab) {
137 | return [];
138 | }
139 | };
140 |
141 | module.exports = engine_react;
142 |
--------------------------------------------------------------------------------