> ## Documentation Index
> Fetch the complete documentation index at: https://learn.nextedy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Conditional Formatting

> Conditional formatting in Nextedy RISKSHEET combines three configuration elements -- `cellDecorators`, `styles`, and `formulas` -- to create data-driven visual indicators.

export const LastReviewed = ({date}) => {
  if (!date) return null;
  const formatted = new Date(`${date}T00:00:00Z`).toLocaleDateString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
    timeZone: "UTC"
  });
  return <p className="mt-10 text-sm text-gray-400 dark:text-zinc-500 not-prose">
      Last reviewed on {formatted}
    </p>;
};

## How Conditional Formatting Works

The conditional formatting pipeline flows through three stages: a formula calculates the cell value, a cell decorator evaluates that value and toggles CSS classes, and the style definitions apply visual properties to those classes.

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/yWl5nA2D0IzEnZC1/risksheet/diagrams/reference/styling/conditional-formatting/diagram-1.svg?fit=max&auto=format&n=yWl5nA2D0IzEnZC1&q=85&s=71feb33b985209fa0cf8b900c96f6226" alt="diagram" style={{ maxWidth: "720px", width: "100%" }} width="720" height="220" data-path="risksheet/diagrams/reference/styling/conditional-formatting/diagram-1.svg" />
</Frame>

## Configuration Components

| Component      | Configuration Property | Type     | Role                                                                                                                                                                          |
| -------------- | ---------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Formula        | `formulas`             | `object` | Named JavaScript functions that compute derived values from item fields. Referenced by the `formula` property on column definitions.                                          |
| Cell Decorator | `cellDecorators`       | `object` | Named JavaScript functions that evaluate cell values and toggle CSS classes on the cell DOM element. Mapped to columns by matching the column `id` to the decorator key name. |
| Style          | `styles`               | `object` | CSS class definitions that specify visual properties (background color, text color, font weight, borders). Keys are CSS selectors prefixed with `.`.                          |

## Cell Decorators Reference

### `cellDecorators` Property

| Name             | Type     | Default | Description                                                                                                                                                                                                                                                                        |
| ---------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cellDecorators` | `object` | `{}`    | Collection of named JavaScript functions that apply conditional CSS classes to cells based on their values. Each key is a decorator name that maps to a column's `id` property. The function receives an `info` object and uses jQuery `toggleClass` to add or remove CSS classes. |

### Decorator Function Signature

Each cell decorator function receives a single `info` parameter object:

| Property     | Type          | Description                                                                                     |
| ------------ | ------------- | ----------------------------------------------------------------------------------------------- |
| `info.value` | `any`         | The current cell value (after formula calculation if applicable)                                |
| `info.cell`  | `HTMLElement` | The DOM element for the cell. Use jQuery `$(info.cell).toggleClass()` to add/remove CSS classes |
| `info.item`  | `object`      | The complete work item data for the current row. Access any field via `info.item['fieldName']`  |

<Warning title="Use `toggleClass`, Not Inline Styles">
  Cell decorators MUST use jQuery `toggleClass()` (or `wijmo.toggleClass()` for row headers) to apply CSS classes -- never set inline styles directly. The grid reuses cell DOM elements when scrolling, so inline styles persist on cells that no longer match the original condition, causing incorrect colors on different rows.
</Warning>

### Built-In Decorator: `rpn`

Applies conditional CSS classes to Risk Priority Number (RPN) cells based on risk thresholds:

```yaml theme={null}
cellDecorators:
  rpn: "function(info){ var val = info.value; $(info.cell).toggleClass('boldCol', true); $(info.cell).toggleClass('rpn1', val>0 && val <= 150); $(info.cell).toggleClass('rpn2', val > 150 && val <= 250); $(info.cell).toggleClass('rpn3', val > 250);}"
```

| CSS Class | Condition                 | Risk Level                   |
| --------- | ------------------------- | ---------------------------- |
| `boldCol` | Always                    | All RPN cells displayed bold |
| `rpn1`    | `val > 0 && val <= 150`   | Low risk                     |
| `rpn2`    | `val > 150 && val <= 250` | Medium risk                  |
| `rpn3`    | `val > 250`               | High risk                    |

<Note title="Thresholds Are Configurable">
  The RPN thresholds shown here (150/250) are typical defaults but are user-configurable in the cell decorator function. Different deployments use different thresholds depending on their risk scoring scale and methodology. Adjust the numeric boundaries in the decorator to match your organization's risk tolerance.
</Note>

### Built-In Decorator: `rowHeaderRpnNew`

Applies conditional CSS classes to row headers based on the revised RPN value (after mitigations):

```yaml theme={null}
cellDecorators:
  rowHeaderRpnNew: "function(info){ var val = info.item['rpnNew']; $(info.cell).toggleClass('rpn1', val>0 && val <= 150); $(info.cell).toggleClass('rpn2', val>0 && val > 150 && val <= 250); $(info.cell).toggleClass('rpn3', val>0 && val > 250);}"
```

<Note title="Row Header Decorators">
  Row header decorators read from `info.item` (the full item data), not `info.value`, because the row header does not have a bound column value. The decorator name must match the `headers.rowHeader.renderer` value. Row header decorators use jQuery `$(info.cell).toggleClass('className', condition)` -- the same syntax as cell decorators, and what the shipped configurations use. The Wijmo form `wijmo.toggleClass(info.cell, 'className', condition)` is also supported as an alternative.
</Note>

## Styles Reference

### `styles` Property

| Name     | Type     | Default | Description                                                                                                                                                                                                                                    |
| -------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `styles` | `object` | `{}`    | Collection of CSS class definitions. Each key is a CSS selector (prefixed with `.`) and the value is a CSS declaration block wrapped in curly braces. Styles defined here are injected into the page and available for use by cell decorators. |

### Style Definition Format

Style keys use CSS selector syntax with a leading dot. The value contains CSS properties **wrapped in curly braces** `{}`.

```yaml theme={null}
styles:
  .className: "{property: value; property: value;}"
```

<Warning title="Curly Braces Are Required">
  Style values MUST be wrapped in curly braces `{}`. Without the braces, the style declaration may fail to apply correctly. Correct format: `'.rpn1': '{background-color: #eaf5e9 !important; color: #1d5f20 !important;}'`.
</Warning>

<Warning title="Use `!important`">
  CSS styles in Risksheet typically require `!important` to override the grid's default cell styling. Without `!important`, your custom background colors and text colors may not appear. This is a common source of issues when setting up conditional formatting.
</Warning>

### Default RPN Style Definitions

| CSS Selector | Properties                                                           | Purpose                                                |
| ------------ | -------------------------------------------------------------------- | ------------------------------------------------------ |
| `.boldCol`   | `{font-weight:600;}`                                                 | Bold text for RPN cells                                |
| `.rpn1`      | `{background-color: #eaf5e9 !important; color: #1d5f20 !important;}` | Low risk: light green background, dark green text      |
| `.rpn2`      | `{background-color: #fff3d2 !important; color: #735602 !important;}` | Medium risk: light yellow background, dark yellow text |
| `.rpn3`      | `{background-color: #f8eae7 !important; color: #ab1c00 !important;}` | High risk: light red background, dark red text         |

### Header Group Styles

Styles can target header group rows using compound selectors:

| CSS Selector                  | Properties                                                                         | Purpose                                                              |
| ----------------------------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `.firstRow .headSysReq`       | `{background-color:rgba(62, 175, 63, 0.12) !important; color:#2A792D !important;}` | First row of System Requirement column group: light green background |
| `.lastRow .headSysReq`        | `{background-color:#FFF !important; color:#2A792D !important;}`                    | Last row of System Requirement column group: white background        |
| `.firstRow .headFinalRanking` | `{background-color:rgba(62, 175, 63, 0.12) !important; color:#2A792D !important;}` | First row of Final Ranking column group: light green background      |
| `.lastRow .headFinalRanking`  | `{background-color:#FFF !important; color:#2A792D !important;}`                    | Last row of Final Ranking column group: white background             |

## Formulas Reference

### `formulas` Property

| Name       | Type     | Default | Description                                                                                                                                                                                                                                          |
| ---------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `formulas` | `object` | `{}`    | Collection of named JavaScript functions for calculating derived values in cells. Each key is a formula name referenced by the `formula` property on column definitions. Functions receive an `info` object with `info.item` for accessing row data. |

### Formula Function Signature

| Property     | Type     | Description                                                                               |
| ------------ | -------- | ----------------------------------------------------------------------------------------- |
| `info.item`  | `object` | The work item data for the current row. Access field values via `info.item['fieldName']`. |
| Return value | `any`    | The calculated value to display in the cell. Return `null` to display an empty cell.      |

### Built-In Formula: `commonRpn`

Calculates the initial RPN by multiplying occurrence, detection, and severity:

```yaml theme={null}
formulas:
  commonRpn: "function(info){ var value = info.item['occ']*info.item['det']*info.item['sev']; return value?value:null;}"
```

### Built-In Formula: `commonRpnNew`

Calculates the revised RPN (after mitigations) using the new rating values:

```yaml theme={null}
formulas:
  commonRpnNew: "function(info){ var value = info.item['occNew']*info.item['detNew']*info.item['sevNew']; return value?value:null; }"
```

## Enum Value Formatting

When applying conditional formatting to enum columns, cell decorator functions must compare against enum **IDs**, not display values.

<Warning title="Use Enum IDs, Not Display Names">
  Cell decorator functions compare against enum IDs (e.g., `'yes'`), not display values (e.g., `'Y'`). This is the most common mistake when setting up enum-based conditional formatting. If your decorator is not working, verify that you are using the `id` property from the enum definition, not the `name` property.
</Warning>

<Note title="Enums Are Defined in Polarion">
  Enum values are not declared inside the sheet configuration. Enumerations are defined centrally in Siemens Polarion ALM (**Administration > Enumerations**) and referenced by column definitions via `type: enum:<enumId>` or `type: multiEnum:<enumId>`. The Risksheet server loads enum values automatically when rendering the grid.
</Note>

```yaml theme={null}
cellDecorators:
  approvalStatus: "function(info){ var val = info.value; $(info.cell).toggleClass('approved', val === 'yes'); $(info.cell).toggleClass('notApproved', val === 'no'); }"

styles:
  .approved: "{background-color: #e8f5e9 !important; color: #2e7d32 !important;}"
  .notApproved: "{background-color: #ffebee !important; color: #c62828 !important;}"

columns:
  - id: approvalStatus
    header: Approval
    type: "enum:approvalStatus"
    bindings: approvalStatus
```

In this example, the `approvalStatus` enum (with IDs `yes` / `no`) is defined in Polarion Administration, not in the sheet configuration. The decorator function reads `info.value` and toggles CSS classes that the `styles` section visualizes.

<Tip title="Rating vs. Enum Type">
  Columns using `type: "rating:ENUMID"` show enum descriptions in their dropdown, while columns using `type: "enum:ENUMID"` show only the enum name. Both types store the enum ID as the cell value. Choose `rating` for risk parameters (severity, occurrence, detection) where the description adds context.
</Tip>

## Row Header Formatting

Apply conditional formatting to row headers based on item data. The row header renderer reads from the full item data object rather than a specific column value.

```yaml theme={null}
headers:
  rowHeader:
    renderer: rowHeaderRpnNew

cellDecorators:
  rowHeaderRpnNew: "function(info){ var val = info.item['rpnNew']; $(info.cell).toggleClass('rpn1', val>0 && val <= 150); $(info.cell).toggleClass('rpn2', val>0 && val > 150 && val <= 250); $(info.cell).toggleClass('rpn3', val>0 && val > 250);}"
```

| Property                     | Type     | Default | Description                                                                                                        |
| ---------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------ |
| `headers.rowHeader.renderer` | `string` | None    | Name of a cell decorator function to apply to row headers. The function name must match a key in `cellDecorators`. |

## Severity-Based Cell Styling

Apply color gradients based on individual severity ratings (not the combined RPN):

```yaml theme={null}
cellDecorators:
  sevColor: "function(info){ var val = info.value; $(info.cell).toggleClass('highSev', val >= 8); $(info.cell).toggleClass('medSev', val >= 4 && val < 8); $(info.cell).toggleClass('lowSev', val > 0 && val < 4); }"

styles:
  .highSev: "{background-color: #ffcdd2 !important; color: #b71c1c !important;}"
  .medSev: "{background-color: #fff9c4 !important; color: #f57f17 !important;}"
  .lowSev: "{background-color: #c8e6c9 !important; color: #1b5e20 !important;}"
```

## Conditional Editability

Use cell decorators to dynamically control which fields are editable based on item state. This pattern modifies the `systemReadOnlyFields` value on the item to lock specific columns.

```yaml theme={null}
cellDecorators:
  lockWhenApproved: "function(info){ if(info.item['reviewStatus'] === 'approved'){ info.item.systemReadOnlyFields = (info.item.systemReadOnlyFields || '') + '|severity||occurrence|'; $(info.cell).addClass('rs-readonly'); } }"
```

This pattern appends `severity` and `occurrence` to the pipe-delimited `systemReadOnlyFields` string when the item's `reviewStatus` enum equals `approved`, preventing edits to risk parameters on already-reviewed items. The `rs-readonly` CSS class applies the built-in Risksheet visual styling for grayed-out cells.

<Note title="Approval Review Limitation">
  Risksheet approval review creates approval-tagged comments but does not trigger Polarion's formal approval workflow (draft -> reviewed -> approved). When using `reviewStatus`-based conditional locking, remember that the field reflects Risksheet's review state, not Polarion's formal work item approval status.
</Note>

## Column-Level CSS

In addition to cell decorators, you can apply static CSS classes to all cells in a column using the `cellCss` property:

| Name             | Type     | Default     | Description                                                                                                  |
| ---------------- | -------- | ----------- | ------------------------------------------------------------------------------------------------------------ |
| `cellCss`        | `string` | `undefined` | CSS class name(s) to apply to all cells in the column. Unlike cell decorators, this applies unconditionally. |
| `headerGroupCss` | `string` | `undefined` | CSS class name(s) to apply to the header group row for this column.                                          |

```yaml theme={null}
columns:
  - id: severity
    header: Severity
    type: "rating:severity"
    bindings: severityRating
    cellCss: risk-param-col

styles:
  .risk-param-col: "{text-align: center !important; font-weight: 600 !important;}"
```

## Complete Example

Full FMEA conditional formatting configuration with initial and revised risk color coding, row header formatting, and rating-based styling:

```yaml theme={null}
formulas:
  commonRpn: "function(info){ var value = info.item['occ']*info.item['det']*info.item['sev']; return value?value:null;}"
  commonRpnNew: "function(info){ var value = info.item['occNew']*info.item['detNew']*info.item['sevNew']; return value?value:null; }"

cellDecorators:
  rpn: "function(info){ var val = info.value; $(info.cell).toggleClass('boldCol', true); $(info.cell).toggleClass('rpn1', val>0 && val<=150); $(info.cell).toggleClass('rpn2', val>150 && val<=250); $(info.cell).toggleClass('rpn3', val>250); }"
  rpnNew: "function(info){ var val = info.value; $(info.cell).toggleClass('boldCol', true); $(info.cell).toggleClass('rpn1', val>0 && val<=150); $(info.cell).toggleClass('rpn2', val>150 && val<=250); $(info.cell).toggleClass('rpn3', val>250); }"
  rowHeaderRpnNew: "function(info){ var val = info.item['rpnNew']; $(info.cell).toggleClass('rpn1', val>0 && val<=150); $(info.cell).toggleClass('rpn2', val>0 && val>150 && val<=250); $(info.cell).toggleClass('rpn3', val>0 && val>250); }"

styles:
  .boldCol: "{font-weight:600;}"
  .rpn1: "{background-color: #eaf5e9 !important; color: #1d5f20 !important;}"
  .rpn2: "{background-color: #fff3d2 !important; color: #735602 !important;}"
  .rpn3: "{background-color: #f8eae7 !important; color: #ab1c00 !important;}"
  .firstRow .headSysReq: "{background-color:rgba(62, 175, 63, 0.12) !important; color:#2A792D !important;}"
  .lastRow .headSysReq: "{background-color:#FFF !important; color:#2A792D !important;}"
  .firstRow .headFinalRanking: "{background-color:rgba(62, 175, 63, 0.12) !important; color:#2A792D !important;}"
  .lastRow .headFinalRanking: "{background-color:#FFF !important; color:#2A792D !important;}"

headers:
  rowHeader:
    renderer: rowHeaderRpnNew
  columnHeader:
    height: 32
  columnGroupHeader:
    height: 32

columns:
  - id: sev
    header: S
    width: 60
    type: "rating:severity"
    bindings: severityRating
  - id: occ
    header: O
    width: 60
    type: "rating:occurrence"
    bindings: occurrenceRating
  - id: det
    header: D
    width: 60
    type: "rating:detection"
    bindings: detectionRating
  - id: rpn
    header: RPN
    width: 80
    formula: commonRpn
  - id: sevNew
    header: "S*"
    width: 60
    type: "rating:severity"
    bindings: severityRatingNew
  - id: occNew
    header: "O*"
    width: 60
    type: "rating:occurrence"
    bindings: occurrenceRatingNew
  - id: detNew
    header: "D*"
    width: 60
    type: "rating:detection"
    bindings: detectionRatingNew
  - id: rpnNew
    header: "RPN*"
    width: 80
    formula: commonRpnNew
```

The rating enumerations (`severity`, `occurrence`, `detection`) referenced by `type: "rating:..."` are defined in Polarion Administration -> Enumerations, not in the sheet configuration.

## Troubleshooting

| Symptom                       | Cause                                                 | Solution                                                                                                           |
| ----------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| Cell colors not appearing     | Missing `!important` in style definition              | Add `!important` to `background-color` and `color` properties                                                      |
| Cell colors not appearing     | Style value missing curly braces                      | Wrap the style declaration in `{}`: `.rpn1: "{background-color: #eaf5e9 !important;}"`                             |
| Enum decorator not matching   | Comparing against display name instead of ID          | Use the enum `id` value (e.g., `'yes'`) not the `name` value (e.g., `'Y'`)                                         |
| Stale colors on scrolled rows | Decorator uses inline styles instead of `toggleClass` | Switch to `$(info.cell).toggleClass('className', condition)` so the grid can correctly clear classes on cell reuse |
| Row header not colored        | Decorator name mismatch                               | Ensure `headers.rowHeader.renderer` value matches a key in `cellDecorators`                                        |
| Styles overridden             | CSS specificity conflict                              | Use compound selectors or add `!important`                                                                         |
| Decorator not firing          | Column ID mismatch                                    | Ensure the `cellDecorators` key matches the column `id` property exactly                                           |

## Related Pages

* [Cell Decorators](/risksheet/reference/styling/cell-decorators) -- cell decorator function reference and patterns
* [CSS Classes](/risksheet/reference/styling/css-classes) -- complete CSS class reference and custom style definitions
* [Item Colors](/risksheet/reference/styling/item-colors) -- row-level color coding for work item types
* [Formula Syntax](/risksheet/reference/formulas/formula-syntax) -- formula function syntax and `info` object reference
* [Formula Examples](/risksheet/reference/formulas/formula-examples) -- formula patterns that drive conditional formatting
* [Custom Renderer Templates](/risksheet/reference/templates/custom-renderers) -- advanced cell rendering with JavaScript functions

<LastReviewed date="2026-06-24" />
