What's new in Grid v7.0.0

New themes & CSS

All products in the Bryntum suite now has new themes:

  • Svalbard Light & Dark
  • Stockholm Light & Dark
  • Visby Light & Dark
  • Material3 Light & Dark
  • High Contrast Light & Dark

The new themes are based on CSS variables and are easier to customize than the old themes. The themes only change CSS variable (CSS custom properties) values, there are no custom selectors etc. in them. A single theme file has the custom values for all products.

The structural CSS for each product is separated from the theme CSS, making the theme files much smaller than before.

To for example include the "Material3 Light" theme in your app for Grid, you need to include the following CSS files:

<!-- Structural CSS -->
<link rel="stylesheet" href="build/grid.css">
<!-- Theme CSS -->
<link rel="stylesheet" href="build/material3-light.css">

Also note that none of the new themes applies any font-family. The demo styling does, but the themes themselves do not. Previously the Material theme pulled in Roboto.

No built-in FontAwesome Free

The themes also no longer include FontAwesome Free, so you need to include it yourself if you want to use icons. This change was made to not bloat the CSS files for apps that do not use our default icons.

This also means that we no longer re-scope FontAwesome (there are no b-fa-xx rules). Instead, use FontAwesome classes as you normally would.

There is still a version of FontAwesome Free included in the build folder of the Grid package for your convenience. Include it in your app with something like this:

<!-- Optionally include FontAwesome Free -->
<link rel="stylesheet" href="build/fontawesome/css/fontawesome.css">
<link rel="stylesheet" href="build/fontawesome/css/solid.css">

If you chose to not include it (or your own version of FontAwesome), your app will need to override our b-icon-xx rules to show the icons you are using instead.

CSS variables

As mentioned above, the styling is now based on CSS variables (CSS custom properties). All Bryntum CSS variables are prefixed with --b- to avoid conflicts with other CSS variables in your app. For example, the background of a Panel is set using the --b-panel-background variable:

.my-custom-panel {
  --b-panel-background : #ccc;
}

Available CSS variables are listed in the docs. Make sure to also check the updated customization guides.

Selector normalization

Previously we used a somewhat random mix of single words and kebab-casing for the CSS selectors (for example b-celledit, but b-grid-cell). This has been normalized to use kebab-case. For example the CellEdit features no longer adds the .b-celledit class, but instead correctly kebab cased .b-cell-edit.

This will likely affect any custom styling you have, please check your selectors.

Advanced - Loading from sources

When loading from sources, the CSS is pulled in automatically. Each imported class adds a <link> tag to the head of the document. This should not be used in production, and it might lead to some timing issues. But, it lets you create custom structural CSS files with only the components you need. We will be adding a guide on this later.

New transitions and a new transition config

Grid has a bunch of new transitions, for example for expanding and collapsing groups and columns. It also has a new way of turning them on or off use the transition config, which replaces the old individual animation related configs. The new config is an object with properties that controls different kinds of transitions. The following transitions can be configured:

  • removeRecord - Transition removing rows (replaces animateRemovingRows)
  • insertRecord - Transition inserting rows (new)
  • toggleTreeNode - Transition collapsing/expanding tree nodes (replaces animateTreeNodeToggle)
  • filterRemoval - Transition filters leading to rows being removed (only during specific conditions, replaces animateFilterRemovals)
  • toggleRegion - Transition collapsing/expanding regions (replaces RegionResize.animateCollapseExpand)
  • toggleColumn - Transition showing/hiding columns (new)
  • toggleGroup - Transition collapsing/expanding groups (new)
  • expandCollapseColumn - Transition expanding/collapsing parent/group columns (new)

All transitions are enabled by default.

Usage:

const grid = new Grid({
    transition : {
        removeRecord : true/false,
        insertRecord : true/false,
        toggleTreeNode : true/false,
        filterRemoval : true/false,
        toggleRegion : true/false,
        toggleColumn : true/false,
        toggleGroup : true/false,
        expandCollapseColumn : true/false
    }
});

New AIFilter feature

A new AIFilter feature has been added that lets you filter the grid using natural language. The feature uses a large language model (LLM) such as OpenAI's GPT-4 to interpret the user's input and convert it into filter criteria.

To use the feature, you need to include it in your Grid's features config, and add an aifilterfield to your toolbar (or somewhere else). You also need to provide a URL for the AI prompt, and an API plugin for the LLM you want to use. You also need to provide descriptions for the fields in your store, so the AI knows what data it can filter on.

new Grid({
    features : {
        aiFilter : {
            promptUrl : '/ai/prompt', // Your own endpoint that returns the prompt
            apiPlugin : OpenAIPlugin, // GooglePlugin, AnthropicPlugin is also available (and more is coming)
            model : 'gpt-4-1', // Model to use, not required by all plugins
        }
    },
    tbar : [{
        type        : 'aifilterfield',
        width       : 400,
        placeholder : 'Ask AI to filter…'
    }],
    store : {
        fields : [
            // Descriptions for the fields in your store
            { name : 'name', type : 'string', description : 'The name of the person' },
            { name : 'age', type : 'number', description : 'The age of the person' },
            { name : 'country', type : 'string', description : 'The country the person lives in' }
        ]
    }
})

PinColumns Feature

The new PinColumns feature provides an intuitive way for users to pin columns to either side of the Grid, improving data visibility and navigation in wide datasets. User can pin columns to the start or end of the Grid without needing any additional subGrid configuration. When enabled, the feature adds a Pin columns option to both the column header context menu and cell context menu.

This feature is disabled by default.

Usage:

const grid = new Grid({
    features : {
        pinColumns : true
    }
});
Pin columns
//<code-header>
fiddle.title = 'Pin columns';
//</code-header>
const grid = new Grid({
    appendTo : targetElement,

    height : 300,

    features : {
        pinColumns : true
    },

    // Small dataset: student grades across five subjects and their average
    data : [
        { id : 1, student : 'Alice Johnson', math : 88, science : 92, history : 81, english : 90, geography : 85, average : 87.20 },
        { id : 2, student : 'Ben Carter', math : 74, science : 79, history : 85, english : 78, geography : 80, average : 79.20 },
        { id : 3, student : 'Chloe Nguyen', math : 93, science : 87, history : 90, english : 91, geography : 88, average : 89.80 },
        { id : 4, student : 'Diego Morales', math : 66, science : 72, history : 69, english : 70, geography : 64, average : 68.20 },
        { id : 5, student : 'Elena Petrova', math : 82, science : 84, history : 88, english : 86, geography : 82, average : 84.40 },
        { id : 6, student : 'Farah Khan', math : 95, science : 91, history : 94, english : 94, geography : 96, average : 94.00 },
        { id : 7, student : 'George Smith', math : 70, science : 68, history : 73, english : 72, geography : 71, average : 70.80 },
        { id : 8, student : 'Hiro Tanaka', math : 89, science : 85, history : 92, english : 88, geography : 90, average : 88.80 }
    ],

    // First column is pinned to start, last column pinned to end
    columns : [
        { field : 'student', text : 'Student', width : 180, pinned : 'start' },
        { type : 'number', field : 'math', text : 'Math', width : 120 },
        { type : 'number', field : 'science', text : 'Science', width : 120 },
        { type : 'number', field : 'history', text : 'History', width : 120 },
        { type : 'number', field : 'english', text : 'English', width : 120 },
        { type : 'number', field : 'geography', text : 'Geography', width : 120 },
        { text : 'Average', field : 'average', width : 140, type : 'number', pinned : 'end' }
    ]
});