# web-foundation
> reusable web components for making interfaces within postmates  

### How to start a frontend package
There's a lot of moving pieces required to get you programming with components before an official spec drops from the W3C, but don't fret, we've created some copypasta to help jumpstart the adventure and placed them all in the ```examples``` directory here.

First thing first, the ```webpack.config.js``` file has been abstracted out to a point where you shouldn't have to edit it at all. Just copy it into your new project. All of the configuration is consolidated into the ```project.config.js```.

It's a little specific to how frontend projects get built within django here at postmates, but to set up your static files correctly, edit the project name to match your app name. This will make the compiled output available at ```/static/(js|css|img)/{project}/[entry].[ext]```.

Next, set up your aliases. These allow you to replace ```../../../files/config.js``` with ```files/config```. As code starts to morph and abstractions break down, not having your modules tied to a relative directory structure is a huge time saver.

Lastly, you have to set up your bundles, or what actually compiles. The format is loosely ```bundlename: path/to/kickoff.js```. By adding this and running webpack, you'll find ```bundlename.min.js```, ```bundlename.min.css```, and ```[ img-file-hash ].[ext]``` in their respective static folders.

To make sure that the project is as universal and deployable as the next frontend project in these repos, a ```package.json``` file is also included. Mostly it's just a collection of script commands we're working to normalize around.

### Creating Atoms & Components

An **Atom** is a base level interaction element (checkbox, switch, textarea), whereas a **Component** is a smashing together of atoms (address, user profile). In practice, components usually are data driven (filling out a form or something), where an atom is state driven (this component is on or off).

All components/atoms should have:

- A unique name (enforced by directory structure)
- A less file with the same name as the component
- An index.js file that exports the appropriate View(s) and/or Model(s)

Things to note:

- Filenames should be slugs. i.e. a component calld `TextInput` would have a folder and filename "text-input"
- **Atoms** should have a named export matching the name of the React component (i.e. `TextInput`)
- **Components** should have:
    + the `View` as `default export` (this will be re-exported at the root level as `MyComponentView`)
    + two named exports `Model` and `View` (these will be re-exported at the root level as `MyComponent.Model` and `MyComponent.View`)
    + Any additional named exports will be re-exported as properties of `MyComponent` (similar to `Model` and `View`)

### Transforms

Transforms are functions that add additional functionality to our Atoms and Components. They partially serve the purpose that mixins, decorators, or component inheritance might have served. If you find yourself adding functionality to your react component that you've added before and expect to add again - consider creating a transform.

Example Usage:

```javascript
import FormValidation from 'web-foundation/transforms';

// in constructor of react component
constructor(props) {
    super(props);

    FormValidation(this, /* arguments */);
}
```
