@primer/react-brand
Version:
Primer Brand is a GitHub's design system for creating React-based marketing websites and digital experiences.
382 lines (335 loc) • 16.5 kB
Markdown
---
title: Comparison table
ready: true
figma: https://www.figma.com/file/BJ95AjraesmRCWsKA013GS/Primer-Brand?node-id=375%3A8130
source: https://github.com/primer/brand/blob/main/packages/react/src/ComparisonTable/ComparisonTable.tsx
storybook: '/brand/storybook/?path=/story/components-comparisontable--playground'
description: Use the comparison table component to compare two products or features in a table format.
---
```js
import {ComparisonTable} from '@primer/react-brand'
```
## Examples
### Default
```jsx
<ComparisonTable>
<ComparisonTable.Row>
<ComparisonTable.Cell>Use case</ComparisonTable.Cell>
<ComparisonTable.Cell>GitHub</ComparisonTable.Cell>
<ComparisonTable.Cell>Jenkins</ComparisonTable.Cell>
</ComparisonTable.Row>
<ComparisonTable.Row>
<ComparisonTable.Cell>Automation & CI/CD</ComparisonTable.Cell>
<ComparisonTable.Cell>
<Text as="p" size="300">
Comparable native core capabilities
</Text>
<Text as="p" size="300">
<a href="https://github.com">Over 13,000 GitHub Actions are available</a> in the GitHub Marketplace to automate
your development workflow.
</Text>
</ComparisonTable.Cell>
<ComparisonTable.Cell>
<Text as="p" size="300">
Comparable native capabilities
</Text>
<Text as="p" size="300">
1,800+ community contributed Jenkins plugins <a href="https://github.com">in Jenkins Plugin Marketplace.</a>
</Text>
</ComparisonTable.Cell>
</ComparisonTable.Row>
<ComparisonTable.Row>
<ComparisonTable.Cell>Deployment models</ComparisonTable.Cell>
<ComparisonTable.Cell>Cloud or self-hosted</ComparisonTable.Cell>
<ComparisonTable.Cell>
<Text as="p" size="300">
Self-hosted only
</Text>
<Text as="p" size="300">
CloudBees is the cloud alternative
</Text>
</ComparisonTable.Cell>
</ComparisonTable.Row>
<ComparisonTable.Footnote>
*** This is a biased overview of capabilities by use case, based on publicly available information as of 2022-05-16.
</ComparisonTable.Footnote>
</ComparisonTable>
```
### Optional heading
A heading can be provided using the `heading` prop on the root `<ComparisonTable>`. This will render a heading at an appropriate size relative to the table, and present it accordingly.
For granular control over heading markup or appearance, we recommend using [`Heading`](../../typography/Heading/index.md).
```jsx
<ComparisonTable heading="GitHub vs Jenkins">
<ComparisonTable.Row>
<ComparisonTable.Cell>Use case</ComparisonTable.Cell>
<ComparisonTable.Cell>GitHub</ComparisonTable.Cell>
<ComparisonTable.Cell>Jenkins</ComparisonTable.Cell>
</ComparisonTable.Row>
<ComparisonTable.Row>
<ComparisonTable.Cell>Automation & CI/CD</ComparisonTable.Cell>
<ComparisonTable.Cell>
<Text as="p" size="300">
Comparable native core capabilities
</Text>
<Text as="p" size="300">
<a href="https://github.com">Over 13,000 GitHub Actions are available</a> in the GitHub Marketplace to automate
your development workflow.
</Text>
</ComparisonTable.Cell>
<ComparisonTable.Cell>
<Text as="p" size="300">
Comparable native capabilities
</Text>
<Text as="p" size="300">
1,800+ community contributed Jenkins plugins <a href="https://github.com">in Jenkins Plugin Marketplace.</a>
</Text>
</ComparisonTable.Cell>
</ComparisonTable.Row>
<ComparisonTable.Row>
<ComparisonTable.Cell>Deployment models</ComparisonTable.Cell>
<ComparisonTable.Cell>Cloud or self-hosted</ComparisonTable.Cell>
<ComparisonTable.Cell>
<Text as="p" size="300">
Self-hosted only
</Text>
<Text as="p" size="300">
CloudBees is the cloud alternative
</Text>
</ComparisonTable.Cell>
</ComparisonTable.Row>
<ComparisonTable.Footnote>
*** This is a biased overview of capabilities by use case, based on publicly available information as of 2022-05-16.
</ComparisonTable.Footnote>
</ComparisonTable>
```
### Featured columns
By default, the first data column will be marked as `featured`. This is to draw attention to a particular product as the basis of a comparison against adjacent columns.
Featured columns will have the visually-hidden text `featured` appended to their column title. This text is used to identify the featured column to screen reader users and can be customized using the `visuallyHiddenFeaturedLabel` prop.
Use `featuredColumn` to alternate the highlighted column if needed.
#### Color customization
The default colors can be customized through dedicated CSS variables.
| Name | Default |
| :--------------------------------------------- | :---------------------------- |
| `--brand-ComparisonTable-featured-color-start` | `--base-color-scale-pink-4` |
| `--brand-ComparisonTable-featured-color-end` | `--base-color-scale-indigo-5` |
```jsx filename="noinline"
const App = () => {
const designTokenOverrides = `
.custom-colors[data-color-mode='dark'] {
/*
* Modify the value of these tokens.
* Remember to apply light mode equivalents if you're enabling theme switching.
*/
--brand-ComparisonTable-featured-color-start: var(--base-color-scale-green-2);
--brand-ComparisonTable-featured-color-end: var(--base-color-scale-blue-3);
/*
* For example only
*/
padding: 3rem;
background-color: var(--brand-color-canvas-default);
}
.custom-heading {
background: linear-gradient(271.72deg, var(--brand-ComparisonTable-featured-color-end) 7.09%, var(--brand-ComparisonTable-featured-color-start) 96.61%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
text-align: center;
margin-bottom: var(--base-size-32);
}
`
return (
<ThemeProvider colorMode="dark" className="custom-colors">
<style>{designTokenOverrides}</style>
<Heading as="h3" className="custom-heading">
GitHub vs Jenkins
</Heading>
<ComparisonTable>
<ComparisonTable.Row>
<ComparisonTable.Cell>Use case</ComparisonTable.Cell>
<ComparisonTable.Cell>GitHub</ComparisonTable.Cell>
<ComparisonTable.Cell>Jenkins</ComparisonTable.Cell>
</ComparisonTable.Row>
<ComparisonTable.Row>
<ComparisonTable.Cell>Automation & CI/CD</ComparisonTable.Cell>
<ComparisonTable.Cell>
<Text as="p" size="300">
Comparable native core capabilities
</Text>
<Text as="p" size="300">
Over 13,000 GitHub Actions are available in the GitHub Marketplace to automate your development workflow.
</Text>
</ComparisonTable.Cell>
<ComparisonTable.Cell>
<Text as="p" size="300">
Comparable native capabilities
</Text>
<Text as="p" size="300">
1,800+ community contributed Jenkins plugins in Jenkins Plugin Marketplace.
</Text>
</ComparisonTable.Cell>
</ComparisonTable.Row>
<ComparisonTable.Row>
<ComparisonTable.Cell>Deployment models</ComparisonTable.Cell>
<ComparisonTable.Cell>Cloud or self-hosted</ComparisonTable.Cell>
<ComparisonTable.Cell>
<Text as="p" size="300">
Self-hosted only
</Text>
<Text as="p" size="300">
CloudBees is the cloud alternative
</Text>
</ComparisonTable.Cell>
</ComparisonTable.Row>
<ComparisonTable.Footnote>
*** This is a biased overview of capabilities by use case, based on publicly available information as of
2022-05-16.
</ComparisonTable.Footnote>
</ComparisonTable>
</ThemeProvider>
)
}
render(<App />)
```
### Dynamic data
Comparison tables are typically generated using data from an API or content management system.
`ComparisonTable` accepts `ReactNode` as a valid child, to facilitate conditional and dynamic rendering.
```jsx filename="noinline"
const App = () => {
const comparisonTableData = {
heading: 'GitHub vs Jenkins',
footnotes:
'*** This is a biased overview of capabilities by use case, based on publicly available information as of 2022-05-16.',
headingLabels: ['', 'GitHub', 'Jenkins'],
features: [
{
label: 'Automation & CI/CD',
values: [
{
name: 'GitHub',
value:
'Over 13,000 GitHub Actions are available in the GitHub Marketplace to automate your development workflow.',
},
{
name: 'Jenkins',
value: '1,800+ community contributed Jenkins plugins in Jenkins Plugin Marketplace.',
},
],
},
{
label: 'Deployment models',
values: [
{
name: 'GitHub',
value: 'Cloud or self-hosted',
},
{
name: 'Jenkins',
value: 'Self-hosted only. CloudBees is the cloud alternative',
},
],
},
],
}
return (
<ComparisonTable heading={comparisonTableData.heading}>
<ComparisonTable.Row>
{comparisonTableData.headingLabels.map(label => (
<ComparisonTable.Cell key={label}>{label}</ComparisonTable.Cell>
))}
</ComparisonTable.Row>
{comparisonTableData.features.map(({label, values}) => {
return (
<ComparisonTable.Row key={label}>
<ComparisonTable.Cell key={label}>{label}</ComparisonTable.Cell>
{values.map(({value, name}) => (
<ComparisonTable.Cell key={name}>{value}</ComparisonTable.Cell>
))}
</ComparisonTable.Row>
)
})}
<ComparisonTable.Footnote>{comparisonTableData.footnotes}</ComparisonTable.Footnote>
</ComparisonTable>
)
}
render(<App />)
```
### Minimal layout
`ComparisonTable` has an alternative visual presentation mode called `minimal`. This will display the data without the featured columns.
This variant is suitable for embedding into long-form content, or in situations where usage of on-screen color needs to be minimized.
```jsx
<ComparisonTable heading="What is containerization?" variant="minimal">
<ComparisonTable.Row>
<ComparisonTable.Cell></ComparisonTable.Cell>
<ComparisonTable.Cell>Containerization</ComparisonTable.Cell>
<ComparisonTable.Cell>Virtualization</ComparisonTable.Cell>
</ComparisonTable.Row>
<ComparisonTable.Row>
<ComparisonTable.Cell>Operating system (OS) </ComparisonTable.Cell>
<ComparisonTable.Cell>
Containers use the host OS, meaning all containers must be compatible with that OS.
</ComparisonTable.Cell>
<ComparisonTable.Cell>
VMs are effectively separate computers that run their own OS. For example, a VM can run Windows even if the host
OS is Ubuntu.
</ComparisonTable.Cell>
</ComparisonTable.Row>
<ComparisonTable.Row>
<ComparisonTable.Cell>Computing resources </ComparisonTable.Cell>
<ComparisonTable.Cell>
Containers are lightweight, taking only the resources needed to run the application and the container
manager.{' '}
</ComparisonTable.Cell>
<ComparisonTable.Cell>
VMs emulate a full computer, meaning that they replicate much of the host environment. That uses more memory, CPU
cycles, and disk space.
</ComparisonTable.Cell>
</ComparisonTable.Row>
<ComparisonTable.Row>
<ComparisonTable.Cell>Shareability </ComparisonTable.Cell>
<ComparisonTable.Cell>
Container images are relatively small in size, making them easy to share.
</ComparisonTable.Cell>
<ComparisonTable.Cell>VM images are often much larger as they include a full OS.</ComparisonTable.Cell>
</ComparisonTable.Row>
<ComparisonTable.Row>
<ComparisonTable.Cell>Security</ComparisonTable.Cell>
<ComparisonTable.Cell>
Containers might be isolated only very lightly from each other. A process in one container could access memory
used by another container, for example.
</ComparisonTable.Cell>
<ComparisonTable.Cell>
By running a separate OS, VMs running on the same hardware are more isolated from one another than containers.
</ComparisonTable.Cell>
</ComparisonTable.Row>
</ComparisonTable>
```
## Component props
### ComparisonTable `Required`
| name | type | default | required | description |
| ----------------------------- | --------------------------------------------------------------------------------------- | ------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `children` | `ComparisonTable.Row`, `ComparisonTable.Cell`, `ComparisonTable.Footnotes`, `ReactNode` | undefined | `true` | Valid children. Accepts `ReactNode` for conditional rendering. |
| `heading` | `string` | undefined | `false` | Optional heading that appears above table, preconfigured as a `h3`. |
| `featuredColumn` | `number` | `1` | `false` | Indicates that the data column at the specified index is visually important and unique in relation to its adjacent cells, and will be styled accordingly. |
| `visuallyHiddenFeaturedLabel` | `string` | `"featured"` | `false` | A visually-hidden label which is appended to the end of the column title. Used to identify the featured column to screen reader users. |
| `variant` | `"default"`, `"minimal"` | `"default"` | `false` | Applies alternative presentation. |
### ComparisonTable.Row `Required`
The first row in a table is automatically styled as a table header row.
| name | type | default | required | description |
| ---------- | ---------------------- | --------- | -------- | ----------------------------------------------- |
| `children` | `ComparisonTable.Cell` | undefined | `true` | Cells (columns) to be displayed inside the row. |
### ComparisonTable.Cell `Required`
The first cell in a row is automatically styled as a header cell.
| name | type | default | required | description |
| ---------- | ----------- | --------- | -------- | ----------------------------------------------- |
| `children` | `ReactNode` | undefined | `true` | Content to be displayed inside the column cell. |
### ComparisonTable.Footnote
Optional node that appears below the table. This is useful for adding additional context or disclaimers.
| name | type | default | required | description |
| ---------- | ----------- | --------- | -------- | ----------------------------------------------- |
| `children` | `ReactNode` | undefined | `true` | Content to be displayed inside the column cell. |
`id`, `className` and `ref` are forwarded by default to all children.
## Design tokens
| css | js |
| ---------------------------------------------- | -------------------------------------------- |
| `--brand-ComparisonTable-featured-color-start` | `brand.ComparisonTable.featured.color.start` |
| `--brand-ComparisonTable-featured-color-end` | `brand.ComparisonTable.featured.color.end` |