Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions community-modules/styles/src/internal/base/parts/_grid-layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -119,19 +119,26 @@
--ag-internal-row-overlay-image: none;
}

.ag-row .ag-grid-container-wrapper {
.ag-grid-container-wrapper {
width: 100%;
height: 100%;
background-color: inherit;
}

.ag-row:not(.ag-header-row) {
// Pinned rows need an opaque background, but the row background might be semi-transparent (very common
// for --ag-odd-row-background-color) so we use inheritance to pass the background down from the row
> .ag-grid-pinned-left-cells,
> .ag-grid-pinned-right-cells,
> .ag-grid-scrolling-cells {
> .ag-grid-pinned-right-cells {
background-color: inherit;

// apply an opaque background
background-image: linear-gradient(var(--ag-data-background-color), var(--ag-data-background-color));
}

.ag-grid-container-wrapper {
// re-apply the transparent row color over the opaque background
background-color: inherit;
}
}

.ag-spanned-cell-wrapper {
Expand Down
4 changes: 4 additions & 0 deletions community-modules/styles/src/internal/base/parts/_root.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
--ag-indentation-level: 0;
}

.ag-styled-root {
display: contents;
}

[class*='ag-theme-'] {
-webkit-font-smoothing: antialiased;
font-family: var(--ag-font-family);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
}

.ag-tool-panel-external {
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
margin-bottom: 0;
}

&.ag-dnd-ghost {
.ag-dnd-ghost {
font-size: calc(var(--ag-font-size) - 1px);
font-weight: 700;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
color: var(--ag-disabled-foreground-color);
}

&.ag-dnd-ghost {
.ag-dnd-ghost {
font-size: var(--ag-font-size);
font-weight: 600;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@
}
}

&.ag-dnd-ghost {
.ag-dnd-ghost {
font-size: calc(var(--ag-font-size) - 1px);
font-weight: 600;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@
border: var(--ag-borders-secondary) var(--ag-secondary-border-color);
}

&.ag-dnd-ghost {
.ag-dnd-ghost {
font-weight: 500;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,11 @@ export const ThemeBuilderHomepage: React.FC<Props> = ({ gridHeight = null }) =>
className={`${styles.grid} ${gridHeight ? '' : styles.gridHeight}`}
>
<ShadowDom>
<div style={{ height: '100%' }} data-ag-theme-mode={isDarkMode ? 'dark-blue' : 'light'}>
<div
className="ag-theme-mode"
style={{ height: '100%' }}
data-ag-theme-mode={isDarkMode ? 'dark-blue' : 'light'}
>
<AgGridReact
theme={theme}
columnDefs={columnDefs}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const SelectButton = ({ preset, scrollerRef }: SelectButtonProps) => {
nonce: undefined,
moduleCss: undefined,
});
setThemeClass(theme._getCssClass());
setThemeClass(theme._getCssClasses()[1]); // [1] is the theme apply classes eg ag-theme-params-1

style.textContent = theme._getParamsCss();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ export default {

{% /if %}

The active colour scheme can then be controlled by setting the `data-ag-theme-mode="mode"` attribute on any parent element of the grid, commonly the `html` or `body` elements:
The active colour scheme is controlled by setting `data-ag-theme-mode="mode"` on the `<html>` or `<body>` element.

{% if isFramework("javascript") %}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,23 @@ The standard way of changing a grid's appearance after initialisation is to upda

Often however, a grid application is embedded within a website, and the website and grid application have different codebases. It may not be easy to update the theme grid option in response to the website's dark mode changing.

For this use case we provide theme modes. When a theme uses the `colorSchemeVariable` colour scheme, which is the default for our [built-in themes](./themes/#built-in-themes), the colour scheme can be controlled by setting the `data-ag-theme-mode="mode"` attribute on any parent element of the grid, commonly the `html` or `body` elements, where `mode` is any of:
For this use case we provide theme modes. When a theme uses the `colorSchemeVariable` colour scheme, which is the default for our [built-in themes](./themes/#built-in-themes), the colour scheme can be controlled by setting the `data-ag-theme-mode="mode"` attribute on the `<html>` or `<body>` elements, where `mode` is one of:

- `light`
- `dark`
- `dark-blue`

{% note %}
If your grid is inside Shadow DOM or you only want to change the mode of some grids on the page, you may set the attribute on any ancestor element of the grid that has the `ag-theme-mode` class on it:

```html
<div class="ag-theme-mode" data-ag-theme-mode="dark">
...
</div>
```

{% /note %}

You can also define custom colour modes by passing the mode name as the second argument to `withParams`. This example defines custom colour schemes for light and dark mode and switches between them by setting the `data-ag-theme-mode` attribute on the `body` element:

```js
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,10 @@ function useTheme(theme: string, isDark: boolean) {
themePart = themeMaterial;
break;
}
const gridDiv = document.getElementById('myGrid')!;
if (isDark) {
gridDiv.setAttribute('data-ag-theme-mode', 'dark');
document.body.setAttribute('data-ag-theme-mode', 'dark');
} else {
gridDiv.removeAttribute('data-ag-theme-mode');
document.body.removeAttribute('data-ag-theme-mode');
}
gridApi.setGridOption('theme', themePart);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,6 @@ export class AgGridAngular<TData = any, TColDef extends ColDef<TData> = ColDef<a
frameworkCompWrapper: this._frameworkCompWrapper,
},
modules: (this.modules || []) as any,
setThemeOnGridDiv: true,
};

const api = createGrid(this._nativeElement, mergedGridOps, gridParams);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,19 @@ export interface IDragAndDropImageComponent<
>
extends IComponent<TParams>, IDragAndDropImage {}

// the wrapper div has no class - the drag and drop service adds the theme class to it
const DragAndDropElement: ElementParams = {
tag: 'div',
cls: 'ag-dnd-ghost ag-unselectable',
children: [
{
tag: 'div',
ref: 'eGhost',
cls: 'ag-dnd-ghost ag-unselectable',
children: [
{ tag: 'span', ref: 'eIcon', cls: 'ag-dnd-ghost-icon ag-shake-left-to-right' },
{ tag: 'div', ref: 'eLabel', cls: 'ag-dnd-ghost-label' },
],
},
{ tag: 'span', ref: 'eIcon', cls: 'ag-dnd-ghost-icon ag-shake-left-to-right' },
{ tag: 'div', ref: 'eLabel', cls: 'ag-dnd-ghost-label' },
],
};
export class DragAndDropImageComponent extends Component implements IDragAndDropImageComponent<any, any> {
private dragSource: GridDragSource | null = null;

private readonly eIcon: HTMLElement = RefPlaceholder;
private readonly eLabel: HTMLElement = RefPlaceholder;
private readonly eGhost: HTMLElement = RefPlaceholder;

private dropIconMap: { [key in DragAndDropIcon]: Element };

Expand All @@ -67,12 +59,7 @@ export class DragAndDropImageComponent extends Component implements IDragAndDrop

public init(params: IDragAndDropImageParams): void {
this.dragSource = params.dragSource;

this.setTemplate(DragAndDropElement);
// also apply theme class to the ghost element for backwards compatibility
// with themes that use .ag-theme-classname.ag-dnd-ghost, which used to be
// required before the theme class was also set on the wrapper.
this.beans.environment.applyThemeClasses(this.eGhost);
}

public override destroy(): void {
Expand All @@ -81,7 +68,8 @@ export class DragAndDropImageComponent extends Component implements IDragAndDrop
}

public setIcon(iconName: DragAndDropIcon | null, shake: boolean): void {
const { eGhost, eIcon, dragSource, dropIconMap, gos } = this;
const { eIcon, dragSource, dropIconMap, gos } = this;
const eGhost = this.getGui();

_clearElement(eIcon);

Expand Down
69 changes: 32 additions & 37 deletions packages/ag-grid-community/src/grid.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AgContextParams } from 'ag-stack';
import { AgContext, _missing } from 'ag-stack';
import { AgContext, _createStyledRootElements, _missing } from 'ag-stack';

import { createGridApi } from './api/apiUtils';
import type { GridApi } from './api/gridApi';
Expand Down Expand Up @@ -32,7 +32,6 @@ import {
_registerModule,
_unRegisterGridModules,
} from './modules/moduleRegistry';
import { _createElement } from './utils/element';
import { NoModulesRegisteredError, missingRowModelTypeError } from './validation/errorMessages/errorText';
import { _error, _logPreInitErr } from './validation/logging';
import { VanillaFrameworkOverrides } from './vanillaFrameworkOverrides';
Expand All @@ -47,8 +46,6 @@ export interface GridParams {
frameworkOverrides?: IFrameworkOverrides;
// INTERNAL - bean instances to add to the context
providedBeanInstances?: { [key: string]: any };
// INTERNAL - set by frameworks if the provided grid div is safe to set a theme class on
setThemeOnGridDiv?: boolean;
// INTERNAL - set by studio
withinStudio?: boolean;

Expand Down Expand Up @@ -86,29 +83,19 @@ export function createGrid<TData>(
_error(11);
return {} as GridApi;
}
const gridParams: GridParams | undefined = params;
let destroyCallback: (() => void) | undefined;
if (!gridParams?.setThemeOnGridDiv) {
// frameworks already create an element owned by our code, so we can set
// the theme class on it. JS users calling createGrid directly are
// passing an element owned by their application, so we can't set a
// class name on it and must create a wrapper.
const newGridDiv = _createElement({ tag: 'div' });
newGridDiv.style.height = '100%';
eGridDiv.appendChild(newGridDiv);
eGridDiv = newGridDiv;
destroyCallback = () => eGridDiv.remove();
}
const [outer, inner] = _createStyledRootElements();
eGridDiv.appendChild(outer);
const api = new GridCoreCreator().create(
eGridDiv,
outer,
inner,
gridOptions,
(context) => {
const gridComp = new GridComp(eGridDiv);
const gridComp = new GridComp(inner);
context.createBean(gridComp);
},
undefined,
params,
destroyCallback
() => outer.remove()
);

return api;
Expand All @@ -120,7 +107,12 @@ let nextGridId = 1;
// their own UI
/** @internal AG_GRID_INTERNAL - Not for public use. Can change / be removed at any time. */
export class GridCoreCreator {
/**
* @param eOutermostGridOwned the outermost element owned by grid code, the parent of which is application-owned
* @param eGridDiv the element into which the grid UI should be appended - the inner element of the styled root
*/
public create(
eOutermostGridOwned: HTMLElement,
eGridDiv: HTMLElement,
providedOptions: GridOptions,
createUi: (context: Context) => void,
Expand Down Expand Up @@ -151,7 +143,7 @@ export class GridCoreCreator {

const destroyCallback = () => {
_gridElementCache.delete(api);
_gridApiCache.delete(eGridDiv);
_gridApiCache.delete(eOutermostGridOwned);
_unRegisterGridModules(gridId);
_destroyCallback?.();
};
Expand Down Expand Up @@ -189,8 +181,8 @@ export class GridCoreCreator {

const api = context.getBean('gridApi');

_gridApiCache.set(eGridDiv, api);
_gridElementCache.set(api, eGridDiv);
_gridApiCache.set(eOutermostGridOwned, api);
_gridElementCache.set(api, eOutermostGridOwned);

return api;
}
Expand Down Expand Up @@ -339,30 +331,33 @@ function getDefaultRowModelType(passedRowModelType?: RowModelType): RowModelType
}

/**
* Returns a `GridApi` instance that is associated with the grid rendered in `gridElement`.
*
* The `gridElement` argument can be one of the following:
* - a DOM node
* - the grid ID as determined by the `gridId` grid option.
* - CSS selector string
* Returns the `GridApi` associated with a grid
*
* When using a CSS selector, it must refer to the element passed to `createGrid`.
*
* If passing a DOM node as an argument, this DOM node must be an immediate child of the element passed
* to `createGrid`. This is to support the case where multiple grids are instantiated in a single element.
* The `gridElement` argument can be:
* - the grid ID as determined by the `gridId` grid option
* - a DOM node or a CSS selector string identifying a DOM node. This can point
* to any element within a grid, or to the parent element of the grid if the
* grid is the first child.
*/
export function getGridApi(gridElement: Element | string | null | undefined): GridApi | undefined {
if (typeof gridElement === 'string') {
try {
gridElement =
document.querySelector(`[grid-id="${gridElement}"]`)?.parentElement ??
document.querySelector(gridElement)?.firstElementChild ??
document.getElementById(gridElement)?.firstElementChild;
document.querySelector(`[grid-id="${gridElement}"]`) ??
document.querySelector(gridElement) ??
document.getElementById(gridElement);
} catch {
gridElement = null;
}
}
return gridElement ? _gridApiCache.get(gridElement) : undefined;
gridElement = gridElement?.firstElementChild ?? gridElement;
while (gridElement) {
const api = _gridApiCache.get(gridElement);
if (api) {
return api;
}
gridElement = gridElement.parentElement;
}
}

/**
Expand Down
1 change: 0 additions & 1 deletion packages/ag-grid-community/src/gridComp/gridComp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export class GridComp extends TabGuardComp {
public postConstruct(): void {
const compProxy: IGridComp = {
destroyGridUi: () => this.destroyBean(this),
setRtlClass: (cssClass: string) => this.addCss(cssClass),
forceFocusOutOfContainer: this.forceFocusOutOfContainer.bind(this),
updateLayoutClasses: this.updateLayoutClasses.bind(this),
getFocusableContainers: this.getFocusableContainers.bind(this),
Expand Down
3 changes: 0 additions & 3 deletions packages/ag-grid-community/src/gridComp/gridCtrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import type { Component, ComponentSelector } from '../widgets/component';

/** @internal AG_GRID_INTERNAL - Not for public use. Can change / be removed at any time. */
export interface IGridComp extends LayoutView {
setRtlClass(cssClass: string): void;
destroyGridUi(): void;
forceFocusOutOfContainer(up: boolean): void;
getFocusableContainers(): FocusableContainer[];
Expand Down Expand Up @@ -66,8 +65,6 @@ export class GridCtrl extends BeanStub {

this.createManagedBean(new LayoutFeature(this.view));

this.view.setRtlClass(this.gos.get('enableRtl') ? 'ag-rtl' : 'ag-ltr');

if (this.gos.get('suppressContentVisibilityAuto')) {
this.eGui.style.setProperty('content-visibility', 'visible');
}
Expand Down
Loading
Loading