{"id":14985533,"url":"https://github.com/bufferapp/buffer-components","last_synced_at":"2026-02-01T19:30:16.901Z","repository":{"id":16686596,"uuid":"66678554","full_name":"bufferapp/buffer-components","owner":"bufferapp","description":"Buffer's shared collection of React UI components 🤜🤛","archived":true,"fork":false,"pushed_at":"2024-09-11T23:45:21.000Z","size":3951,"stargazers_count":140,"open_issues_count":12,"forks_count":40,"subscribers_count":36,"default_branch":"master","last_synced_at":"2025-01-10T23:45:58.055Z","etag":null,"topics":["atomic-design","javascript","react","snapshot-testing","storybook"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@bufferapp/components","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bufferapp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-08-26T20:52:10.000Z","updated_at":"2024-09-26T20:21:12.000Z","dependencies_parsed_at":"2024-11-16T02:31:15.761Z","dependency_job_id":"adb2e2dc-0304-4f7d-aef0-c723a07ee20a","html_url":"https://github.com/bufferapp/buffer-components","commit_stats":{"total_commits":467,"total_committers":26,"mean_commits":17.96153846153846,"dds":0.7173447537473233,"last_synced_commit":"ad1d2cd708ea922d43857ad32a6f8c7a17e85ba9"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bufferapp%2Fbuffer-components","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bufferapp%2Fbuffer-components/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bufferapp%2Fbuffer-components/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bufferapp%2Fbuffer-components/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bufferapp","download_url":"https://codeload.github.com/bufferapp/buffer-components/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239493675,"owners_count":19647995,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atomic-design","javascript","react","snapshot-testing","storybook"],"created_at":"2024-09-24T14:11:09.747Z","updated_at":"2026-02-01T19:30:16.860Z","avatar_url":"https://github.com/bufferapp.png","language":"JavaScript","readme":"# Buffer Components\n\n[![Build Status](https://travis-ci.org/bufferapp/buffer-components.svg?branch=master)](https://travis-ci.org/bufferapp/buffer-components)\n\nA shared set of UI Components using React and CSS Modules.\n\nDemo: https://bufferapp.github.io/buffer-components/\n\nTo use this in your project start at the [usage](#usage) section. If you'd like to add to this\nlibrary skip to [component development](#component-development).\n\n## Usage\n\nInstall the package and save the exact version:\n\n```sh\nnpm install @bufferapp/components -SE\n```\n\nNow in your code you can import a specific component:\n\n```js\nimport Button from '@bufferapp/components/Button';\n```\n\n### Requirements\n\nFor the component library you're required to use a few plugins and a valid Webpack config.\n\nFirst, you'll need React installed (0.14 or newer):\n\n```sh\nnpm i react react-dom -SE\n```\n\nIn addition to your Babel configuration (not documented), you'll need the style-loader Webpack plugin:\n\n```sh\nnpm i style-loader -SDE\n```\n\nYour Webpack config should use the proper config, here is an example:\n\n```js\nmodule.exports = {\n  module: {\n    loaders: [\n      {\n        test: /\\.css$/,\n        loaders: [\n          'style-loader',\n        ],\n      },\n    ],\n  },\n};\n```\n\n\n## Component Development\n\n- [Quick Start](#quick-start)\n- [Test](#test)\n- [Component Anatomy](#component-anatomy)\n- [FAQ](#faq)\n\n## Quick Start\n\nInstall Node Modules\n\n```sh\nnpm i\n```\n\nStart React Storybook\n\n```sh\nnpm start\n```\n\nOpen http://localhost:9001\n\n## Test\n\nRun Linter And Test\n\n```sh\nnpm run test\n```\n\nRun Test and watch for changes\n\n```sh\nnpm run test-watch\n```\n\nUpdate Test Snapshots\n\n```sh\nnpm run test-update\n```\n\nNote: only commit these if you have manually inspected them with a story\n\n## Component Anatomy\n\n```\nsrc/ # root\n+-- MyComponent/ # component root\n  `-- index.js # component display logic\n  `-- story.js # storybook entry\n```\n\n## Versioning\n\n```\nmajor.minor.patch\n```\n\n### Considered patch release\n\nCan upgrade without changes to the codebase\n\n- Add a component\n- Add a new prop to a component\n\n### Considered minor release\n\nAn upgrade would require a code change to work\n\n- Remove a component\n- Remove a prop\n\n### Considered major release\n\n- Major milestone achieved (i.e a complete set of components)\n- Complete re-skinning of components\n- Up for debate\n\n## FAQ\n\n**What is a component**\n\nIn 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).\n\nThis means that UI is a function of state since we're using pure functions to build our views.\n\n```\nUI = f(state)\n```\n\n**How do I determine the scope of a component**\n\nThis 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.\n\n**What's the development workflow look like?**\n\nNote: 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`.\n\n1. Create a branch with the name of the new component\n\nNote: also make sure you're up to date\n\n```\ngit checkout master\ngit pull -r\ngit checkout -b task/add-newcomponent\n```\n\n2. Install dependencies and start the storybook\n\n```\nnpm i \u0026\u0026 npm start\n```\n\nopen http://localhost:9001 in your browser\n\n3. Create a `NewComponent` folder under `src` (see [Component Anatomy](#component-anatomy))\n```\nsrc/\n+-- NewComponent/\n```\n\n4. Create a story for the `NewComponent`\n\n```\nsrc/\n+-- NewComponent/\n `-- story.js\n```\n\npopulate **story.js** with a default story\n\n```js\n// story.js\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport NewComponent from './index';\n\nstoriesOf('Card', module)\n  .add('Default', () =\u003e (\n    \u003cNewComponent /\u003e\n  ));\n```\n\nNow when you look at Storybook you should see a broken story (red screen)\n\n5. Implement your component\n\n```\nsrc/\n+-- NewComponent/\n `-- story.js\n `-- index.js\n```\n\npopulate **index.js** with the new component\n\n```js\nimport React from 'react';\nimport { calculateStyles } from '../lib/utils';\n\nconst NewComponent = ({ hovered }) =\u003e\n  \u003cdiv\n    style={calculateStyles({\n      default:{\n        background: 'green',\n      },\n      hovered: {\n        background: 'red',\n      }\n    },{\n      hovered, // key matches above style key and is activated when value is true\n    })}\n  \u003e\n    NewComponent\n  \u003c/div\u003e;\n\nexport default NewComponent;\n```\n\n6. Run the test for the first time\n\nIt'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.\n\n```sh\nnpm t\n```\n\n7. Commit it!\n\n```sh\ngit add .\ngit commit -m \"Add NewComponent\"\ngit push -u origin task/add-newcomponent\n```\n\nAt this point it's a good idea to generate a PR on github :)\n\n**How do I write tests for a component?**\n\nThis automatically happens when you write stories. They are tested with jest snapshots under the hood.\n\nSince 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.\n\nYou're verifying that each property change has the expected outcome in HTML.\n\nThe first time the test is run it generates a new snapshot. The **second** time it's checked against the snapshot.\n\n**How Do I Update A Snapshot**\n\n```\nnpm run test-update\n```\n\n**How do determine what a component does?**\n\nThere's a pattern you can follow\n\n1. Look at the Component.propTypes section\n  - This is essentially the API of the component\n2. Look at the render function\n3. Look at any helper functions\n4. Ask one of the contributors :)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbufferapp%2Fbuffer-components","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbufferapp%2Fbuffer-components","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbufferapp%2Fbuffer-components/lists"}