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.
Run yarn component
from the project root to generate a component in the package of your choosing.
A component directory will be generated in packages/<package>/<component>/
with the following files:
<component>.js
: The implementation of the component<component>.test.js
: Unit tests for the component<component>.stories.js
: Storybook stories that describe all of the interesting states of the component Additionally, the component will be re-exported frompackages/<package>/src/index.js
to make the component accessible to anyone using the package via npm.
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
- Use React Hooks when possible
- Specify the
PropTypes
for the component - Use JSDoc comments to add a description for each
PropType
- When styles are necessary, use Emotion
- 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!
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.
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.
A single story file can include many different scenarios. Use this to your advantage to showcase a component under a variety of conditions.
Build with yarn build
while in the packages/<package>
directory (or run yarn build-packages
from the project root). This will generate changes in the es
and dist
directories. These build directories are not committed to source control.
You can also use the yarn watch
command at the project root to automatically rebuild any changed packages.
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 component packages. 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!
To keep your PR up to date automatically, apply the automerge
label. Kodiak will automatically keep your branches up to date and merge at the appropriate time.
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!