diff --git a/.github/renovate.json5 b/.github/renovate.json5
index 12e15489b..c31f39a8f 100644
--- a/.github/renovate.json5
+++ b/.github/renovate.json5
@@ -22,6 +22,10 @@
{
packageNames: ['rxjs'],
allowedVersions: '7.8.1',
+ },
+ {
+ packageNames: ['slickgrid'],
+ allowedVersions: '4.x',
}
],
schedule: ['on friday and tuesday'],
diff --git a/examples/vite-demo-vanilla-bundle/src/app-routing.ts b/examples/vite-demo-vanilla-bundle/src/app-routing.ts
index 8cb41d816..6e70aac73 100644
--- a/examples/vite-demo-vanilla-bundle/src/app-routing.ts
+++ b/examples/vite-demo-vanilla-bundle/src/app-routing.ts
@@ -20,6 +20,7 @@ import Example16 from './examples/example16';
import Example17 from './examples/example17';
import Example18 from './examples/example18';
import Example19 from './examples/example19';
+import Example20 from './examples/example20';
export class AppRouting {
constructor(private config: RouterConfig) {
@@ -45,6 +46,7 @@ export class AppRouting {
{ route: 'example17', name: 'example17', view: './examples/example17.html', viewModel: Example17, title: 'Example17', },
{ route: 'example18', name: 'example18', view: './examples/example18.html', viewModel: Example18, title: 'Example18', },
{ route: 'example19', name: 'example19', view: './examples/example19.html', viewModel: Example19, title: 'Example19', },
+ { route: 'example20', name: 'example20', view: './examples/example20.html', viewModel: Example20, title: 'Example20', },
{ route: '', redirect: 'example01' },
{ route: '**', redirect: 'example01' }
];
diff --git a/examples/vite-demo-vanilla-bundle/src/app.html b/examples/vite-demo-vanilla-bundle/src/app.html
index ec4ba32ad..8621010f4 100644
--- a/examples/vite-demo-vanilla-bundle/src/app.html
+++ b/examples/vite-demo-vanilla-bundle/src/app.html
@@ -92,6 +92,9 @@
Slickgrid-Universal
Example19 - ExcelCopyBuffer with Cell Selection
+
+ Example20 - Basic grid inside a Shadow DOM
+
diff --git a/examples/vite-demo-vanilla-bundle/src/examples/example18.ts b/examples/vite-demo-vanilla-bundle/src/examples/example18.ts
index d8b7106c4..ccbcc6756 100644
--- a/examples/vite-demo-vanilla-bundle/src/examples/example18.ts
+++ b/examples/vite-demo-vanilla-bundle/src/examples/example18.ts
@@ -39,17 +39,7 @@ const historicSparklineFormatter: Formatter = (_row: number, _cell: number, _val
return svgElem.outerHTML;
};
-export default class Example34 {
- title = 'Example 34: Real-Time Stock Trading';
- subTitle = `Simulate a stock trading platform with lot of price changes
-
- - you can start/stop the simulation
- - optionally change random numbers, between 0 and 10 symbols, per cycle (higher numbers means more changes)
- - optionally change the simulation changes refresh rate in ms (lower number means more changes).
- - you can Group by 1 of these columns: Currency, Market or Type
- - to show SlickGrid HUGE PERF., do the following: (1) lower Changes Rate (2) increase both Changes per Cycle and (3) lower Highlight Duration
-
`;
-
+export default class Example18 {
columnDefinitions: Column[] = [];
dataset: any[] = [];
gridOptions!: GridOption;
diff --git a/examples/vite-demo-vanilla-bundle/src/examples/example19.ts b/examples/vite-demo-vanilla-bundle/src/examples/example19.ts
index 6c4a4b18f..bdb4d7afa 100644
--- a/examples/vite-demo-vanilla-bundle/src/examples/example19.ts
+++ b/examples/vite-demo-vanilla-bundle/src/examples/example19.ts
@@ -6,16 +6,8 @@ import './example19.scss';
const NB_ITEMS = 100;
declare const Slick: SlickNamespace;
-export default class Example34 {
+export default class Example19 {
protected _eventHandler: SlickEventHandler;
- title = 'Example 19: ExcelCopyBuffer with Cell Selection';
- subTitle = `Cell Selection using "Shift+{key}" where "key" can be any of:
-
- - Arrow Up/Down/Left/Right
- - Page Up/Down
- - Home
- - End
-
`;
columnDefinitions: Column[] = [];
dataset: any[] = [];
@@ -71,7 +63,7 @@ export default class Example34 {
id: i,
name: i < 26
? String.fromCharCode('A'.charCodeAt(0) + (i % 26))
- : String.fromCharCode('A'.charCodeAt(0) + ((i / 26) | 0) -1) + String.fromCharCode('A'.charCodeAt(0) + (i % 26)),
+ : String.fromCharCode('A'.charCodeAt(0) + (Math.floor(i / 26)) - 1) + String.fromCharCode('A'.charCodeAt(0) + (i % 26)),
field: i as any,
minWidth: 60,
width: 60,
diff --git a/examples/vite-demo-vanilla-bundle/src/examples/example20.html b/examples/vite-demo-vanilla-bundle/src/examples/example20.html
new file mode 100644
index 000000000..112075be0
--- /dev/null
+++ b/examples/vite-demo-vanilla-bundle/src/examples/example20.html
@@ -0,0 +1,14 @@
+
+ Example 20 - Basic grid inside a Shadow DOM
+ (with Salesforce Theme)
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/vite-demo-vanilla-bundle/src/examples/example20.ts b/examples/vite-demo-vanilla-bundle/src/examples/example20.ts
new file mode 100644
index 000000000..9d946b333
--- /dev/null
+++ b/examples/vite-demo-vanilla-bundle/src/examples/example20.ts
@@ -0,0 +1,135 @@
+import { Column, FieldType, Filters, Formatters, GridOption, SlickEventHandler, SlickNamespace, } from '@slickgrid-universal/common';
+import { Slicker, SlickVanillaGridBundle } from '@slickgrid-universal/vanilla-bundle';
+import { ExampleGridOptions } from './example-grid-options';
+
+const NB_ITEMS = 100;
+declare const Slick: SlickNamespace;
+
+interface ShadowContainer {
+ shadow: ShadowRoot;
+ gridContainer: HTMLDivElement;
+}
+
+export default class Example20 {
+ protected _eventHandler: SlickEventHandler;
+
+ columnDefinitions: Column[] = [];
+ dataset: any[] = [];
+ gridOptions!: GridOption;
+ gridContainerElm: HTMLDivElement;
+ isWithPagination = true;
+ sgb: SlickVanillaGridBundle;
+
+ attached() {
+ this._eventHandler = new Slick.EventHandler();
+ const shadowObj = this.createShadowElement();
+
+ // define the grid options & columns and then create the grid itself
+ this.defineGrid(shadowObj);
+
+ // mock some data (different in each dataset)
+ this.dataset = this.getData(NB_ITEMS);
+ this.gridContainerElm = document.querySelector(`#host`) as HTMLDivElement;
+ document.body.classList.add('salesforce-theme');
+
+ setTimeout(() => {
+ this.sgb = new Slicker.GridBundle(shadowObj.gridContainer as HTMLDivElement, this.columnDefinitions, { ...ExampleGridOptions, ...this.gridOptions }, this.dataset);
+ }, 25);
+ }
+
+ /**
+ * Build the Shadow DOM. In this example, it will
+ * have just a div for the grid, and a
+ * for the Alpine style.
+ *
+ * Notice that the tag must be placed inside
+ * the Shadow DOM tree, it cannot be placed on the
+ * tag because the Shadow DOM is unaffected by external
+ * styles
+ */
+ createShadowElement(): ShadowContainer {
+ const host = document.querySelector('#host') as HTMLDivElement;
+ const shadow = host.attachShadow({ mode: 'open' });
+ const gridContainer = document.createElement('div');
+ // gridContainer.style.width = '600px';
+ // gridContainer.style.height = '500px';
+ gridContainer.classList.add('grid20');
+ shadow.appendChild(gridContainer);
+
+ const linkElement = document.createElement('link');
+ linkElement.type = 'text/css';
+ linkElement.rel = 'stylesheet';
+ linkElement.href = './src/styles.scss';
+ shadow.appendChild(linkElement);
+ return { shadow, gridContainer };
+ }
+
+ dispose() {
+ this._eventHandler.unsubscribeAll();
+ this.sgb?.dispose();
+ this.gridContainerElm.remove();
+ document.body.classList.remove('salesforce-theme');
+ }
+
+ /* Define grid Options and Columns */
+ defineGrid(shadowObj) {
+ this.columnDefinitions = [
+ { id: 'title', name: 'Title', field: 'title', sortable: true, minWidth: 100, filterable: true },
+ { id: 'duration', name: 'Duration (days)', field: 'duration', sortable: true, minWidth: 100, filterable: true, type: FieldType.number },
+ { id: '%', name: '% Complete', field: 'percentComplete', sortable: true, minWidth: 100, filterable: true, type: FieldType.number },
+ { id: 'start', name: 'Start', field: 'start', formatter: Formatters.dateIso, filter: { model: Filters.compoundDate }, type: FieldType.date, exportWithFormatter: true, filterable: true },
+ { id: 'finish', name: 'Finish', field: 'finish', formatter: Formatters.dateIso, filter: { model: Filters.compoundDate }, type: FieldType.date, exportWithFormatter: true, filterable: true },
+ { id: 'effort-driven', name: 'Effort Driven', field: 'effortDriven', sortable: true, minWidth: 100, filterable: true }
+ ];
+
+ this.gridOptions = {
+ gridHeight: 450,
+ gridWidth: 800,
+ enableCellNavigation: true,
+ enableFiltering: true,
+ headerRowHeight: 35,
+ rowHeight: 30,
+ shadowRoot: shadowObj.shadow
+ };
+ }
+
+ getData(itemCount: number) {
+ // mock a dataset
+ const datasetTmp: any[] = [];
+ for (let i = 0; i < itemCount; i++) {
+ const randomYear = 2000 + Math.floor(Math.random() * 10);
+ const randomMonth = Math.floor(Math.random() * 11);
+ const randomDay = Math.floor((Math.random() * 29));
+ const randomPercent = Math.round(Math.random() * 100);
+
+ datasetTmp.push({
+ id: i,
+ title: 'Task ' + i,
+ duration: Math.round(Math.random() * 100) + '',
+ percentComplete: randomPercent,
+ start: new Date(randomYear, randomMonth + 1, randomDay),
+ finish: new Date(randomYear + 1, randomMonth + 1, randomDay),
+ effortDriven: (i % 5 === 0)
+ });
+ }
+
+ return datasetTmp;
+ }
+
+ generatePhoneNumber(): string {
+ let phone = '';
+ for (let i = 0; i < 10; i++) {
+ phone += Math.round(Math.random() * 9) + '';
+ }
+ return phone;
+ }
+
+ // Toggle the Grid Pagination
+ // IMPORTANT, the Pagination MUST BE CREATED on initial page load before you can start toggling it
+ // Basically you cannot toggle a Pagination that doesn't exist (must created at the time as the grid)
+ togglePagination() {
+ this.isWithPagination = !this.isWithPagination;
+ this.sgb.paginationService!.togglePaginationVisibility(this.isWithPagination);
+ this.sgb.slickGrid!.setSelectedRows([]);
+ }
+}
diff --git a/package.json b/package.json
index 7bc7dc858..0ad914ac3 100644
--- a/package.json
+++ b/package.json
@@ -91,7 +91,7 @@
"rimraf": "^5.0.5",
"rxjs": "^7.8.1",
"servor": "^4.0.2",
- "slickgrid": "^4.0.3",
+ "slickgrid": "^4.1.1",
"sortablejs": "^1.15.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
diff --git a/packages/common/package.json b/packages/common/package.json
index 40c330df4..6ec74f4e7 100644
--- a/packages/common/package.json
+++ b/packages/common/package.json
@@ -79,7 +79,7 @@
"flatpickr": "^4.6.13",
"moment-mini": "^2.29.4",
"multiple-select-vanilla": "^0.5.0",
- "slickgrid": "^4.0.3",
+ "slickgrid": "^4.1.1",
"sortablejs": "^1.15.0",
"un-flatten-tree": "^2.0.12"
},
diff --git a/packages/common/src/extensions/__tests__/slickDraggableGrouping.spec.ts b/packages/common/src/extensions/__tests__/slickDraggableGrouping.spec.ts
index f1887adaf..c10be847b 100644
--- a/packages/common/src/extensions/__tests__/slickDraggableGrouping.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickDraggableGrouping.spec.ts
@@ -75,6 +75,7 @@ const gridStub = {
getCellNode: jest.fn(),
getCellFromEvent: jest.fn(),
getColumns: jest.fn(),
+ getContainerNode: jest.fn(),
getHeaderColumn: jest.fn(),
getOptions: jest.fn(),
getPreHeaderPanel: jest.fn(),
@@ -141,6 +142,7 @@ describe('Draggable Grouping Plugin', () => {
sharedService = new SharedService();
translateService = new TranslateServiceStub();
extensionUtility = new ExtensionUtility(sharedService, backendUtilityService, translateService);
+ jest.spyOn(gridStub, 'getContainerNode').mockReturnValue(document.body as HTMLDivElement);
jest.spyOn(SharedService.prototype, 'gridOptions', 'get').mockReturnValue(gridOptionsMock);
jest.spyOn(SharedService.prototype, 'slickGrid', 'get').mockReturnValue(gridStub);
jest.spyOn(gridStub, 'getColumns').mockReturnValue(mockColumns);
diff --git a/packages/common/src/extensions/__tests__/slickGridMenu.spec.ts b/packages/common/src/extensions/__tests__/slickGridMenu.spec.ts
index 57fd5f163..3961dae4c 100644
--- a/packages/common/src/extensions/__tests__/slickGridMenu.spec.ts
+++ b/packages/common/src/extensions/__tests__/slickGridMenu.spec.ts
@@ -49,6 +49,7 @@ const gridStub = {
autosizeColumns: jest.fn(),
getColumnIndex: jest.fn(),
getColumns: jest.fn(),
+ getContainerNode: jest.fn(),
getGridPosition: () => ({ width: 10, left: 0 }),
getOptions: jest.fn(),
getSelectedRows: jest.fn(),
@@ -156,6 +157,7 @@ describe('GridMenuControl', () => {
translateService = new TranslateServiceStub();
extensionUtility = new ExtensionUtility(sharedService, backendUtilityService, translateService);
+ jest.spyOn(gridStub, 'getContainerNode').mockReturnValue(document.body as HTMLDivElement);
jest.spyOn(gridStub, 'getColumns').mockReturnValue(columnsMock);
jest.spyOn(gridStub, 'getOptions').mockReturnValue(gridOptionsMock);
jest.spyOn(SharedService.prototype, 'dataView', 'get').mockReturnValue(dataViewStub);
diff --git a/packages/common/src/extensions/slickDraggableGrouping.ts b/packages/common/src/extensions/slickDraggableGrouping.ts
index e11682d9f..d15b8ec82 100644
--- a/packages/common/src/extensions/slickDraggableGrouping.ts
+++ b/packages/common/src/extensions/slickDraggableGrouping.ts
@@ -129,6 +129,10 @@ export class SlickDraggableGrouping {
return this._gridUid || (this.grid?.getUID() ?? '');
}
+ get gridContainer() {
+ return this.grid.getContainerNode();
+ }
+
/** Initialize plugin. */
init(grid: SlickGrid, groupingOptions?: DraggableGrouping) {
this._addonOptions = { ...this._defaults, ...groupingOptions };
@@ -215,7 +219,7 @@ export class SlickDraggableGrouping {
this._eventHandler.unsubscribeAll();
this.pubSubService.unsubscribeAll(this._subscriptions);
this._bindingEventService.unbindAll();
- emptyElement(document.querySelector(`.${this.gridUid} .slick-preheader-panel`));
+ emptyElement(this.gridContainer.querySelector(`.${this.gridUid} .slick-preheader-panel`));
}
clearDroppedGroups() {
@@ -354,8 +358,8 @@ export class SlickDraggableGrouping {
}
} as SortableOptions;
- this._sortableLeftInstance = Sortable.create(document.querySelector(`.${grid.getUID()} .slick-header-columns.slick-header-columns-left`) as HTMLDivElement, sortableOptions) as SortableInstance;
- this._sortableRightInstance = Sortable.create(document.querySelector(`.${grid.getUID()} .slick-header-columns.slick-header-columns-right`) as HTMLDivElement, sortableOptions) as SortableInstance;
+ this._sortableLeftInstance = Sortable.create(this.gridContainer.querySelector(`.${grid.getUID()} .slick-header-columns.slick-header-columns-left`) as HTMLDivElement, sortableOptions) as SortableInstance;
+ this._sortableRightInstance = Sortable.create(this.gridContainer.querySelector(`.${grid.getUID()} .slick-header-columns.slick-header-columns-right`) as HTMLDivElement, sortableOptions) as SortableInstance;
return {
sortableLeftInstance: this._sortableLeftInstance,
diff --git a/packages/common/src/extensions/slickGridMenu.ts b/packages/common/src/extensions/slickGridMenu.ts
index 1b0ca7ef0..477584b4b 100644
--- a/packages/common/src/extensions/slickGridMenu.ts
+++ b/packages/common/src/extensions/slickGridMenu.ts
@@ -187,7 +187,8 @@ export class SlickGridMenu extends MenuBaseClass {
const gridUidSelector = this._gridUid ? `.${this._gridUid}` : '';
const gridMenuWidth = this._addonOptions?.menuWidth || this._defaults.menuWidth;
const headerSide = (this.gridOptions.hasOwnProperty('frozenColumn') && this.gridOptions.frozenColumn! >= 0) ? 'right' : 'left';
- this._headerElm = document.querySelector(`${gridUidSelector} .slick-header-${headerSide}`);
+ const gridContainer = this.grid.getContainerNode();
+ this._headerElm = gridContainer.querySelector(`.slick-header-${headerSide}`);
if (this._headerElm && this._addonOptions) {
// resize the header row to include the hamburger menu icon
@@ -196,7 +197,7 @@ export class SlickGridMenu extends MenuBaseClass {
// if header row is enabled, we also need to resize its width
const enableResizeHeaderRow = this._addonOptions.resizeOnShowHeaderRow ?? this._defaults.resizeOnShowHeaderRow;
if (enableResizeHeaderRow && this.gridOptions.showHeaderRow) {
- const headerRowElm = document.querySelector(`${gridUidSelector} .slick-headerrow`);
+ const headerRowElm = gridContainer.querySelector(`${gridUidSelector} .slick-headerrow`);
if (headerRowElm) {
headerRowElm.style.width = `calc(100% - ${gridMenuWidth}px)`;
}
diff --git a/packages/common/src/interfaces/gridOption.interface.ts b/packages/common/src/interfaces/gridOption.interface.ts
index cc6a84337..22d813772 100644
--- a/packages/common/src/interfaces/gridOption.interface.ts
+++ b/packages/common/src/interfaces/gridOption.interface.ts
@@ -587,6 +587,9 @@ export interface GridOption {
/** CSS class name used when cell is selected */
selectedCellCssClass?: string;
+ /** Defaults to undefined. If we are inside a Shadow DOM tree, this must be the shadow root of the tree */
+ shadowRoot?: ShadowRoot;
+
/** Do we want to show cell selection? */
showCellSelection?: boolean;
diff --git a/packages/common/src/services/__tests__/extension.service.spec.ts b/packages/common/src/services/__tests__/extension.service.spec.ts
index 9c9551814..3091887fd 100644
--- a/packages/common/src/services/__tests__/extension.service.spec.ts
+++ b/packages/common/src/services/__tests__/extension.service.spec.ts
@@ -87,6 +87,7 @@ jest.mock('../../extensions/slickRowMoveManager', () => ({
const gridStub = {
autosizeColumns: jest.fn(),
getColumnIndex: jest.fn(),
+ getContainerNode: jest.fn(),
getOptions: jest.fn(),
getPluginByName: jest.fn(),
getPreHeaderPanel: jest.fn(),
@@ -131,6 +132,7 @@ const filterServiceStub = {
const pubSubServiceStub = {
publish: jest.fn(),
subscribe: jest.fn(),
+ subscribeEvent: jest.fn(),
unsubscribe: jest.fn(),
unsubscribeAll: jest.fn(),
} as BasePubSubService;
@@ -190,6 +192,7 @@ describe('ExtensionService', () => {
treeDataServiceStub,
translateService,
);
+ jest.spyOn(gridStub, 'getContainerNode').mockReturnValue(document.body as HTMLDivElement);
});
afterEach(() => {
@@ -304,7 +307,7 @@ describe('ExtensionService', () => {
expect(extSpy).toHaveBeenCalled();
expect(output).toEqual({ name: ExtensionName.autoTooltip, instance: pluginInstance } as ExtensionModel);
- expect(output.instance instanceof SlickAutoTooltip).toBeTrue();
+ expect(output!.instance instanceof SlickAutoTooltip).toBeTrue();
});
it('should register the ColumnPicker addon when "enableColumnPicker" is set in the grid options', () => {
@@ -318,7 +321,7 @@ describe('ExtensionService', () => {
expect(gridSpy).toHaveBeenCalled();
expect(output).toEqual({ name: ExtensionName.columnPicker, instance: pluginInstance } as ExtensionModel);
- expect(output.instance instanceof SlickColumnPicker).toBeTrue();
+ expect(output!.instance instanceof SlickColumnPicker).toBeTrue();
});
it('should call "onExtensionRegistered" when defined in grid option and the ColumnPicker control gets created', () => {
@@ -335,7 +338,7 @@ describe('ExtensionService', () => {
const output = service.getExtensionByName(ExtensionName.columnPicker);
expect(onRegisteredMock).toHaveBeenCalledWith(expect.toBeObject());
- expect(output.instance instanceof SlickColumnPicker).toBeTrue();
+ expect(output!.instance instanceof SlickColumnPicker).toBeTrue();
});
it('should register the DraggableGrouping addon when "enableDraggableGrouping" is set in the grid options', () => {
@@ -355,7 +358,7 @@ describe('ExtensionService', () => {
const output2 = service.getExtensionByName(ExtensionName.groupItemMetaProvider);
expect(onRegisteredMock).toHaveBeenCalledWith(expect.toBeObject());
- expect(output.instance instanceof SlickDraggableGrouping).toBeTrue();
+ expect(output!.instance instanceof SlickDraggableGrouping).toBeTrue();
expect(gridSpy).toHaveBeenCalled();
expect(pluginInstance).toBeTruthy();
expect(output!.instance).toEqual(pluginInstance);
@@ -377,7 +380,7 @@ describe('ExtensionService', () => {
const output = service.getExtensionByName(ExtensionName.gridMenu);
expect(onRegisteredMock).toHaveBeenCalledWith(expect.toBeObject());
- expect(output.instance instanceof SlickGridMenu).toBeTrue();
+ expect(output!.instance instanceof SlickGridMenu).toBeTrue();
});
it('should register the GroupItemMetaProvider addon when "enableGrouping" is set in the grid options', () => {
@@ -389,7 +392,7 @@ describe('ExtensionService', () => {
const pluginInstance = service.getExtensionInstanceByName(ExtensionName.groupItemMetaProvider);
expect(gridSpy).toHaveBeenCalled();
- expect(output.instance instanceof SlickGroupItemMetadataProvider).toBeTrue();
+ expect(output!.instance instanceof SlickGroupItemMetadataProvider).toBeTrue();
expect(pluginInstance).toBeTruthy();
expect(output!.instance).toEqual(pluginInstance);
expect(output).toEqual({ name: ExtensionName.groupItemMetaProvider, instance: pluginInstance } as ExtensionModel);
@@ -450,7 +453,7 @@ describe('ExtensionService', () => {
const pluginInstance = service.getExtensionInstanceByName(ExtensionName.cellMenu);
expect(onRegisteredMock).toHaveBeenCalledWith(expect.toBeObject());
- expect(output.instance instanceof SlickCellMenu).toBeTrue();
+ expect(output!.instance instanceof SlickCellMenu).toBeTrue();
expect(gridSpy).toHaveBeenCalled();
expect(pluginInstance).toBeTruthy();
expect(output!.instance).toEqual(pluginInstance);
@@ -467,7 +470,7 @@ describe('ExtensionService', () => {
const pluginInstance = service.getExtensionInstanceByName(ExtensionName.contextMenu);
expect(onRegisteredMock).toHaveBeenCalledWith(expect.toBeObject());
- expect(output.instance instanceof SlickContextMenu).toBeTrue();
+ expect(output!.instance instanceof SlickContextMenu).toBeTrue();
expect(gridSpy).toHaveBeenCalled();
expect(pluginInstance).toBeTruthy();
expect(output!.instance).toEqual(pluginInstance);
@@ -484,7 +487,7 @@ describe('ExtensionService', () => {
const pluginInstance = service.getExtensionInstanceByName(ExtensionName.headerButton);
expect(onRegisteredMock).toHaveBeenCalledWith(expect.toBeObject());
- expect(output.instance instanceof SlickHeaderButtons).toBeTrue();
+ expect(output!.instance instanceof SlickHeaderButtons).toBeTrue();
expect(gridSpy).toHaveBeenCalled();
expect(pluginInstance).toBeTruthy();
expect(output!.instance).toEqual(pluginInstance);
@@ -501,7 +504,7 @@ describe('ExtensionService', () => {
const pluginInstance = service.getExtensionInstanceByName(ExtensionName.headerMenu);
expect(onRegisteredMock).toHaveBeenCalledWith(expect.toBeObject());
- expect(output.instance instanceof SlickHeaderMenu).toBeTrue();
+ expect(output!.instance instanceof SlickHeaderMenu).toBeTrue();
expect(gridSpy).toHaveBeenCalled();
expect(pluginInstance).toBeTruthy();
expect(output!.instance).toEqual(pluginInstance);
@@ -519,7 +522,7 @@ describe('ExtensionService', () => {
const pluginInstance = service.getExtensionInstanceByName(ExtensionName.cellExternalCopyManager);
expect(onRegisteredMock).toHaveBeenCalledWith(expect.toBeObject());
- expect(output.instance instanceof SlickCellExcelCopyManager).toBeTrue();
+ expect(output!.instance instanceof SlickCellExcelCopyManager).toBeTrue();
expect(gridSpy).toHaveBeenCalled();
expect(pluginInstance).toBeTruthy();
expect(output!.instance).toEqual(pluginInstance);
@@ -643,7 +646,7 @@ describe('ExtensionService', () => {
service.bindDifferentExtensions();
- const columnPickerInstance = service.getExtensionByName(ExtensionName.columnPicker).instance;
+ const columnPickerInstance = service.getExtensionByName(ExtensionName.columnPicker)!.instance;
const extSpy = jest.spyOn(columnPickerInstance, 'translateColumnPicker');
service.translateColumnPicker();
expect(extSpy).toHaveBeenCalled();
@@ -815,7 +818,7 @@ describe('ExtensionService', () => {
service.renderColumnHeaders(columnsMock);
expect(setColumnsSpy).toHaveBeenCalledWith(columnsMock);
- expect(service.getExtensionByName(ExtensionName.columnPicker).instance.columns).toEqual(columnsMock);
+ expect(service.getExtensionByName(ExtensionName.columnPicker)!.instance.columns).toEqual(columnsMock);
});
it('should replace the Grid Menu columns when plugin is enabled and method is called with new column definition collection provided as argument', () => {
@@ -834,7 +837,7 @@ describe('ExtensionService', () => {
service.renderColumnHeaders(columnsMock);
expect(setColumnsSpy).toHaveBeenCalledWith(columnsMock);
- expect(service.getExtensionByName(ExtensionName.gridMenu).instance.columns).toEqual(columnsMock);
+ expect(service.getExtensionByName(ExtensionName.gridMenu)!.instance.columns).toEqual(columnsMock);
});
});
});
diff --git a/packages/vanilla-bundle/package.json b/packages/vanilla-bundle/package.json
index d6585d08a..b693f5730 100644
--- a/packages/vanilla-bundle/package.json
+++ b/packages/vanilla-bundle/package.json
@@ -65,7 +65,7 @@
"@slickgrid-universal/utils": "workspace:~",
"dequal": "^2.0.3",
"flatpickr": "^4.6.13",
- "slickgrid": "^4.0.3",
+ "slickgrid": "^4.1.1",
"sortablejs": "^1.15.0",
"whatwg-fetch": "^3.6.19"
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8e1b7ea74..cb4d6259a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -97,8 +97,8 @@ importers:
specifier: ^4.0.2
version: 4.0.2
slickgrid:
- specifier: ^4.0.3
- version: 4.0.3
+ specifier: ^4.1.1
+ version: 4.1.1
sortablejs:
specifier: ^1.15.0
version: 1.15.0
@@ -236,8 +236,8 @@ importers:
specifier: ^0.5.0
version: 0.5.0
slickgrid:
- specifier: ^4.0.3
- version: 4.0.3
+ specifier: ^4.1.1
+ version: 4.1.1
sortablejs:
specifier: ^1.15.0
version: 1.15.0
@@ -528,8 +528,8 @@ importers:
specifier: ^4.6.13
version: 4.6.13
slickgrid:
- specifier: ^4.0.3
- version: 4.0.3
+ specifier: ^4.1.1
+ version: 4.1.1
sortablejs:
specifier: ^1.15.0
version: 1.15.0
@@ -8699,8 +8699,8 @@ packages:
is-fullwidth-code-point: 3.0.0
dev: true
- /slickgrid@4.0.3:
- resolution: {integrity: sha512-zA89snSHupR3vmuP1Q/Lb7jYjykGH4cbcigKlSnmIksdUwClJw2DhUYtgJL8Py9OTIKRm4GpuF14dA0tTGwrYg==}
+ /slickgrid@4.1.1:
+ resolution: {integrity: sha512-KYwo7e6VzZiwgmMwPw8oKvJFVt61JtnBKPgwqS+t7o1FTQHhZAHf6HPxssqGRmfqlTbg3Li7UjBqYQkOTGrBVA==}
dependencies:
sortablejs: 1.15.0
diff --git a/test/cypress/e2e/example20.cy.ts b/test/cypress/e2e/example20.cy.ts
new file mode 100644
index 000000000..8fea00d6e
--- /dev/null
+++ b/test/cypress/e2e/example20.cy.ts
@@ -0,0 +1,57 @@
+describe('Example 20 - Basic grid inside a Shadow DOM', { retries: 0 }, () => {
+ const fullTitles = ['Title', 'Duration (days)', '% Complete', 'Start', 'Finish', 'Effort Driven'];
+
+ it('should display Example title', () => {
+ cy.visit(`${Cypress.config('baseUrl')}/example20`);
+ cy.get('h3').should('contain', 'Example 20 - Basic grid inside a Shadow DOM');
+ cy.get('h3 span.subtitle').should('contain', '(with Salesforce Theme)');
+ });
+
+ it('should have a grid with size 800 * 450px', () => {
+ cy.get('#host').shadow()
+ .find('.grid20')
+ .should('have.css', 'width', '800px');
+
+ cy.get('#host').shadow()
+ .find('.grid20 > .slickgrid-container')
+ .should($el => expect(parseInt(`${$el.height()}`, 10)).to.eq(450));
+ });
+
+ it('should have exact column titles in grid', () => {
+ cy.get('#host').shadow()
+ .find('.grid20')
+ .find('.slick-header-columns')
+ .children()
+ .each(($child, index) => expect($child.text()).to.eq(fullTitles[index]));
+ });
+
+ it('should click on the "Title" column to "Sort Ascending"', () => {
+ cy.get('#host').shadow()
+ .find('.grid20')
+ .find('.slick-header-column')
+ .first()
+ .click();
+
+ cy.get('#host').shadow()
+ .find('.slick-row')
+ .first()
+ .children('.slick-cell')
+ .first()
+ .should('contain', 'Task 0');
+ });
+
+ it('should click again on the "Title" column to "Sort Descending"', () => {
+ cy.get('#host').shadow()
+ .find('.grid20')
+ .find('.slick-header-column')
+ .first()
+ .click();
+
+ cy.get('#host').shadow()
+ .find('.slick-row')
+ .first()
+ .children('.slick-cell')
+ .first()
+ .should('contain', 'Task 99');
+ });
+});