> ## 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.

# Display Sub-Columns

> Configure sub-columns and grouped header layouts in Nextedy RISKSHEET to organize related fields under a shared header label, control header height for multi-line text, and dynamically toggle column visibility.

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>;
};

This guide covers three related techniques that work together to give you control over how columns appear in the grid: header groups (the foundation for sub-columns), column header height (for readable multi-line labels), and dynamic column visibility (for runtime configuration without re-editing the sheet configuration).

## Before You Start

You will need:

* A Risksheet document with an existing sheet configuration (risksheet.json), edited through the configuration editor (YAML supported since v25.5.0)
* Administrator access to the project (to modify the sheet configuration)
* For dynamic visibility: the ability to create or edit a Polarion wiki page in the project

If you have not yet built a column, see [Add a Basic Column](/risksheet/guides/columns/add-basic-column) first.

## Visual Structure

The grid renders a two-level column header when one or more columns share the same `headerGroup` value. Row 0 of the header shows the group name; row 1 shows individual column headers.

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/-Icoak49xQVOW38R/risksheet/diagrams/guides/columns/sub-columns/diagram-1.svg?fit=max&auto=format&n=-Icoak49xQVOW38R&q=85&s=571c823fe415a46e345d3aaca47a0bbf" alt="diagram" style={{ maxWidth: "540px", width: "100%" }} width="540" height="220" data-path="risksheet/diagrams/guides/columns/sub-columns/diagram-1.svg" />
</Frame>

<Steps>
  <Step title="Group Columns Under a Shared Header">
    Add the `headerGroup` property to every column that should appear under the same parent label. All columns sharing that exact string become sub-columns of the group.

    ```yaml theme={null}
    columns:
      - id: severity
        header: S
        bindings: severityRating
        headerGroup: Initial Risk Assessment
        width: 60
        level: 2
      - id: occurrence
        header: O
        bindings: occurrenceRating
        headerGroup: Initial Risk Assessment
        width: 60
        level: 2
      - id: detection
        header: D
        bindings: detectionRating
        headerGroup: Initial Risk Assessment
        width: 60
        level: 2
    ```

    The group span is determined automatically by consecutive columns sharing the same `headerGroup` string. Place the columns next to each other in the `columns` array — non-adjacent columns with the same group name will not merge into a single header span.

    <Tip>
      Use header groups to organize wide FMEA grids into logical sections: an *Initial Risk Assessment* group for the first Severity/Occurrence/Detection/RPN block, a *Mitigation* group for the action columns, and a *Final Risk Assessment* group for the revised severity/occurrence/detection/RPN block. This keeps the grid readable even with 20+ columns.
    </Tip>
  </Step>

  <Step title="Increase Header Height for Multi-Line Labels">
    When sub-column headers contain longer text (for example, "Occurrence after mitigation"), the default header height truncates the label. Increase header height through the `headers` section so headers wrap into multiple lines.

    ```yaml theme={null}
    headers:
      columnHeader:
        height: 64
      columnGroupHeader:
        height: 32
      rowHeader:
        renderer: rowHeaderRpnNew
    ```

    The default column header height is 32 pixels. Setting `columnHeader.height` to 48 or 64 pixels allows two or three lines of text to wrap. The `columnGroupHeader.height` controls the upper row that shows the group label — keep it small unless you are also wrapping group names.

    <Warning title="Header height applies to all columns">
      The `columnHeader.height` value is global: it affects every column in the sheet, not just the one with long text. Choose a height that works for the widest header text, then tune individual column widths to balance vertical and horizontal space.
    </Warning>
  </Step>

  <Step title="Tune Column Widths">
    Header text wrapping depends on column width as well as header height. A narrow column with a long header still truncates even when header height is increased. Set `width` per column to give the header enough horizontal room.

    ```yaml theme={null}
    columns:
      - id: occurrenceAfterMitigation
        header: Occurrence after mitigation
        bindings: occNew
        headerGroup: Final Risk Assessment
        width: 120
        level: 2
    ```

    For the last visible column, the grid automatically adjusts width by a few pixels to account for scrollbar presence, so you do not need to compensate manually.

    <Tip title="Balance header height against width">
      If you cannot widen columns (for example, because you must fit many sub-columns under one group), increase `columnHeader.height` instead. A common balanced layout is `height: 48` with column widths of 60–80 pixels — enough for two lines of short labels under a grouped header.
    </Tip>
  </Step>

  <Step title="Make Sub-Columns Dynamically Visible">
    To enable users to enable, disable, or rename sub-columns without editing the sheet configuration directly, combine the standard `visible` column property with a Polarion wiki page that overrides values at runtime.

    First, define the sub-columns in the sheet configuration as you normally would, including the `headerGroup`:

    ```yaml theme={null}
    columns:
      - id: ifu1
        header: IFU 1
        bindings: customIfu1
        headerGroup: Instructions for Use
        visible: false
        width: 100
        level: 2
      - id: ifu2
        header: IFU 2
        bindings: customIfu2
        headerGroup: Instructions for Use
        visible: false
        width: 100
        level: 2
    ```

    Then add a wiki page script block in the project's wiki (Documents and Pages) that flips the `visible` property and overrides the `header` text for each column at load time. The columns you enable inherit their position and header group from the first configured column in the group, keeping the grouped sub-column layout intact.

    <Tip title="Column builder pattern (from ticket resolution)">
      Nextedy implemented this dynamic column builder pattern for a customer who needed runtime toggling of custom field columns (IFU\_1 through IFU\_10). The script block on a wiki page reads which columns should be enabled and what their header labels should be, then updates the configuration before the grid renders. The first configured column establishes the position and `headerGroup` — subsequent enabled columns inherit both.
    </Tip>

    <Warning title="Custom fields must exist in Polarion first">
      Before referencing a custom field in `bindings`, the field must be defined on the work item type in Polarion (**Administration > Work Items > Custom Fields**). Otherwise, the column appears empty and may emit binding errors. Verify the field ID exactly matches the `bindings` value — IDs are case-sensitive.
    </Warning>
  </Step>

  <Step title="Hide and Show via Saved Views">
    For users who need to switch between full and condensed sub-column layouts at runtime, define [Saved Views](/risksheet/guides/customization/saved-views) instead of toggling `visible`. Views use `columnIds` (note the plural) to declare which columns are shown:

    ```yaml theme={null}
    views:
      - name: Full Analysis
        defaultView: true
        columnIds:
          - "@all"
      - name: Initial Only
        columnIds:
          - "@all"
          - "-occurrenceAfterMitigation"
          - "-severityAfterMitigation"
          - "-detectionAfterMitigation"
    ```

    The `@all` token includes every column; the `-columnId` prefix excludes specific columns from that set. Users switch views from the toolbar without changing the underlying sheet configuration.
  </Step>
</Steps>

## Verification

You should now see:

* A two-level header in the grid: the `headerGroup` label across the top, with each sub-column header listed beneath it
* Multi-line header text wrapping correctly within the configured `columnHeader.height`
* Sub-columns aligned in the expected order under their parent group
* If you configured saved views, a view switcher in the toolbar that toggles which sub-columns are visible
* If you configured the wiki-page column builder, sub-columns turning on or off based on the wiki configuration when the document opens

If header text still truncates, confirm that `columnHeader.height` was saved (close and reopen the document — header changes apply on reload) and that columns sharing a `headerGroup` are placed consecutively in the `columns` array.

## See Also

* [Add a Basic Column](/risksheet/guides/columns/add-basic-column)
* [Control Column Visibility](/risksheet/guides/columns/column-visibility)
* [Display Multi-Level Hierarchies](/risksheet/guides/columns/multi-level-hierarchy)
* [Create Saved Views](/risksheet/guides/customization/saved-views)
* [Configure Column Visibility](/risksheet/guides/customization/column-visibility)
* [Column Types](/risksheet/reference/columns/index)
* [Configuration Examples](/risksheet/reference/examples/index)

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