Hello! Whether you have met with the Hack Oregon organization or not, you are welcome to contribute to the Civic Platform! Bear in mind that this repo only encompasses the front-end web assets. There are many backend repos as well where data is cleaned, analyzed, converted into databases, and made available through APIs.
We use React and Redux as the backbone of our front-end technologies, but there are also many smaller libraries that any contributor may want to learn more about. Here's a list of resources:
- React
- Redux (along with Thunk)
- React Router
- Emotion
- Victory Charts
- Mapbox GL JS
- Storybook
Our testing tools are:
We use the following tools to ensure code quality and consistency:
A couple other libraries in use in the background are:
These libraries in the background aren't necessary to really understand, but knowing that the tools are in use and how they work can help when debugging issues. Read more in our Architecture guide.
We use automated tools to ensure code quality. You don't need to install anything, but you can configure your editor to make working with these automated tools easier.
We use Prettier, an opinionated code formatter, to format our code consistently across the project. This repository is configured to run Prettier automatically before files are committed. You can configure your editor to run Prettier on your files as you code.
In addition, we use ESLint to avoid problems with our code. ESLint can be configured in your editor.
At the heart of Civic is a library of components. We showcase them all in a Storybook to help designers plan Story Cards and project narratives. This showcase also aids developers when implementing Story Cards as well as components. Creating a Storybook story for every component helps ensure a component can stand on its own and work as imagined under a variety of inputs.
We strive for stateless, reusable components that have been tested under a variety of conditions. These components are best for using as building blocks.
First, create a new folder in the src
directory of the component-library
package for the new component. Follow the conventions
that the other components follow:
- Capitalize the component name
- Create a JS file with the same name as the component
When writing the JS implementation of a component, there aren't any hard and fast rules, but there are some strong suggestions:
- Prefer a stateless, function component over a stateful, class component
- Specify the
PropTypes
for the component - When styles are necessary, prefer Emotion over CSS
- Choose composition over inheritance
- Don't be afraid to break a large component down into smaller components that compose
- Expect a variety of prop inputs
- Expect a variety of layout usages
- Don't forget about mobile styles as well as mobile interactions
With these suggestions along with code review, you're sure to make something that will be useful for years to come!
In the same component directory, make a test file named <component>.test.js
.
Good unit tests will help you be confident your component works the way you think it does. Arguably even more important: it will help future developers be confident that their broad changes or upgrades don't break your hard work.
A component that will stand the test of time should adhere to the Robustness Principle.
Be conservative in what you do, be liberal in what you accept from others
Tests are a great way to ensure a component is in fact robust. Write unit tests that provide a wide range of prop values
for a component. When the component takes a number, test 0
, 1
, large numbers, and negative numbers. No matter how surprising
the inputs may be, the output should not surprise.
In the stories
directory in the component-library
package, make a story file named <component>.story.js
.
Then, in the index.js
file in the same stories
directory, import your new story file and call the exported function.
Testing helps us make sure how code works. Stories make sure our designs works. They are useful for testing the user experience of interactions as well as the end result of a variety of inputs. Varying input is especially important in data visualization design. Even if any given chart type doesn't lend itself favorably for every data configuration, keep the Robustness Principle in mind.
Storybook has a variety of addons for adding interactivity to your story that may help a designer or developer review and experiment with the behavior of the component the story is for.
A single story file can include multiple scenarios. Use this to your advantage to showcase a component under a variety of conditions.
When making a new component, that component needs to be re-exported in packages/component-library/src/index.js
.
This makes the component accessible to anyone importing the component via npm.
Build with yarn build
while in the packages/component-library
directory (or run yarn bootstrap
from the project root). This will generate changes in the es
and dist
directories. These build directories are not committed to source control.
Story Cards a special kind of component that is reusable but is not composable. In a nutshell, a Story Card is a self-contained reusable asset that tells a story with data. Story Cards come out of Hack Oregon's project work but are boxed up as Story Cards so they can be embedded in other contexts.
To make a Story Card, start by making a new component in the appropriate project package. Then, make a React component that wraps around the
StoryCard
component from the Component Library.
Story Cards can often be rather complex. When implementing a Story Card, make sure to think about all the UI elements that go into the card's design. Make sure not to reinvent components that are already in the Component Library. Likewise, when the necessary UI elements aren't in the component library, ask yourself if the element is reusable. If it is, it should probably be implemented alone in the component library, then imported and placed in the story card.
Stories are scrolling narratives that tie multiple story cards together to tell the full story of a project. These are implemented as the App
component
in each project package. It is crucial to use the App
component for the Story as this component is imported by the respective Year package for the
project.
Stories have a fair amount of detail to them. They are responsible for page layout as well API actions.
The Platform refers to the packages in this repo that are not project packages, year packages, or the component library. These are the packages that enforce consistency, eliminate duplication, and allow the majority of development to be focused on components and stories. However, the platform should never be considered done!
When making changes to platform packages, make sure to test changes against project packages, year packages, and Storybook.
Once a change has been implemented and tested, open a Pull Request on Github. Explain what the change is and why it was made. Include screenshots when relevant, and never merge without first getting a design review and a code review!
Finishing a task and getting it merged is incredibly rewarding, and every contribution, no matter how small, assists in Hack Oregon's mission to build civic data projects!