Colors
The react-bootstrap-data-grid grid component supports changing the background colors of grid cells according to Bootstrap color variants. This manner of applying color variants is designed to be similar to the way that Bootstrap supports applying color variants to tables.
API Reference Documentation Notice
Some of the contents of this article refer to TypeScript type definitions for types within the react-bootstrap-data-grid code base. Such references are generally look like the following: GridProps.
Efforts are underway to create comprehensive TypeScript type reference documentation. In the meantime, feel free to explore the react-bootstrap-data-grid source code for specific information about types.
Alternatively, you may be able to gain a satisfactory understanding of how to use the feature described in this article by simply following the code sample in this article.
Granularity
The react-bootstrap-data-grid grid supports applying color variants at varying levels of granularity: from selecting a color variant for the entire grid to differing variants for each individual cell.
More specific variant settings can override less specific ones. For example, a grid-wide variant will be overridden by a setting for a row, which will in turn be overridden by the settings for specific cells.
Additionally, one can set a color variant for a grid's borders in a manner similar to that of Bootstrap tables.
The following sections describe each level of granularity available:
Grid-wide
One can set the color variant for the entire grid by passing a value to the variant prop of the Grid component. The
result on the styling to the grid is similar to
using a table variant Bootstrap CSS class on the HTML table element.
Header Row
Set the headerRowVariant prop on the Grid component to set the color variant on the header row of the grid. There is
only one header row for a grid, so this prop takes a single string value that applies to that row.
Header Cell
One can customize the color variant on individual header cells by passing a function as the headerCellVariant prop on
the Grid component.
Parameters passed to the function include the column definition (ColDef) and the column index (zero-based starting
on the left). The function can either return a string that is the color variant or null. When null is returned,
the color scheme of the cell will inherit the color scheme of the header row, which in turn may inherit
the grid-wide setting.
Body Row
One can set the color variant on a per-row basis in the grid's body by passing a function to the bodyRowVariant prop
on the Grid component.
A grid often contains more than one body row. For that reason, two parameters are passed into the function to provide
details about each row. The first parameter is a detailed object of type FormattedRow that includes the contents of
each cell in the row. The second parameter is the zero-based index of the row starting from the top of the grid body.
The function can return a string that is color variant or null to have the row inherit the color scheme from the
grid-wide setting.
Body Cell
One can set the color variant on a per-cell basis in the grid's body by passing a function to the bodyCellVariant prop
on the Grid component.
The function takes 4 parameters:
- Contents and metadata for the cell. Type of the parameter is
CellData. - Contents and metadata for the entire row. Type of the parameter is
FormattedRow. - The zero-based column index starting from the left
- THe zero-based row index starting from the top of the grid body
For cells where the function returns null the color scheme will be inherited from the body row.
Borders
Border color can be set in two ways. The first is that when one sets a grid-wide color variant, the border color for the grid will change to a color that is derived (via Sass color processing functions) from the variant color.
This border color can additionally be overridden by separate border variant color setting. When the borderVariant prop
on the Grid component is set, the component will apply a
Bootstrap border color utility
to the grid.
Example
The following code sample interactively demonstrates the different color variant settings described earlier in the article.
Live Demo
Code
"use client";
import Grid, {
GridProps,
RowDef,
ColDef,
} from "@absreim/react-bootstrap-data-grid/grid";
import { FC, ReactNode, useState } from "react";
import Form from "react-bootstrap/Form";
import Stack from "react-bootstrap/Stack";
// --- Sample data ---
interface Bg3Class {
name: string;
primaryAttribute: string;
savingThrowProficiencies: string;
spellcastingAbility: string;
armorProficiency: string;
}
const cols: ColDef[] = [
{
name: "name",
label: "Name",
type: "string",
},
{
name: "primaryAttribute",
label: "Primary Attribute",
type: "string",
width: 200,
},
{
name: "savingThrowProficiencies",
label: "Saving Throw Proficiencies",
type: "string",
width: 250,
},
{
name: "spellcastingAbility",
label: "Spellcasting Ability",
type: "string",
width: 200,
},
{
name: "armorProficiency",
label: "Armor Proficiency",
type: "string",
width: 200,
},
];
const rows: RowDef<Bg3Class>[] = [
{
id: "barbarian",
data: {
name: "Barbarian",
primaryAttribute: "Strength",
savingThrowProficiencies: "Strength, Constitution",
spellcastingAbility: "Charisma",
armorProficiency: "Medium",
},
},
{
id: "bard",
data: {
name: "Bard",
primaryAttribute: "Charisma",
savingThrowProficiencies: "Charisma, Dexterity",
spellcastingAbility: "Charisma",
armorProficiency: "Light",
},
},
{
id: "cl" + "eric",
data: {
name: "Cleric",
primaryAttribute: "Wisdom",
savingThrowProficiencies: "Wisdom, Charisma",
spellcastingAbility: "Wisdom",
armorProficiency: "Medium",
},
},
{
id: "druid",
data: {
name: "Druid",
primaryAttribute: "Wisdom",
savingThrowProficiencies: "Wisdom, Intelligence",
spellcastingAbility: "Wisdom",
armorProficiency: "Medium",
},
},
{
id: "fighter",
data: {
name: "Fighter",
primaryAttribute: "Strength",
savingThrowProficiencies: "Strength, Constitution",
spellcastingAbility: "Intelligence",
armorProficiency: "Heavy",
},
},
{
id: "monk",
data: {
name: "Monk",
primaryAttribute: "Dexterity",
savingThrowProficiencies: "Dexterity, Strength",
spellcastingAbility: "Wisdom",
armorProficiency: "None",
},
},
{
id: "paladin",
data: {
name: "Paladin",
primaryAttribute: "Strength",
savingThrowProficiencies: "Wisdom, Charisma",
spellcastingAbility: "Charisma",
armorProficiency: "Heavy",
},
},
{
id: "ranger",
data: {
name: "Ranger",
primaryAttribute: "Dexterity",
savingThrowProficiencies: "Dexterity, Strength",
spellcastingAbility: "Wisdom",
armorProficiency: "Medium",
},
},
{
id: "rogue",
data: {
name: "Rogue",
primaryAttribute: "Dexterity",
savingThrowProficiencies: "Dexterity, Intelligence",
spellcastingAbility: "Intelligence",
armorProficiency: "Light",
},
},
{
id: "sorcerer",
data: {
name: "Sorcerer",
primaryAttribute: "Charisma",
savingThrowProficiencies: "Charisma, Constitution",
spellcastingAbility: "Charisma",
armorProficiency: "None",
},
},
{
id: "warlock",
data: {
name: "Warlock",
primaryAttribute: "Charisma",
savingThrowProficiencies: "Charisma, Wisdom",
spellcastingAbility: "Charisma",
armorProficiency: "Light",
},
},
{
id: "wizard",
data: {
name: "Wizard",
primaryAttribute: "Intelligence",
savingThrowProficiencies: "Intelligence, Wisdom",
spellcastingAbility: "Intelligence",
armorProficiency: "None",
},
},
];
// --- Form elements ---
const variants: string[] = [
"primary",
"secondary",
"success",
"warning",
"danger",
"info",
"light",
"dark",
];
const headerCellsFn: GridProps["headerCellVariant"] = (_, colIndex) => {
if (colIndex % 2 === 0) {
return "primary";
}
return null;
};
const bodyRowsFn: GridProps["bodyRowVariant"] = (_, displayIndex) => {
if (displayIndex % 2 === 0) {
return "success";
}
return null;
};
const bodyCellsFn: GridProps["bodyCellVariant"] = (
_,
__,
colIndex,
displayIndex,
) => {
if (colIndex === displayIndex) {
return "info";
}
return null;
};
const useVariantDropdown: (
name: string,
label: string,
) => { selectUi: ReactNode; propValue: string | undefined } = (name, label) => {
const [stateVal, setStateVal] = useState<string>("");
const id = `${name}-settingDropdown`;
const selectUi = (
<div>
<label htmlFor={id}>{label}</label>
<Form.Select
id={id}
value={stateVal}
onChange={({ target }) => setStateVal(target.value)}
>
<option value="">(None)</option>
{variants.map((variant) => (
<option key={variant} value={variant}>
{variant}
</option>
))}
</Form.Select>
</div>
);
const propValue = stateVal === "" ? undefined : stateVal;
return {
selectUi,
propValue,
};
};
const useToggleSwitch: (
name: string,
label: string,
) => { switchUi: ReactNode; enabled: boolean } = (name, label) => {
const [enabled, setEnabled] = useState<boolean>(false);
const switchUi = (
<Form.Check
id={`${name}-settingToggle`}
type="switch"
label={label}
checked={enabled}
onChange={({ target }) => setEnabled(target.checked)}
/>
);
return {
switchUi,
enabled,
};
};
// --- Demo component ---
const ColorSettingsDemo: FC = () => {
const gridVariant = useVariantDropdown("grid", "Grid-wide Variant");
const headerRowVariant = useVariantDropdown(
"headerRow",
"Header Row Variant",
);
const borderVariant = useVariantDropdown("border", "Border Variant");
const headerCells = useToggleSwitch(
"headerCells",
"Enable Header Cell Variants",
);
const bodyRows = useToggleSwitch("bodyRows", "Enable Body Row Variants");
const bodyCells = useToggleSwitch("bodyCells", "Enable Body Cell Variants");
return (
<Stack gap={2}>
{gridVariant.selectUi}
{headerRowVariant.selectUi}
{borderVariant.selectUi}
{headerCells.switchUi}
{bodyRows.switchUi}
{bodyCells.switchUi}
<Grid
width="parent"
rows={rows}
cols={cols}
variant={gridVariant.propValue}
headerRowVariant={headerRowVariant.propValue}
borderVariant={borderVariant.propValue}
headerCellVariant={headerCells.enabled ? headerCellsFn : undefined}
bodyRowVariant={bodyRows.enabled ? bodyRowsFn : undefined}
bodyCellVariant={bodyCells.enabled ? bodyCellsFn : undefined}
/>
</Stack>
);
};
export default ColorSettingsDemo;