From aec693e0b362aa2a0442466b459b69e0901d9bc4 Mon Sep 17 00:00:00 2001 From: animesh10 Date: Fri, 10 Mar 2017 10:21:35 -0800 Subject: [PATCH] Include component generator into the App Generator (#217) * move component generator * update component generator index * remove unused dependency * updating Readme * add createDirectory * update component generator changes * remove absolute path to node modules * upstream changes, single quotes * upstream changes --- packages/generator-electrode/README.md | 43 +- .../generator-electrode/component/index.js | 173 ++++++ .../component/templates/_gulpfile.js | 32 ++ .../component/templates/_package.json | 39 ++ .../component/templates/_readme.md | 60 ++ .../component/templates/babelrc | 3 + .../component/templates/demo/_demo.css | 4 + .../component/templates/demo/_demo.jsx | 34 ++ .../component/templates/demo/eslintrc | 3 + .../demo/examples/_component.example | 1 + .../component/templates/editorconfig | 14 + .../component/templates/eslintrc | 8 + .../component/templates/example/_example.js | 15 + .../component/templates/example/_index.html | 22 + .../component/templates/example/example.less | 57 ++ .../component/templates/example/gitignore | 5 + .../component/templates/gitignore | 514 ++++++++++++++++++ .../component/templates/npmignore | 28 + .../component/templates/src/_Component.js | 1 + .../templates/src/components/_component.jsx | 21 + .../templates/src/lang/_DefaultMessages.js | 20 + .../component/templates/src/lang/_en.json | 4 + .../src/lang/tenants/asda/_defaultMessages.js | 11 + .../tenants/electrodeio/_defaultMessages.js | 11 + .../lang/tenants/samsclub/_defaultMessages.js | 11 + .../lang/tenants/walmart/_defaultMessages.js | 11 + .../templates/src/styles/_component.css | 14 + .../client/components/_component.spec.jsx | 20 + .../helpers/_intlEnzymeTestHelper.js | 45 ++ .../component/templates/test/client/eslintrc | 10 + packages/generator-electrode/package.json | 3 +- 31 files changed, 1235 insertions(+), 2 deletions(-) create mode 100644 packages/generator-electrode/component/index.js create mode 100644 packages/generator-electrode/component/templates/_gulpfile.js create mode 100644 packages/generator-electrode/component/templates/_package.json create mode 100644 packages/generator-electrode/component/templates/_readme.md create mode 100644 packages/generator-electrode/component/templates/babelrc create mode 100644 packages/generator-electrode/component/templates/demo/_demo.css create mode 100644 packages/generator-electrode/component/templates/demo/_demo.jsx create mode 100644 packages/generator-electrode/component/templates/demo/eslintrc create mode 100644 packages/generator-electrode/component/templates/demo/examples/_component.example create mode 100644 packages/generator-electrode/component/templates/editorconfig create mode 100644 packages/generator-electrode/component/templates/eslintrc create mode 100644 packages/generator-electrode/component/templates/example/_example.js create mode 100644 packages/generator-electrode/component/templates/example/_index.html create mode 100644 packages/generator-electrode/component/templates/example/example.less create mode 100644 packages/generator-electrode/component/templates/example/gitignore create mode 100644 packages/generator-electrode/component/templates/gitignore create mode 100644 packages/generator-electrode/component/templates/npmignore create mode 100644 packages/generator-electrode/component/templates/src/_Component.js create mode 100644 packages/generator-electrode/component/templates/src/components/_component.jsx create mode 100644 packages/generator-electrode/component/templates/src/lang/_DefaultMessages.js create mode 100644 packages/generator-electrode/component/templates/src/lang/_en.json create mode 100644 packages/generator-electrode/component/templates/src/lang/tenants/asda/_defaultMessages.js create mode 100644 packages/generator-electrode/component/templates/src/lang/tenants/electrodeio/_defaultMessages.js create mode 100644 packages/generator-electrode/component/templates/src/lang/tenants/samsclub/_defaultMessages.js create mode 100644 packages/generator-electrode/component/templates/src/lang/tenants/walmart/_defaultMessages.js create mode 100644 packages/generator-electrode/component/templates/src/styles/_component.css create mode 100644 packages/generator-electrode/component/templates/test/client/components/_component.spec.jsx create mode 100644 packages/generator-electrode/component/templates/test/client/components/helpers/_intlEnzymeTestHelper.js create mode 100644 packages/generator-electrode/component/templates/test/client/eslintrc diff --git a/packages/generator-electrode/README.md b/packages/generator-electrode/README.md index 95b138c02..817f56d20 100644 --- a/packages/generator-electrode/README.md +++ b/packages/generator-electrode/README.md @@ -1,7 +1,7 @@ # generator-electrode [![NPM version][npm-image]][npm-url] [![Dependency Status][daviddm-image]][daviddm-url] [![devDependency Status][daviddm-dev-image]][daviddm-dev-url] [![npm downloads][npm-downloads-image]][npm-downloads-url] -> Generate Electrode ~~Isomorphic~~ Universal React App with NodeJS backend. +> Generate Electrode ~~Isomorphic~~ Universal React App with NodeJS backend or a React component with useful gulp tasks for development, building and publishing. ## Installation @@ -42,6 +42,47 @@ Some common ones: - `gulp server-prod` - start server in production mode - `gulp check` - run unit tests with coverage +## Generating a React Component + Install the generator if you haven't already: + + ```bash + npm install -g generator-electrode + ``` + + Then run the generator: + + ```bash + yo electrode:component + ``` + +...and follow the prompts. + +## Developing Your Component + +### Source + +Your component source code is in `src`. You can use JSX and ES6 syntax freely in +your component source; it will be transpiled to `lib` with Babel before being +published to npm so that your users will simply be able to include it. + +It's a great idea to add a description, documentation and other information to +your `README.md` file, to help people who are interested in using your +component. + +### Example and Preview + +Preview your component with LiveReload: + +```bash +gulp demo ; gulp open-demo +``` + +A webserver will be started on [localhost:4000](http://127.0.0.1:4000) running +the examples in `demo/examples/*` + +You can use this code-playground to test your component, then publish it to let +potential users try out your component and see what it can do. + ## Getting To Know Yeoman * Yeoman has a heart of gold. diff --git a/packages/generator-electrode/component/index.js b/packages/generator-electrode/component/index.js new file mode 100644 index 000000000..550f5efa2 --- /dev/null +++ b/packages/generator-electrode/component/index.js @@ -0,0 +1,173 @@ +"use strict"; + +var _ = require("lodash"); +var chalk = require("chalk"); +var yeoman = require("yeoman-generator"); +var path = require('path'); +var extend = _.merge; +var parseAuthor = require('parse-author'); + +var ReactComponentGenerator = yeoman.Base.extend({ + constructor: function () { + yeoman.Base.apply(this, arguments); + }, + initializing: function () { + this.pkg = this.fs.readJSON(this.destinationPath('package.json'), {}); + + // Pre set the default props from the information we have at this point + this.props = { + packageName: this.pkg.name + }; + + if (_.isObject(this.pkg.author)) { + this.props.developerName = this.pkg.author.name; + this.props.createDirectory = true; + } else if (_.isString(this.pkg.author)) { + var info = parseAuthor(this.pkg.author); + this.props.developerName = info.name; + } + }, + prompting: { + greeting: function () { + this.log( + "\n" + chalk.bold.underline("Welcome to the Electrode Component Generator") + + "\n" + + "\nWe're going to set up a new " + chalk.bold("Electrode") + " component, ready for development with" + + "\n" + chalk.bold("gulp, webpack, demo, electrode component archetype, and live-reload") + ); + }, + askFor: function () { + if (this.pkg.name || this.options.name) { + this.props.name = this.pkg.name || _.kebabCase(this.options.name); + } + var prompts = [{ + type: "input", + name: "projectName", + message: "What is your Package/GitHub project name? (e.g., 'wysiwyg-component')", + default: "wysiwyg-component" + }, + { + type: "input", + name: "packageName", + message: "What is the ClassName for your component?", + default: this.props.componentName + }, { + type: "input", + name: "packageName", + message: "What will be the npm package name?", + default: this.props.packageName + }, { + type: "input", + name: "packageGitHubOrg", + message: "What will be the GitHub organization username (e.g., 'walmartlabs')?", + default: this.props.packageGitHubOrg + }, { + type: "input", + name: "developerName", + message: "What is your name? (for copyright notice, etc.)", + default: this.props.developerName + }, + { + type: "input", + name: "ghUser", + message: "What is your GitHub Username?", + default: this.props.developerName + }, { + type: "list", + name: "quoteType", + message: "Use double quotes or single quotes?", + choices: ["\"", "'"], + default: "\"" + }, { + type: "input", + name: "ghRepo", + message: "What is the name of the GitHub repo where this will be published?", + default: this.packageName + }, { + type: "confirm", + name: "createDirectory", + message: "Would you like to create a new directory for your project?", + default: true + }]; + return this.prompt(prompts).then((props) => { + this.props = extend(this.props, props); + this.projectName = this.props.projectName; + this.packageName = this.props.projectName; + this.developerName = this.props.developerName.split(" ").map(_.toLower).join(""); + this.quoteType = this.props.quoteType; + this.ghUser = this.props.ghUser; + this.ghRepo = this.props.ghRepo; + this.packageGitHubOrg = this.props.packageGitHubOrg; + this.createDirectory = this.props.createDirectory; + this.componentName = _.kebabCase(_.deburr(this.props.projectName)) + .replace(/^\s+|\s+$/g, "") + .replace(/(^|[-_ ])+(.)/g, function (match, first, second) { + return second.toUpperCase(); + }); + this.currentYear = new Date().getFullYear(); + if (this.props.createDirectory) { + var newRoot = this.destinationPath() + '/' + this.packageName; + this.destinationRoot(newRoot); + } + }); + } + }, + + writing: { + project: function () { + this.copy("babelrc", ".babelrc"); + this.copy("gitignore", ".gitignore"); + this.copy("npmignore", ".npmignore"); + this.copy("editorconfig", ".editorconfig"); + if (this.quoteType === "'") { + this.template("eslintrc", ".eslintrc"); + } + this.template("_gulpfile.js", "gulpfile.js"); + this.template("_package.json", "package.json"); + this.template("_readme.md", "README.md"); + }, + component: function () { + this.template("src/components/_component.jsx", "src/components/" + this.projectName + ".jsx"); + this.template("src/styles/_component.css", "src/styles/" + this.projectName + ".css"); + + // l10n language templates + this.template("src/lang/_DefaultMessages.js", "src/lang/default-messages.js"); + this.template("src/lang/_en.json", "src/lang/en.json"); + this.template("src/lang/tenants/electrodeio/_defaultMessages.js", "src/lang/tenants/electrodeio/default-messages.js"); + + this.template("src/_Component.js", "src/index.js"); + }, + test: function () { + this.template("test/client/eslintrc", "test/client/.eslintrc"); + this.template("test/client/components/_component.spec.jsx", "test/client/components/" + this.projectName + ".spec.jsx"); + this.copy("test/client/components/helpers/_intlEnzymeTestHelper.js", "test/client/components/helpers/intl-enzyme-test-helper.js"); + }, + demo: function () { + this.template("demo/_demo.jsx", "demo/demo.jsx"); + this.template("demo/_demo.css", "demo/demo.css"); + this.template("demo/examples/_component.example", "demo/examples/" + this.projectName + ".example"); + } + }, + + install: function () { + this.npmInstall(); + }, + + end: function () { + if (this.quoteType === "'") { + this.spawnCommandSync("node_modules/.bin/eslint", ["--fix", "src", "demo", "example", "test", "--ext", ".js,.jsx"]); + } + var chdir = this.createDirectory ? "'cd " + this.packageName + "' then " : ""; + this.log( + "\n" + chalk.green.underline("Your new Electrode component is ready!") + + "\n" + + "\nYour component is in src/ and your demo files are in demo/" + + "\n" + + "\nType " + chdir + "'gulp demo' to run the development build and demo tasks." + + "\n" + ); + } + +}); + +module.exports = ReactComponentGenerator; diff --git a/packages/generator-electrode/component/templates/_gulpfile.js b/packages/generator-electrode/component/templates/_gulpfile.js new file mode 100644 index 000000000..50ca29d8d --- /dev/null +++ b/packages/generator-electrode/component/templates/_gulpfile.js @@ -0,0 +1,32 @@ +"use strict"; + +const exec = require("electrode-gulp-helper").exec; + +/** + * There is a full range of gulp tasks defined in the above archetype + * but below is a concise list of most often used gulp tasks at the + * component level + * + * Full list of gulp tasks: + * https://github.com/electrode-io/electrode-archetype-react-component/blob/master/archetype-gulpfile.js#L38-L134 + * + */ + +const tasks = { + "demo": ["generate", "server-dev"], + "demo-iso": ["dev-iso"], + "generate": ["generate-metadata", "generate-documentation"], + "generate-documentation": () => exec(`electrode-docgen --package ./package.json --src ./src --markdown components.md`), + "generate-metadata": () => exec(`electrode-docgen --package ./package.json --src ./src --metadata components.json`), + <% if (quoteType === "'") { %> + 'archetype:lint-server': () => exec(`eslint --color -c ./.eslintrc config/karma config/webpack demo-server`), + "lint-react-demo": () => exec(`eslint --ext .js,.jsx -c ./.eslintrc demo/*.jsx --color`), + "lint-react-src": () => exec(`eslint --ext .js,.jsx -c ./.eslintrc src --color`), + "lint-scripts": () => exec(`eslint --ext .js -c ./.eslintrc scripts --color`), + "lint-react-test": () => exec(`eslint --ext .js,.jsx -c ./test/client/.eslintrc test/client --color`), + <% } %> + "prepublish": ["npm:prepublish"], + "preversion": ["check-cov"] +}; + +require("electrode-archetype-react-component")(tasks); diff --git a/packages/generator-electrode/component/templates/_package.json b/packages/generator-electrode/component/templates/_package.json new file mode 100644 index 000000000..c1cccc2a3 --- /dev/null +++ b/packages/generator-electrode/component/templates/_package.json @@ -0,0 +1,39 @@ +{ + "name": "<%= packageName %>", + "version": "1.0.0", + "description": "<%= projectName %>", + "main": "lib/index.js", + "author": { + "name": "<%= developerName %>", + "url": "https://github.com/<%= ghUser %>" + }, + "repository": { + "type": "git", + "url": "https://github.com/<%= packageGitHubOrg %>/<%= ghRepo %>.git" + }, + "bugs": { + "url": "https://github.com/<%= packageGitHubOrg %>/<%= ghRepo %>/issues" + }, + "homepage": "https://github.com/<%= packageGitHubOrg %>/<%= ghRepo %>", + "dependencies": {}, + "devDependencies": { + "electrode-archetype-react-component": "^1.0.0", + "electrode-archetype-react-component-dev": "^1.0.0", + "gulp": "^3.9.1" + }, + "engines": { + "node": "^4.2.6", + "npm": "^3.5.3" + }, + "scripts": { + "prepublish": "gulp prepublish", + "start": "gulp demo", + "test": "gulp check" + }, + "keywords": [ + "react", + "electrode", + "electrode-component", + "react-component" + ] +} diff --git a/packages/generator-electrode/component/templates/_readme.md b/packages/generator-electrode/component/templates/_readme.md new file mode 100644 index 000000000..6a4f04a44 --- /dev/null +++ b/packages/generator-electrode/component/templates/_readme.md @@ -0,0 +1,60 @@ +# <%= projectName %> + +__COMPONENT DESCRIPTION GOES HERE__ + + +## Demo & Examples + +Live demo: [<%= ghUser %>.github.io/<%= packageName %>](http://<%= ghUser %>.github.io/<%= packageName %>/) + +To build the examples locally, run: + +``` +npm install +npm start +``` + +Then open [`localhost:8000`](http://localhost:8000) in a browser. + + +## Installation + +The easiest way to use <%= packageName %> is to install it from NPM and include it in your own React build process (using [Browserify](http://browserify.org), [Webpack](http://webpack.github.io/), etc). + +You can also use the standalone build by including `dist/<%= packageName %>.js` in your page. If you use this, make sure you have already included React, and it is available as a global variable. + +``` +npm install <%= packageName %> --save +``` + + +## Usage + +__EXPLAIN USAGE HERE__ + +``` +var <%= componentName %> = require('<%= packageName %>'); + +<<%= componentName %>>Example> +``` + +### Properties + +* __DOCUMENT PROPERTIES HERE__ + +### Notes + +__ADDITIONAL USAGE NOTES__ + + +## Development (`src`, `lib` and the build process) + +**NOTE:** The source code for the component is in `src`. A transpiled CommonJS version (generated with Babel) is available in `lib` for use with node.js, browserify and webpack. A UMD bundle is also built to `dist`, which can be included without the need for any build system. + +To build, watch and serve the examples (which will also watch the component source), run `npm start`. If you just want to watch changes to `src` and rebuild `lib`, run `npm run watch` (this is useful if you are working with `npm link`). + +## License + +__PUT LICENSE HERE__ + +Copyright (c) <%= currentYear %> <%= developerName %>. diff --git a/packages/generator-electrode/component/templates/babelrc b/packages/generator-electrode/component/templates/babelrc new file mode 100644 index 000000000..0c48bf401 --- /dev/null +++ b/packages/generator-electrode/component/templates/babelrc @@ -0,0 +1,3 @@ +{ + "extends": "./node_modules/electrode-archetype-react-component/config/babel/.babelrc" +} diff --git a/packages/generator-electrode/component/templates/demo/_demo.css b/packages/generator-electrode/component/templates/demo/_demo.css new file mode 100644 index 000000000..a0bc57e6f --- /dev/null +++ b/packages/generator-electrode/component/templates/demo/_demo.css @@ -0,0 +1,4 @@ +/* Component styles */ +.demoStyle { + composes: className from "../src/styles/<%= projectName %>.css"; +} diff --git a/packages/generator-electrode/component/templates/demo/_demo.jsx b/packages/generator-electrode/component/templates/demo/_demo.jsx new file mode 100644 index 000000000..bf8f29e80 --- /dev/null +++ b/packages/generator-electrode/component/templates/demo/_demo.jsx @@ -0,0 +1,34 @@ +/*@flow*/ + +import React from "react"; +import { addLocaleData, IntlProvider } from "react-intl"; +import Demo from "electrode-demo-index"; + +import * as libraryScope from "../src/index"; + +const locale = "en"; +const messages = require(`../src/lang/${locale}.json`); +const localeData = require(`react-intl/locale-data/${locale}`); + +addLocaleData(localeData); + +const localScope = { IntlProvider, messages, locale }; + +const components = [ + { + title: "<%= componentName %>", + examples: [ + { + type: "playground", + code: require("raw!./examples/<%= projectName %>.example"), + noRender: true + } + ] + } +]; + +const demo = () => ( + +); + +export default demo; diff --git a/packages/generator-electrode/component/templates/demo/eslintrc b/packages/generator-electrode/component/templates/demo/eslintrc new file mode 100644 index 000000000..be0115c56 --- /dev/null +++ b/packages/generator-electrode/component/templates/demo/eslintrc @@ -0,0 +1,3 @@ +--- +extends: + - "../node_modules/electrode-archetype-react-component/config/eslint/.eslintrc-react-demo" diff --git a/packages/generator-electrode/component/templates/demo/examples/_component.example b/packages/generator-electrode/component/templates/demo/examples/_component.example new file mode 100644 index 000000000..9241e0e01 --- /dev/null +++ b/packages/generator-electrode/component/templates/demo/examples/_component.example @@ -0,0 +1 @@ +<<%= componentName %> /> diff --git a/packages/generator-electrode/component/templates/editorconfig b/packages/generator-electrode/component/templates/editorconfig new file mode 100644 index 000000000..1f38c5e77 --- /dev/null +++ b/packages/generator-electrode/component/templates/editorconfig @@ -0,0 +1,14 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/packages/generator-electrode/component/templates/eslintrc b/packages/generator-electrode/component/templates/eslintrc new file mode 100644 index 000000000..e8b3a6b49 --- /dev/null +++ b/packages/generator-electrode/component/templates/eslintrc @@ -0,0 +1,8 @@ +--- +extends: + - "./node_modules/electrode-archetype-react-component/config/eslint/.eslintrc-react" + +rules: + quotes: + - 2 + - "single" diff --git a/packages/generator-electrode/component/templates/example/_example.js b/packages/generator-electrode/component/templates/example/_example.js new file mode 100644 index 000000000..59a388156 --- /dev/null +++ b/packages/generator-electrode/component/templates/example/_example.js @@ -0,0 +1,15 @@ +var React = require('react'); +var ReactDOM = require('react-dom'); +var <%= componentName %> = require('<%= packageName %>'); + +var App = React.createClass({ + render () { + return ( +
+ <<%= componentName %> /> +
+ ); + } +}); + +ReactDOM.render(, document.getElementById('app')); diff --git a/packages/generator-electrode/component/templates/example/_index.html b/packages/generator-electrode/component/templates/example/_index.html new file mode 100644 index 000000000..ab86feaef --- /dev/null +++ b/packages/generator-electrode/component/templates/example/_index.html @@ -0,0 +1,22 @@ + + + <%= projectName %> + + + +
+

<%= projectName %>

+

View project on GitHub

+ +
+
+ +
+ +
+ + + + diff --git a/packages/generator-electrode/component/templates/example/example.less b/packages/generator-electrode/component/templates/example/example.less new file mode 100644 index 000000000..446e1cbd9 --- /dev/null +++ b/packages/generator-electrode/component/templates/example/example.less @@ -0,0 +1,57 @@ +/* +// Examples Stylesheet +// ------------------- +*/ + +body { + font-family: Helvetica Neue, Helvetica, Arial, sans-serif; + font-size: 14px; + color: #333; + margin: 0; + padding: 0; +} + +a { + color: #08c; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +.container { + margin-left: auto; + margin-right: auto; + max-width: 720px; + padding: 1em; +} + +.footer { + margin-top: 50px; + border-top: 1px solid #eee; + padding: 20px 0; + font-size: 12px; + color: #999; +} + +h1, h2, h3, h4, h5, h6 { + color: #222; + font-weight: 100; + margin: 0.5em 0; +} + +label { + color: #999; + display: inline-block; + font-size: 0.85em; + font-weight: bold; + margin: 1em 0; + text-transform: uppercase; +} + +.hint { + margin: 15px 0; + font-style: italic; + color: #999; +} diff --git a/packages/generator-electrode/component/templates/example/gitignore b/packages/generator-electrode/component/templates/example/gitignore new file mode 100644 index 000000000..c33fa2833 --- /dev/null +++ b/packages/generator-electrode/component/templates/example/gitignore @@ -0,0 +1,5 @@ +## This file is here to ensure it is included in the gh-pages branch, +## when `gulp deploy` is used to push updates to the demo site. + +# Dependency directory +node_modules diff --git a/packages/generator-electrode/component/templates/gitignore b/packages/generator-electrode/component/templates/gitignore new file mode 100644 index 000000000..0918b45e5 --- /dev/null +++ b/packages/generator-electrode/component/templates/gitignore @@ -0,0 +1,514 @@ + +# Created by https://www.gitignore.io/api/osx,windows,linux,xcode,objective-c,swift,android,java,jetbrains,eclipse,sublimetext,node,vim,netbeans,emacs,vagrant,textmate,otto,gradle + +### OSX ### +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + + +### Windows ### +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + + +### Xcode ### +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata + +## Other +*.xccheckout +*.moved-aside +*.xcuserstate + + +### Objective-C ### +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata + +## Other +*.xccheckout +*.moved-aside +*.xcuserstate +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md + +fastlane/report.xml +fastlane/screenshots + +### Objective-C Patch ### +*.xcscmblueprint + + +### Swift ### +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata + +## Other +*.xccheckout +*.moved-aside +*.xcuserstate +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md + +fastlane/report.xml +fastlane/screenshots + + +### Android ### +# Built application files +*.apk +*.ap_ + +# Files for the Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +### Android Patch ### +gen-external-apklibs + + +### Java ### +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + + +### JetBrains ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm + +*.iml + +## Directory-based project format: +.idea/ +# if you remove the above rule, at least ignore the following: + +# User-specific stuff: +# .idea/workspace.xml +# .idea/tasks.xml +# .idea/dictionaries +# .idea/shelf + +# Sensitive or high-churn files: +# .idea/dataSources.ids +# .idea/dataSources.xml +# .idea/sqlDataSources.xml +# .idea/dynamic.xml +# .idea/uiDesigner.xml + +# Gradle: +# .idea/gradle.xml +# .idea/libraries + +# Mongo Explorer plugin: +# .idea/mongoSettings.xml + +## File-based project format: +*.ipr +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + + +### Eclipse ### +*.pydevproject +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath + +# Eclipse Core +.project + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Java annotation processor (APT) +.factorypath + +# PDT-specific +.buildpath + +# sbteclipse plugin +.target + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + + +### SublimeText ### +# cache files for sublime text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# workspace files are user-specific +*.sublime-workspace + +# project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using SublimeText +# *.sublime-project + +# sftp configuration file +sftp-config.json + + +### Node ### +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git +node_modules + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + + +### Vim ### +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +*.un~ +Session.vim +.netrwhist +*~ + + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +nbactions.xml +.nb-gradle/ + + +### Emacs ### +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ + + +### Vagrant ### +.vagrant/ + + +### TextMate ### +*.tmproj +*.tmproject +tmtags + + +### Otto ### +.otto/ + + +### Gradle ### +.gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +############################################################################### + +### Automation ### +reports +screenshots +sauce_connect*.txt +*.dmp + +### Walmart Projects ### +lib +dist +tmp + +############################################################################### +#########################_WALMART_STANDARD_GITIGNORE_########################## +############################################################################### +# All changes made above this line are subject to overwrites as the standard # +# .gitignore evolves. Please add any project specific ignores below. # +############################################################################### diff --git a/packages/generator-electrode/component/templates/npmignore b/packages/generator-electrode/component/templates/npmignore new file mode 100644 index 000000000..7c0ac811c --- /dev/null +++ b/packages/generator-electrode/component/templates/npmignore @@ -0,0 +1,28 @@ +# Cruft +*.sublime-workspace +.DS_Store +.AppleDouble +.LSOverride +Icon +._* +.Spotlight-V100 +.Trashes +Thumbs.db +ehthumbs.db +Desktop.ini +$RECYCLE.BIN/ +.tmp +npm-debug.log* + +# Code / build +coverage +node_modules +bower_components +test +karma* +webpack* +.eslint* +.editor* +.travis* + +.idea/ diff --git a/packages/generator-electrode/component/templates/src/_Component.js b/packages/generator-electrode/component/templates/src/_Component.js new file mode 100644 index 000000000..889d3dc80 --- /dev/null +++ b/packages/generator-electrode/component/templates/src/_Component.js @@ -0,0 +1 @@ +export { default as <%= componentName %> } from "./components/<%= projectName %>"; diff --git a/packages/generator-electrode/component/templates/src/components/_component.jsx b/packages/generator-electrode/component/templates/src/components/_component.jsx new file mode 100644 index 000000000..5a9e2bcf7 --- /dev/null +++ b/packages/generator-electrode/component/templates/src/components/_component.jsx @@ -0,0 +1,21 @@ +import React from "react"; +import { FormattedMessage } from "react-intl"; + +import styles from "../../src/styles/<%= projectName %>.css"; +import messages from "../lang/default-messages"; + +export default class <%= componentName %> extends React.Component { + render() { + return ( +
+ +
+ ); + } +} + +<%= componentName %>.displayName = "<%= componentName %>"; + +<%= componentName %>.propTypes = {}; + +<%= componentName %>.defaultProps = {}; diff --git a/packages/generator-electrode/component/templates/src/lang/_DefaultMessages.js b/packages/generator-electrode/component/templates/src/lang/_DefaultMessages.js new file mode 100644 index 000000000..535ed889e --- /dev/null +++ b/packages/generator-electrode/component/templates/src/lang/_DefaultMessages.js @@ -0,0 +1,20 @@ +import { defineMessages } from "react-intl"; + +const $tenant = process.env.ELECTRODE_TENANT; +let tenantMessages; + +try { + tenantMessages = require(`./tenants/${$tenant}/default-messages`); //eslint-disable-line +} catch (err) { + tenantMessages = {}; +} + +const messages = defineMessages({ + editMe: { + description: "Edit this description", + defaultMessage: "Edit me!", + id: "<%= componentName %>.defaultTenant.editMe" + } +}); + +module.exports = Object.assign({}, messages, tenantMessages); diff --git a/packages/generator-electrode/component/templates/src/lang/_en.json b/packages/generator-electrode/component/templates/src/lang/_en.json new file mode 100644 index 000000000..e69f798da --- /dev/null +++ b/packages/generator-electrode/component/templates/src/lang/_en.json @@ -0,0 +1,4 @@ +{ + "<%= componentName %>.walmart.editMe": "Edit Me! Walmart English", + "<%= componentName %>.samsclub.editMe": "Edit Me! samsclub English" +} diff --git a/packages/generator-electrode/component/templates/src/lang/tenants/asda/_defaultMessages.js b/packages/generator-electrode/component/templates/src/lang/tenants/asda/_defaultMessages.js new file mode 100644 index 000000000..37ff78f2f --- /dev/null +++ b/packages/generator-electrode/component/templates/src/lang/tenants/asda/_defaultMessages.js @@ -0,0 +1,11 @@ +import {defineMessages} from "react-intl"; + +const messages = defineMessages({ + editMe: { + description: "Edit this description", + defaultMessage: "Edit me!", + id: "<%= componentName %>.asda.editMe" + } +}); + +module.exports = messages; diff --git a/packages/generator-electrode/component/templates/src/lang/tenants/electrodeio/_defaultMessages.js b/packages/generator-electrode/component/templates/src/lang/tenants/electrodeio/_defaultMessages.js new file mode 100644 index 000000000..f86fb373b --- /dev/null +++ b/packages/generator-electrode/component/templates/src/lang/tenants/electrodeio/_defaultMessages.js @@ -0,0 +1,11 @@ +import {defineMessages} from "react-intl"; + +const messages = defineMessages({ + editMe: { + description: "Edit this description", + defaultMessage: "Edit me!", + id: "<%= componentName %>.electrodeio.editMe" + } +}); + +module.exports = messages; diff --git a/packages/generator-electrode/component/templates/src/lang/tenants/samsclub/_defaultMessages.js b/packages/generator-electrode/component/templates/src/lang/tenants/samsclub/_defaultMessages.js new file mode 100644 index 000000000..26d479fb1 --- /dev/null +++ b/packages/generator-electrode/component/templates/src/lang/tenants/samsclub/_defaultMessages.js @@ -0,0 +1,11 @@ +import {defineMessages} from "react-intl"; + +const messages = defineMessages({ + editMe: { + description: "Edit this description", + defaultMessage: "Edit me!", + id: "<%= componentName %>.samsclub.editMe" + } +}); + +module.exports = messages; diff --git a/packages/generator-electrode/component/templates/src/lang/tenants/walmart/_defaultMessages.js b/packages/generator-electrode/component/templates/src/lang/tenants/walmart/_defaultMessages.js new file mode 100644 index 000000000..80a1a056d --- /dev/null +++ b/packages/generator-electrode/component/templates/src/lang/tenants/walmart/_defaultMessages.js @@ -0,0 +1,11 @@ +import {defineMessages} from "react-intl"; + +const messages = defineMessages({ + editMe: { + description: "Edit this description", + defaultMessage: "Edit me!", + id: "<%= componentName %>.walmart.editMe" + } +}); + +module.exports = messages; diff --git a/packages/generator-electrode/component/templates/src/styles/_component.css b/packages/generator-electrode/component/templates/src/styles/_component.css new file mode 100644 index 000000000..0a7614565 --- /dev/null +++ b/packages/generator-electrode/component/templates/src/styles/_component.css @@ -0,0 +1,14 @@ +:root { + --black: #000; + --white: #fff; +} + +.baseStyle { + background-color: var(--black); + color: var(--white); +} + +.someStyle { + composes: baseStyle; + font-size: 18px; +} diff --git a/packages/generator-electrode/component/templates/test/client/components/_component.spec.jsx b/packages/generator-electrode/component/templates/test/client/components/_component.spec.jsx new file mode 100644 index 000000000..e23270231 --- /dev/null +++ b/packages/generator-electrode/component/templates/test/client/components/_component.spec.jsx @@ -0,0 +1,20 @@ +/** + * Client tests + */ +import React from "react"; +import { shallow } from "enzyme"; + +import <%= componentName %> from "src/components/<%= projectName %>"; + +describe("components/<%= projectName %>", () => { + + describe("Mounting", () => { + + it("should render into the document", () => { + const component = shallow(<<%= componentName %> />); + expect(component).to.not.be.null; + }); + + }); + +}); diff --git a/packages/generator-electrode/component/templates/test/client/components/helpers/_intlEnzymeTestHelper.js b/packages/generator-electrode/component/templates/test/client/components/helpers/_intlEnzymeTestHelper.js new file mode 100644 index 000000000..b24a3e7a2 --- /dev/null +++ b/packages/generator-electrode/component/templates/test/client/components/helpers/_intlEnzymeTestHelper.js @@ -0,0 +1,45 @@ +/** + * Components using the react-intl module require access to the intl context. + * This is not available when mounting single components in Enzyme. + * These helper functions aim to address that and wrap a valid, + * English-locale intl context around them. + */ + +import React from "react"; +import { IntlProvider, intlShape } from "react-intl"; +import { mount, shallow } from "enzyme"; + +// You can pass your messages to the IntlProvider. Optional: remove if unneeded. +const messages = require("src/lang/en.json"); // en.json + +// Create the IntlProvider to retrieve context for wrapping around. +const intlProvider = new IntlProvider({ locale: "en", messages }, {}); +const { intl } = intlProvider.getChildContext(); + +/* + When using React-Intl `injectIntl` on components, props.intl is required. +*/ +const nodeWithIntlProp = (node) => { + return React.cloneElement(node, { intl }); +}; + +const shallowWithIntl = (node) => { + return shallow( + nodeWithIntlProp(node), + { + context: {intl} + } + ); +}; + +const mountWithIntl = (node) => { + return mount( + nodeWithIntlProp(node), + { + context: {intl}, + childContextTypes: { intl: intlShape } + } + ); +}; + +export { nodeWithIntlProp, shallowWithIntl, mountWithIntl }; diff --git a/packages/generator-electrode/component/templates/test/client/eslintrc b/packages/generator-electrode/component/templates/test/client/eslintrc new file mode 100644 index 000000000..c8c019e98 --- /dev/null +++ b/packages/generator-electrode/component/templates/test/client/eslintrc @@ -0,0 +1,10 @@ +--- +extends: + - "electrode-archetype-react-component/config/eslint/.eslintrc-react-test" + +<% if (quoteType === "'") { %> +rules: + quotes: + - 2 + - "single" +<% } %> diff --git a/packages/generator-electrode/package.json b/packages/generator-electrode/package.json index f8da3ac9c..167e102d3 100644 --- a/packages/generator-electrode/package.json +++ b/packages/generator-electrode/package.json @@ -16,7 +16,8 @@ "url": "https://github.com/jchip" }, "files": [ - "generators" + "generators", + "component" ], "main": "generators/index.js", "keywords": [