React and ReactDOM (v0.14 or v15) are external dependencies required to use this component.
Card web component written with ES6 modules, classes, and syntax using React to achieve the following goals:
- Reusable and responsively-designed; just drop into DOM node
- Event all interaction
- External styling is bundled with and scoped to the component; targets Bootstrap 3
- Cross-browser for modern browsers [no IE]; thus no style scoped attribute or Shadow DOM encapsulation
- Internationalization using React Intl (thanks to @deepak2510)
[no IE] Uses the native CustomEvent constructor that no version of IE supports (MS Edge does!). This choice was made to reduce complexity and encourage adherence to web standards - add the polyfill if needed.
- Node.js v4+
- webpack
- Bundle javascript, styles and icon
- Babel 6 transpiles ES6 and JSX
- ESLint as configured in .eslintrc
Recommendation: If you are using different node versions on your machine, use nvm to manage them.
Use the following Intl.js polyfill for Safari, which is the only modern browser to not yet implement the ECMAScript Internationalization API:
<script src="https://cdn.polyfill.io/v2/polyfill.js?features=Intl.~locale.en,Intl.~locale.fr"></script>
In webpack, "externals" allows you to specify dependencies that are not resolved by webpack, but become dependencies of the output. This means they are imported from the environment during runtime.
By doing this with React, it reduced the byte size of the bundle from 288521 to 85990 - about a 70% reduction!
After cloning the repo:
cd es6-react-component
npm install
npm run dev
Once bundling is complete, open a browser tab to localhost:8080/demo, and dev.card-component.js is served in memory.
Hot module replacement is activated in the webpack dev server; changes to react_components are automatically reloaded in the browser.
The project is wired to unit test with the Jest framework and Enzyme, a JavaScript testing utility for React that makes it easier to assert, manipulate, and traverse your component's output.
npm test
Source maps are enabled for the webpack dev server. Using Chrome dev tools - open the "Sources" tab, navigate to
top/webpack://./
, and you will find the original source files for which you can set breakpoints in Chrome's debugger.
Optionally, install React developer tools for additional React debugging support in Chrome dev tools under the "React" tab.
Do as described in this section from the consuming application:
> npm i --save es6-react-component react@latest react-dom@latest
The transpiled, minified bundle will be available as /node_modules/es6-react-component/build/dist.card-component.js.
Include it in the consuming page, then event cardstrap
with the container type, e.g.
{ detail: '.container' }
Example JavaScript using CommonJS:
var Cards = require('es6-react-component');
new Cards('.container'); // pass in your container element
Then build the required bundle with webpack (requires installation of correct dependencies, loaders, and config), similar to this webpack.config.js:
module.exports = {
entry: ['./eventing.js'],
output: {
path: './',
filename: 'bundle.js'
},
module: {
loaders: [
{test: /\.css$/, loader: 'style-loader!css-loader'},
{
test: /\.js$/, loader: 'babel', exclude: /node_modules/,
query: {
cacheDirectory: true,
presets: ['es2015', 'react']
}
},
{test: /\.(woff|ttf|eot|svg)(\?[a-z0-9]+)?$/, loader: 'url?limit=100000'},
{test: /\.json$/, loader: 'json'}
]
}
};
After the card component is bootstrapped for a container, each instance is initialized with the initCard
event:
eventedElement.dispatchEvent(new CustomEvent('initCard', {
detail: {
eventedElem: eventedElementId,
targetElem: "div2", // Required
userId: "c685a8ed331c70a47dea8812da69c1bd", // Required
username: "joe.schmo", // Required
bio: "This is Joe's bio.",
avatar: "images/wired.jpg",
locale: "fr-CA"
}
})
);
The following events and data are emitted by each card instance.
CustomEvent | detail |
---|---|
card-bioDeleted | { userId: [sUserId], username: [sUsername] } |
card-liked | { userId: [sUserId], username: [sUsername], likes: [iLikes] } |
card-comment | { userId: [sUserId], username: [sUsername], comment: [sComment] } |