npm package: @mikmak/components
Description: This internal app houses reusable [Vue](https://vuejs.org/) components that can be used across all MikMak web apps. MikMak-Components utilizes [Storybook](https://storybook.js.org/) to develop components in isolation and showcase them to different teams a
Latest version: 0.25.16

# MikMak Component Library and Storybook
This internal app houses reusable [Vue](https://vuejs.org/) components that can be used across all MikMak web apps. MikMak-Components utilizes [Storybook](https://storybook.js.org/) to develop components in isolation and showcase them to different teams and stakeholders.

The latest version of this repo is deployed for viewing at: https://mikmak-components.herokuapp.com/

The package itself is hosted on NPM at: https://www.npmjs.com/package/@mikmak/components

## Using the component library
You can install the component library right into a web app and import a specific or multiple components.

Install using NPM:
```
npm install @mikmak-components
```

Import components locally:
```
import { PrimaryButton, SecondaryButton} from '@mikmak/components'

export default {
  components: { PrimaryButton, SecondaryButton }
}
```

## Contribuiting to the component Library

### Cloning & Setup
```
git clone git@github.com:tipoentertainment/mikmak-components.git
cd mikmak-components
npm i
```

### Developing
To start running storybook locally, simply run: `npm run dev`.

You should now have a local version of storybook running on port [6006](http://localhost:6006).

### Vuetify Material Design Framework
For MikMak-Components utilizing Vuetify components under the hood, there are a few things to note:
1. MikMak-Component wrappers should be built as simple and extensible as possible by severely limiting prop declarations to the absolute minimum required. Use `v-bind="$attrs"` as a direct pass-through for other props available on the Vuetify component, *DO NOT* declare every potental Vuetify prop to a MikMak-Component prop. You can also use `v-on="$listeners"` as a direct pass-through for event listeners.
2. The `vuetify` plugin must be imported and directly exported in any MikMak-Components using Vuetify
3. Any Vuetify components must be wrapped in a `v-app` component within a parent `div` with class `vuetify-styling` to enable intended styling once exported. To prevent Vuetify styles from polluting the global scope, they are processed with PostCSS to apply the `vuetify-styling` prefix wrapper, meaning some styles in consuming applications can show additional styles that might have increased specificity than are defined in MikMak-Components or shown in Storybook. Be sure to use `npm link` to confirm all designs.

_Reference `ToggleV02` as an example of the above_

## Adding a component as an Engineer
An engineer can contribute by adding a component and a corresponding unit test. You can also include a story, which is used to display the component and its documentation.

### Adding a component
You can add your component to `src/components` folders, using `src/styles` tokens wherever possible. Each component should have a corresponding unit test. Then import your component into `main.js`

You can also test your component in the wild (web app of your choice) by using [`npm link`](https://docs.npmjs.com/cli/link).

We use Gitflow when contributing to this project. Check out a branch with name f/nameOfComponent, do your thing, and create a pull request when you're ready to merge.

### Adding a story
You can add a story for your component to `src/stories`.

### Testing
We use [Jest](https://jestjs.io/) framework for unit testing. You can also utilize [Vue Test Utils](https://vue-test-utils.vuejs.org/guides/#getting-started) for easier Vue testing.

To run your tests, run `npm run test`.

If you run into an error with file watching while running these tests, you'll need to update or upgrade your file watcher. On OS X using `brew`, this can be done like so:

```bash
$ brew update
$ brew install watchman
```

## Changing a component as an Engineer
To avoid breaking changes in applications that use MikMak-Components, individual components are now versioned using a simple nested folder structure.

_IMPORTANT: This explains versioning individual components within the folder structure, not the semver versioning of the library as a whole which is always required._

### Does your change require a new version?
No
- Newly added **optional** props
- You are the only user of the version to be updated across all consuming applications and are taking ownership of confirming proper behavior of every instance

Yes
- Modified optional or required props
- Newly added **required** props
- Any other changes

### Adding a new component version
All components are limited to two versions. When additional versions are required, time needs to be allotted for deprecation of older versions throughout all consuming applications.

Components where version folders are already present:
- Create a new folder within the component folder (`vXX`) alongside the previous version, ensuring no more than two versions exist
- Add the new version to `<Component>.stories.js` and `main.js` files
- Follow remaining steps as defined for adding and publishing components

Components where version folders have not yet been added:
- Create a new folder within the component folder (`v01`) and move all original files into the new folder
- Update all references to the original component to reflect the new folder structure required for importing
- *DO NOT* update the export name for `v01` since this would require all consuming applications to also update. All components without versions are understood to be `v01`.
- Create a `v02` folder alongside `v01` and implement your changes there
- Follow remaining steps as defined for adding and publishing components

## Adding Design System documentation as a Designer
A designer can contribute by adding documentation to each component, which outlines its usage and behavior according to MikMak's design system.
To add this documentation for each component:

1. Navigate to stories/Components/[component-name].stories.js
2. Add relavant information to the `Design Template` component. Currently the sections includes usage, behavior and specs. We are using [Vue.js slots](https://vuejs.org/v2/guide/components-slots.html) to pass html into the Design Template. Each template slot corresponds to a specific section. Note, that each file can have multiple stories. Below is an example of the Design Template used in the Primary Button story:

```
<div>
  <DesignTemplate>
    <template v-slot:usage>
    [Designer insert usage HTML here]
    </template>
    <template v-slot:behavior>Behavior Information>
    [Designer insert behavior HTML here]
    </template>
    <template v-slot:specs>
    [Designer insert spec HTML here]
    </template>
  </DesignTemplate>
  <PrimaryButton @click="action">
  Primary Button
  </PrimaryButton>
</div>
```
## Versioning
We use [semantic versioning](https://docs.npmjs.com/about-semantic-versioning) for our package versioning at the library-level. In every PR, before publishing any changes to npm, you need to bump the library's package version in `package.json` and `package-lock.json` so the new npm package does not overwrite one that is already in use and could possibly introduce breaking changes.

How you bump the version will depend on the changes that are being released.
- **Major (X.0.0)**: Breaking change or any major visual change to DS (theme/all colors change, for example)
- **Minor (0.X.0)**: New component or features added, minor visual changes to components. Backwards compatible.
- **Patch (0.0.X)**: Bugs fixes/minor tweaks to existing components. New variants of existing components. Backwards compatible.

## Publishing

In order to publish you need to have an npm account. Once you've created your account ask to be added to the npm MikMak org in the engineering slack channel. Additionally, make sure you have [two-factor authentication enabled](https://docs.npmjs.com/requiring-2fa-for-package-publishing-and-settings-modification) and you are logged into your npm account in your terminal before publishing.

To publish the npm package:
1. Merge your approved PR into `master` through GitHub
1. In your local terminal, checkout the `master` branch
1. Pull down the latest `master`, confirm it includes the changes you just merged as well as an updated package version
1. Run `npm run build-lib`
1. Log into npm account in your terminal (if publishing for first time)
1. Run `npm publish`
1. Confirm the new version is available at https://www.npmjs.com/package/@mikmak/components

## Local Scope (No Publishing)

In order to use the local scope of `mikmak-components` as package dependency in another repo to test changes before/without publishing:

To create local scope:
1. `cd ~/mikmak-components`
2. `npm link`
3. `npm run build-lib  # First time and after every change`
4. `cd ~/project`
5. `npm link @mikmak/components`

To remove local scope:
1. `cd ~/project`
2. `npm uninstall --no-save @mikmak-components && npm install`

You can clean up the global link, though its presence won’t interfere with the application.
1. `cd ~/mikmak-components`
2. `npm uninstall  # Delete global symlink`