@politico/interactive-style
v4.2.6
Published
The reusable foundation of interactive stories at POLITICO
Downloads
1,299
Maintainers
Keywords
Readme
@politico/interactive-style
This library is an ever-evolving implementation of our design standards for interactive projects. The goal of the library is to make it as easy and seamless as possible to step from Figma into code. It should serve as a one-stop shop for everything you need to build a POLITICO Interactive story, whether you're working on an elections-specific project or not.
Quick start
Looking to dive right in? 🚀
Install the library as a dependency, and then you can start using the various
pieces provided as you need them. Note that v4
of this library is still in
pre-release, so you have to specify that that's what you want:
npm install "@politico/interactive-style@>=4.0.1-rc.0"
Styles
You may want to include our standard CSS theme in your global stylesheet.
@use "~@politico/interactive-style/int.scss";
@include int.theme();
That will give you a nice foundation on which to use more specific styles in
your components. All of our style utilities are provided as SCSS variables and
mixins, and we export them all from the int.scss
stylesheet. The easiest way
to use things like our colors, our spacing variables, or our more complicated
mixins is to @use
our main stylesheet and access what you need under the
int
namespace:
@use "~@politico/interactive-style/int.scss";
.container {
color: int.$gray-90;
@include int.sans($size: "300");
@include int.is-desktop() {
@include int.sans($size: "500");
}
}
JavaScript
This library also provides a host of components and utilities for use in your JavaScript. Everything is available as a named export at the top level of the library.
All of our components can be imported and used directly in your own components.
// importing several components
import { Well, Grid, GridItem } from '@politico/interactive-style';
// using them in your component
<Well>
<Grid>
<GridItem>Column 1</GridItem>
<GridItem>Column 2</GridItem>
</Grid>
</Well>
And our hooks and utilites can be imported the same way.
// importing a utility
import { sortBy } from '@politico/interactive-style';
// using it in a function or component
const items = [
{ name: 'Steph', number: 30 },
{ name: 'Klay', number: 11 },
{ name: 'Draymond', number: 23 },
];
const sortedItems = sortBy(items, ['name', 'number']);
How to use the docs in Storybook
The package of documentation in Storybook includes two different kinds of docs:
guides and API documentation. The guides offer high-level introductions to
various concepts addressed by this library, like how our content follows a grid
to give the page consistent structure; all the guides are found under the
"GUIDES" header in the left nav. The API documentation offers more fine-grained
and exhaustive details on all the components, mixins, hooks, and utilities
provided by this library. If you're looking for an abstract description of our
typography system, you should probably start with the typography guide. If
you're looking for documentation on the arguments that the sortBy
utility
accepts, you should look for its API documentation in the utilities section.
Toward Reusability
This library is a result of the Toward Reusability project, documented here in Notion. The project was an effort to create a foundation for reusable standards and components for any individual contributor in the POLITICO Interactive News team to use as a basis for their work. The result is a living, iterative system for the design and development of interactive projects.
As our needs continue to evolve this project will need to evolve with them. Every user of this system should feel empowered to identify shortcomings, gaps, and opportunities for improvement or expansion — and they should also feel empowered to contribute to meeting those needs.
Questions, comments, feedback
Anna Wiederkehr and Andrew Milligan were the main contributors responsible for the foundations of this library. Please direct your inquiries or concerns towards them. The relevant stakeholders are Andrew McGill and Allan James Vestal.
Developing this library
Clone the repo and install dependencies.
npm install
You can run Storybook locally to see your changes as you develop them.
npm run storybook
Once it starts up, you should be able to see Storybook running at http://localhost:6006.
You can run unit tests locally. We use unit tests to test easily testable functions like utilities, and we use stories in Storybook to test React components and to provide visual documentation for everything this library provides. So don't be surprised if you run unit tests and only see utilities being tested.
npm run test
You can also lint all of the JS and SCSS in the project.
npm run lint
Dummy Election Data in Storybook
Two types of mock election data can be included in stories: randomly generated data and data sourced from an AP results API snapshot.
Using AP data
In order to make an AP snapshot available for use as dummy data, retrieve it
from the API, make any adjustments/tweaks to it that you want, and then save it
in a JSON file in .storybook/static/ap-snapshots
. For example, you might
take a snapshot and store it as
.storybook/static/ap-snapshots/2022-11-08-nm-gov-general.json
The path of the file from the ap-snapshots
directory to the .json
extension
will be used as the identifier of this snapshot in storybook, so this example
can be referenced as 2022-11-08-nm-gov-general
.
Once a snapshot is available, you can reference it in a story's dummy data configuration like this:
// in an index.stories.js
import { getElectionDataParameters } from 'Utils/storybook/withElectionData';
const parameters = getElectionDataParameters([{
apSnapshot: '2022-11-08-nm-gov-general',
}]);
or using withElectionData
like this:
// in a specific story file
import { withElectionData } from 'Utils/storybook/withElectionData';
// define your story like normal
const MyStory = Template.bind({});
export default withElectionDataParameters(MyStory, [{
apSnapshot: '2022-11-08-nm-gov-general',
}]);
Helpful scripts
makeComponent
This library provides a makeComponent
script to help with creating new
components from JSON blueprints. You can define a component blueprint in the
blueprints
directory and then run the script with:
npm run makeComponent -- --blueprint blueprints/<MyBlueprint>.json
The blueprint should have the following structure:
{
"section": "elections", // the directory within components
"name": "MyComponent", // the name of the component (pascal case)
"description": "Tk...", // the doc comment describing the component
"props": [
{
"name": "foo", // the name of the prop
"description": "Tk...", // the doc comment describing the prop
"type": "string", // the PropTypes type of the component
"isRequired": true, // whether the prop is required
},
{
"name": "bar",
"description": "Tk...",
"type": "bool",
"default": false, // default value
},
{
"name": "variant",
"description": "Tk...",
"type": "oneOf",
"options": [ // the options for a `oneOf` type prop
"a",
"b",
"c",
],
"default": "a",
},
],
"stories": [
{
"name": "MyStoryName", // name of the story
"args": { // prop values to pass to story (appropriately typed)
"propName": "propValue",
"expandable": "aggregationOnly"
},
"description": "Tk...", // description of the story
"apSnapshot": "snap/shot" // name of AP snapshot for story
},
]
}
Don't forget the extra --
to pass flags to the script through npm!
Publishing Storybook
You can publish a new version of Storybook with:
npm run docs:pub
If you only want to build Storybook and not publish it, you can do that with:
npm run docs:build
Publishing the Library
You can build the library with:
npm run build
If you want to run the build in watch mode so that it rebuilds every time you change a file you can run:
npm run build:watch
You can release a new version of the library with:
npm run release
The release script accepts several arguments (remember to include --
between
npm run release
and your additional arguments):
--message
(or-m
) lets you set a custom git commit message to describe the release. Note that your custom message will be automatically prefixed with the version number, so you if provided the message"Hello world"
while releasing v1.0.0, the commit message will bev1.0.0: Hello world
. By default the message will just be the new version number.--step
(or-s
) lets you specify how to increment the version number. Valid choices arepatch
,minor
,major
,premajor
,preminor
,prepatch
, andprerelease
. Note that--version
takes precedence over--step
. Generally choosepatch
(wich will increment the last number, i.e.,2.2.x
) if you're releasing a bug fix and chooseminor
(which will increment the second number, i.e.,2.x.2
) if you're releasing a new feature. The default ispatch
.--version
(or-v
) lets you specify a specific version number, useful if you want to skip a version for some reason, or provide more nuance to the semantic version. Note that--version
takes precedence over--step
.--preid
lets you specify the pre-release identifier (i.e.,rc
in2.0.1-rc.0
). This isrc
by default. It's only used when you release a "pre" version using one of thepre*
values forstep
.
The release script will automatically build the library, increment the version
number in package.json
, commit the bumped version with a commit message that
includes the new version number, tag the commit with the version number,
publish the package to npm, and push the changes along with the new tag.