diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..3eb97c1d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,151 @@ +# Contributing 💛 + +Thanks so much for helping us develop this project and being a part of the Buffer community. Here are a few guidelines that will help you along the way. + +## Submitting a pull request + +Buffer Shared-Components is an open source project, so pull requests are always welcome, but, before working on a large change, it is best to open an issue first to discuss it with the maintainers. + +When in doubt, try to keep your pull requests small, by not bundling more than one feature or bug fix per pull request :). + +### Branch Structure + +All stable releases are tagged ([view tags](https://github.com/bufferapp/shared-components/tags)), and the `master` branch represents the latest development version of the library. +Patches or hotfix releases are prepared on an independent branch. + + +## Getting started + +Please create a new branch from an up to date master on your fork. + +1. Fork the repository on Github +2. Clone your fork to your local machine `git clone git@github.com:/bufferapp/shared-components.git` +3. Create a branch `git checkout -b my-topic-branch` +4. Make your changes, lint, then push to to GitHub with `git push --set-upstream origin my-topic-branch`. +5. Visit GitHub and make your pull request. + +If you have an existing local repository, please update it before you start, to minimise the chance of merge conflicts. + +```sh +git remote add upstream git@github.com:bufferapp/shared-components.git +git checkout master +git pull upstream master +git checkout -b my-topic-branch +yarn +``` + +### Testing the documentation site + +The documentation site is built with Shared-Components and contains examples of all the components. +To get started: + +```sh +npm run start +``` + +You can now access the documentation site [locally](http://localhost:3000). This script generates the documentation site and watches any changes in the app in order to hot reload the documentation. + + +### Test + +For testing we're using automated snapshot testing with `jest-auto-snapshots`. In order to create a new snapshot test, just create the test file for the given component and add: + +``` +import snap from 'jest-auto-snapshots'; +import MyComponent from '../MyComponent'; + +snap(MyComponent, '../MyComponent.jsx'); +``` + +This will generate snapshot tests for all the different possible rendering state of that component by detecting the different prop types that component uses. + +Tests can be run with `npm run test`. + + +### Building locally + +To build the package locally, run: +```sh +npm run build:lib +``` + +### Coding style + +Please follow the coding style of the project. We use eslint, so if possible, enable linting in your editor to get real-time feedback. The linting rules can be run manually with the following command `npm run lint`. + + +## Adding a new Component + +Our components are organized in folders, in the following structure: + +```sh +src/ # root ++-- components/ # components root + +-- MyComponent/ # component root + -- MyComponent.jsx # React component + -- MyComponent.test.js # Component's test file + -- index.js # default export + -- style.js # component's CSS ++-- docs/ # documentation site components +``` + +When creating a new component, please follow the same structure and create a `.jsx` file for the React component, `index.js` file with the default export (we need this to be able to have nice imports in our components), +a `style.js` with all the style variations for that component, and `test.js` with the snapshot test configuration explained in the [Test](#test) section. + +Here are the basic steps: +- Create a new folder with the component name under components +- In that folder create: + - `ComponentName.jsx` file with the component code, + - `index.js` with the default export, + - `style.js` with components styles using styled-components library + - `ComponentName.test.js` with a snapshot test +- The documentation site should be automatically refreshed and you should see your new component there +- In the examples folder create a new folder named after your component + - add a new file for each version of your component, named `ExampleVersion.jsx` + + +### Styling the Component + +For component styling, we're using the [styled-components](https://www.styled-components.com) library. In the `Button` component example, styles for each button variation (`primary`, `secondary`, `text`...) +and size (`large`, `small`, `default`) are defined in the `style.js` file. Those styles are then imported in the main Button component in order to construct the `styled-component` like this: + +``` +const ButtonStyled = style.div` + ${Styles.buttonbase}; + ${props => Styles[props.size]}; + ${props => Styles[props.type]}; +`; +``` + +Please make sure to use the color, font, border, etc. variables instead of fixed values in CSS. In case the variable you need is not defined, feel free to add it in the corresponding file. + +## Adding Component Documentation + +When you add new folder in components, the documentation system will automatically pick it up and read from the comments and PropTypes in order to create the documentation. +To make the documentation complete, there are a few steps needed for every new component created: + +- Make sure the name of the component file is the same as the name of the folder it's located +- Add a main component description above the component name +- Add a comment for every Prop type +- Add default prop types +- in the `docs/examples` folder create a newfolder named after the component + - in that folder create a new `ExampleComponentType.jsx` file that contains all the different variations of that component, for example + ``` + import React from 'react'; + import Button from '@bufferapp/components/Button'; + + /** Primary type buttons */ + export default function ExamplePrimary() { + return [ + , + , + , + ]; + } + ``` + - this will be shown as three different primary buttons in the documentation together with the code examples + + +## License + +By contributing your code to the bufferapp/shared-components GitHub repository, you agree to license your contribution under the MIT license. \ No newline at end of file diff --git a/LICENCE b/LICENCE new file mode 100644 index 00000000..41e90afc --- /dev/null +++ b/LICENCE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Buffer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index f2b0012d..c1c606cb 100644 --- a/README.md +++ b/README.md @@ -13,301 +13,55 @@

- +[![npm package](https://img.shields.io/npm/v/@bufferapp/components-new/latest.svg)](https://www.npmjs.com/package/@bufferapp/components-new) [![Build Status](https://travis-ci.org/bufferapp/shared-components.svg?branch=master)](https://travis-ci.org/bufferapp/shared-components) -**Hi there!** - Welcome to the official Buffer components library 🎉! This is where we host all the components used by the Buffer applications ([Publish](https://publish.buffer.com), [Analyze](https://analyze.buffer.com) and [Reply](https://reply.buffer.com)), as well as our official [Style Documentation](https://bufferapp.github.io/shared-components/#Button). This library is open source and free for you to explore and use! -If you'd like to dive into our components and learn how to use them in your projects, please head to our ➡️ [Documentation site](https://bufferapp.github.io/shared-components/#Button). - -If you'd like to contribute to this project, keep reading and check out the relevant information below 😊. - - -## Component Development - -In order to start using this project locally, you'll need to clone this repository and install the dependent packages. After that you can checkout our scripts for starting the app, running tests and building the documentation site. - -Here are some useful links to get started with: - -- [Quick Start](#quick-start) -- [Test](#test) -- [Adding a new Component](#adding-a-new-component) -- [FAQ](#faq) - -## Quick Start - -### Install Node Modules - -```sh -npm install -``` - -### Start Documentation App - -```sh -npm start -``` - -This script generates the documentation site and watches any changes in the app in order to hot reload the documentation. - -Open http://localhost:3000 where you'll find the components documentation system. - -## Test - -For testing we're using automated snapshot testing with `jest-auto-snapshots`. In order to create a new snapshot test, just create the test file for the given component and add: - -``` -import snap from 'jest-auto-snapshots'; -import MyComponent from '../MyComponent'; - -snap(MyComponent, '../MyComponent.jsx'); -``` - -This will generate snapshot tests for all the different possible rendering state of that component by detecting the different prop types that component uses. - -### Run Tests - -```sh -npm run test -``` - - -## Adding a new Component - -Our components are organizes in folders, in the following structure: - -```sh -src/ # root -+-- components/ # components root - +-- MyComponent/ # component root - -- MyComponent.jsx # React component - -- MyComponent.test.js # Component's test file - -- index.js # default export - -- style.js # component's CSS -+-- docs/ # documentation site components -``` - -When creating a new component, please follow the same structure and create a `.jsx` file for the React component, `index.js` file with the default export (we need this to be able to have nice imports in our components), -a `style.js` with all the style variations for that component, and `test.js` with the snapshot test configuration explained in the [Test](#test) section. - -Here are the basic steps: -- Create a new folder with the component name under components -- In that folder create: - - `ComponentName.jsx` file with the component code, - - `index.js` with the default export, - - `style.js` with components styles using styled-components library - - `ComponentName.test.js` with a snapshot test -- The documentation site should be automatically refreshed and you should see your new component there -- In the examples folder create a new folder named after your component - - add a new file for each version of your component, named `ExampleVersion.jsx` - - -## Styling the Component - -For component styling, we're using the [styled-components](https://www.styled-components.com) library. In the `Button` component example, styles for each button variation (`primary`, `secondary`, `text`...) -and size (`large`, `small`, `default`) are defined in the `style.js` file. Those styles are then imported in the main Button component in order to construct the `styled-component` like this: - -``` -const ButtonStyled = style.div` - ${Styles.buttonbase}; - ${props => Styles[props.size]}; - ${props => Styles[props.type]}; -`; -``` - -Please make sure to use the color, font, border, etc. variables instead of fixed values in CSS. In case the variable you need is not defined, feel free to add it in the corresponding file. - -## Creating Component Documentation - -When you add new folder in components, the documentation system will automatically pick it up and read from the comments and PropTypes in order to create the documentation. -To make the documentation complete, there are a few steps needed for every new component created: - -- Make sure the name of the component file is the same as the name of the folder it's located -- Add a main component description above the component name -- Add a comment for every Prop type -- Add default prop types -- in the `docs/examples` folder create a newfolder named after the component - - in that folder create a new `ExampleComponentType.jsx` file that contains all the different variations of that component, for example - ``` - import React from 'react'; - import Button from '@bufferapp/components/Button'; - - /** Primary type buttons */ - export default function ExamplePrimary() { - return [ - , - , - , - ]; - } - ``` - - this will be shown as three different primary buttons in the documentation together with the code examples - - -## FAQ - -**What is a component?** - -In the current implementation components are all [functional and stateless](https://medium.com/@housecor/react-stateless-functional-components-nine-wins-you-might-have-overlooked-997b0d933dbc#.ukhlhrqlw). - -This means that UI is a function of state since we're using pure functions to build our views. - -``` -UI = f(state) -``` - -**How do I determine the scope of a component?** +## Installation -This is a tough question, it really depends. But as a general rule, a component should be simple enough to be reusable across multiple applications and be not much longer than 150 lines of code. This is a good one to seek advice if you're not sure. +Buffer Shared Components is available as an `@bufferapp/components-new` [npm package](https://www.npmjs.com/package/@bufferapp/components-new). -**What's the development workflow look like?** -Note: this is *a way* to do this, but not necessarily *the way* to build components. For this workflow let's create a component called `NewComponent`. +## Usage -1. Create a branch with the name of the new component +Here is a quick example to get you started, **it's all you need**: -Note: also make sure you're up to date - -``` -git checkout master -git pull -r -git checkout -b task/add-newcomponent -``` - -2. Install dependencies and start the documentation system - -``` -npm i && npm start -``` - -open http://localhost:3000 in your browser - -3. Create a `NewComponent` folder under `src/components` (see [Adding a new Component](#adding-a-new-component)) -``` -components/ -+-- NewComponent/ -``` - -4. Create the `index.js` file and add the default export -``` -components/ -+-- NewComponent/ - -- index.js -``` - - -5. Create the `style.js` file and add components styles -``` -components/ -+-- NewComponent/ - -- index.js -``` - -6. Create a test file with the snapshot (see [Test](#test) for more information) - -``` -src/ -+-- NewComponent/ - -- NewComponent.test.js -``` - - -6. Implement your component - -``` -import React from 'react'; -import PropTypes from 'prop-types'; -import style from 'styled-components'; -import * as Styles from './style'; - -const NewComponentStyled = style.div` - ${Styles.base}; - ${props => Styles[props.size]}; - ${props => Styles[props.type]}; -`; - -/** Component Description */ -const Button = ({ - children, - prop -}) => ( - - {children} - -); - - -NewComponentStyled.propTypes = { - /** Children node */ - children: PropTypes.node.isRequired, -}; - - -Button.defaultProps = { -}; - - -export default NewComponentStyled; - - -`` - - - -7. Create the `NewComponent` folder under `src/docs` and add the `ExampleNewComponent.jsx` file - -``` +```jsx import React from 'react'; -import NewComponent from '@bufferapp/components/NewComponent'; - -/** NewComponent example */ -export default function ExampleNewComponent() { - return {}}>; +import ReactDOM from 'react-dom'; +import Button from '@bufferapp/components-new/Button'; + +function App() { + return ( + + ); } -``` - -Restart the documentation site! - - -Now when you go to http:localhost:3000 you should see your new component listed 🎉 - -8. Run the test for the first time - -It's important to note that this creates a snapshot of the component. All tests ran in the future will be tested against this snapshot to ensure they haven't changed. - -```sh -npm t +ReactDOM.render(, document.querySelector('#app')); ``` -7. Commit it! -```sh -git add . -git commit -m "Add NewComponent" -git push -u origin task/add-newcomponent -``` +## Documentation -At this point it's a good idea to generate a PR on github :) +Check out our ➡️ [documentation website](https://bufferapp.github.io/shared-components/#Button). -**How do I write tests for a component?** -This automatically happens when you write the first test. They are tested with jest snapshots under the hood. +## Contributing -Since components are [functional and stateless](https://medium.com/@housecor/react-stateless-functional-components-nine-wins-you-might-have-overlooked-997b0d933dbc#.ukhlhrqlw) we can use snapshot testing to get complete coverage. +Want to contribute to this project? That's awesome 🙌! Please check out our [contribution](/CONTRIBUTING.md) doc. :) -You're verifying that each property change has the expected outcome in HTML. +## Changelog -The first time the test is run it generates a new snapshot. The **second** time it's checked against the snapshot. +Curious about the latest changes? +Please read the [changelog](https://github.com/bufferapp/shared-components/releases). -**How Do I Update A Snapshot** -``` -npm run test-update -``` +## License + +This project is licensed under the terms of the +[MIT license](/LICENSE). \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 1077992c..2da13418 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8539,6 +8539,21 @@ "type-check": "~0.3.2" } }, + "license-generator": { + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/license-generator/-/license-generator-0.0.13.tgz", + "integrity": "sha1-RRkekLLMzC4A7/dC4qUiQ68H8n0=", + "requires": { + "commander": "~2.1.0" + }, + "dependencies": { + "commander": { + "version": "2.1.0", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.1.0.tgz", + "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=" + } + } + }, "load-json-file": { "version": "2.0.0", "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",