Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d45881e
feat: add custom menu slot renderers
ghiscoding Feb 6, 2026
30bdb7b
chore: improve slot demo & code implementation
ghiscoding Feb 10, 2026
f7b7a15
chore: add menu args TS Generics
ghiscoding Feb 11, 2026
5411d2c
chore: add unit tests for slot renderer & default renderer
ghiscoding Feb 11, 2026
cb57586
Merge branch 'feat/header-menu-slots' of https://github.com/ghiscodin…
ghiscoding Feb 12, 2026
003c788
chore: add new `commandListBuilder` callback
ghiscoding Feb 12, 2026
8807d66
Merge branch 'next' into feat/header-menu-slots
ghiscoding Feb 12, 2026
871903c
chore: fix some typing errors
ghiscoding Feb 12, 2026
b45bfee
chore: rename `defaultMenuItemRenderer` & add E2E tests
ghiscoding Feb 13, 2026
c27b959
chore: add menu item action when missing in override
ghiscoding Feb 13, 2026
a9419a0
chore: fix failing cypress test
ghiscoding Feb 13, 2026
2a63943
Merge branch 'next' into feat/header-menu-slots
ghiscoding Feb 13, 2026
aea4e8b
chore: use buit-in tooltip plugin instead of div
ghiscoding Feb 13, 2026
015e9f1
chore: loosen cypress rotate test
ghiscoding Feb 13, 2026
ae72869
chore: add docs and cleanup code accross the project
ghiscoding Feb 13, 2026
44cec34
docs: typo
ghiscoding Feb 13, 2026
9396c10
chore: remove deprecated TS downlevelIteration
ghiscoding Feb 13, 2026
be45c8c
docs: replace all ms-select.js reference with multiple-select-vanilla
ghiscoding Feb 13, 2026
9b48399
chore: add slot renderer demo for all frameworks and improve types
ghiscoding Feb 13, 2026
0e268f3
chore: add `hideCommands` and deprecate all hide props
ghiscoding Feb 14, 2026
62e7016
Merge branch 'feat/header-menu-slots' of https://github.com/ghiscodin…
ghiscoding Feb 14, 2026
50fe243
chore: add some hideCommands to demos as comments
ghiscoding Feb 14, 2026
8500768
chore: revert React lazy route
ghiscoding Feb 14, 2026
8f03dac
chore: revert Vue lazy route
ghiscoding Feb 14, 2026
c065cc6
chore: merge router imports
ghiscoding Feb 14, 2026
6c80692
chore: simplify code a bit more
ghiscoding Feb 14, 2026
4661953
chore: simplify code a bit more
ghiscoding Feb 14, 2026
927558d
chore: use typing instead of casting
ghiscoding Feb 14, 2026
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
4 changes: 3 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
_variables.scss
_variables-theme-material.scss
_variables-theme-salesforce.scss
**/test/vitest-coverage/*.*
**/test/vitest-coverage/*.*
demos/vue/src/router/index.ts
demos/react/src/examples/slickgrid/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class CustomAureliaViewModelEditor implements Editor {
elmBindingContext?: IBindingContext;

constructor(private args: any) {
this.grid = args && args.grid;
this.grid = args?.grid;
this.init();
}

Expand Down
2 changes: 1 addition & 1 deletion demos/aurelia/src/examples/slickgrid/example10.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ export class Example10 {
}

onGrid1SelectedRowsChanged(_e: Event, args: any) {
const grid = args && args.grid;
const grid = args?.grid;
if (Array.isArray(args.rows)) {
this.selectedTitle = args.rows.map((idx: number) => {
const item = grid.getDataItem(idx);
Expand Down
2 changes: 1 addition & 1 deletion demos/aurelia/src/examples/slickgrid/example2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export class Example2 {
minWidth: 100,
formatter: customEnableButtonFormatter,
onCellClick: (_e, args) => {
this.toggleCompletedProperty(args && args.dataContext);
this.toggleCompletedProperty(args?.dataContext);
},
},
];
Expand Down
4 changes: 2 additions & 2 deletions demos/aurelia/src/examples/slickgrid/example23.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,11 @@ export class Example23 {
}

refreshMetrics(_e: Event, args: any) {
if (args && args.current >= 0) {
if (args?.current >= 0) {
setTimeout(() => {
this.metrics = {
startTime: new Date(),
itemCount: (args && args.current) || 0,
itemCount: args?.current || 0,
totalItemCount: this.dataset.length || 0,
};
});
Expand Down
10 changes: 5 additions & 5 deletions demos/aurelia/src/examples/slickgrid/example24.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ export class Example24 {
// optionally and conditionally define when the the menu is usable,
// this should be used with a custom formatter to show/hide/disable the menu
menuUsabilityOverride: (args) => {
const dataContext = args && args.dataContext;
const dataContext = args?.dataContext;
return dataContext.id < 21; // say we want to display the menu only from Task 0 to 20
},
// which column to show the command list? when not defined it will be shown over all columns
Expand Down Expand Up @@ -459,7 +459,7 @@ export class Example24 {
},
// only show command to 'Help' when the task is Not Completed
itemVisibilityOverride: (args) => {
const dataContext = args && args.dataContext;
const dataContext = args?.dataContext;
return !dataContext.completed;
},
},
Expand Down Expand Up @@ -525,7 +525,7 @@ export class Example24 {
textCssClass: 'italic',
// only enable this option when the task is Not Completed
itemUsabilityOverride: (args) => {
const dataContext = args && args.dataContext;
const dataContext = args?.dataContext;
return !dataContext.completed;
},
// you can use the 'action' callback and/or subscribe to the 'onCallback' event, they both have the same arguments
Expand All @@ -547,7 +547,7 @@ export class Example24 {
disabled: true,
// only shown when the task is Not Completed
itemVisibilityOverride: (args) => {
const dataContext = args && args.dataContext;
const dataContext = args?.dataContext;
return !dataContext.completed;
},
},
Expand Down Expand Up @@ -578,7 +578,7 @@ export class Example24 {
// subscribe to Context Menu onOptionSelected event (or use the action callback on each option)
onOptionSelected: (_e: any, args: any) => {
// change Priority
const dataContext = args && args.dataContext;
const dataContext = args?.dataContext;
if (dataContext?.hasOwnProperty('priority')) {
dataContext.priority = args.item.option;
this.aureliaGrid.gridService.updateItem(dataContext);
Expand Down
2 changes: 1 addition & 1 deletion demos/aurelia/src/examples/slickgrid/example3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const NB_ITEMS = 100;
// you can create custom validator to pass to an inline editor
const myCustomTitleValidator: EditorValidator = (value: any) => {
// you can get the Editor Args which can be helpful, e.g. we can get the Translate Service from it
// const grid = args && args.grid;
// const grid = args?.grid;
// const gridOptions = grid.getOptions() as GridOption;
// const i18n = gridOptions.i18n;

Expand Down
2 changes: 1 addition & 1 deletion demos/aurelia/src/examples/slickgrid/example33.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ export class Example33 {
onCommand: (e, args) => this.executeCommand(e, args),
onOptionSelected: (_e, args) => {
// change "Completed" property with new option selected from the Cell Menu
const dataContext = args && args.dataContext;
const dataContext = args?.dataContext;
if (dataContext && dataContext.hasOwnProperty('completed')) {
dataContext.completed = args.item.option;
this.aureliaGrid.gridService.updateItem(dataContext);
Expand Down
4 changes: 2 additions & 2 deletions demos/aurelia/src/examples/slickgrid/example4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,12 +312,12 @@ export class Example4 {
}

refreshMetrics(_e: Event, args: any) {
if (args && args.current >= 0) {
if (args?.current >= 0) {
setTimeout(() => {
this.metrics = {
startTime: new Date(),
endTime: new Date(),
itemCount: (args && args.current) || 0,
itemCount: args?.current || 0,
totalItemCount: this.dataset.length || 0,
};
});
Expand Down
75 changes: 75 additions & 0 deletions demos/aurelia/src/examples/slickgrid/example51.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<div class="demo51">
<h2>
<span>Example 51: Menus with Slots</span>
<span class="float-end">
<a
style="font-size: 18px"
target="_blank"
href="https://github.com/ghiscoding/slickgrid-universal/blob/master/demos/aurelia/src/examples/slickgrid/example51.ts"
>
<span class="mdi mdi-link mdi-v-align-sub"></span> code
</a>
</span>
<button
class="ms-2 btn btn-outline-secondary btn-sm btn-icon"
type="button"
data-test="toggle-subtitle"
click.trigger="toggleSubTitle()"
>
<span class="mdi mdi-information-outline" title="Toggle example sub-title details"></span>
</button>
<button class="btn btn-outline-secondary btn-sm btn-icon" click.trigger="toggleDarkMode()" data-test="toggle-dark-mode">
<span class="mdi mdi-theme-light-dark"></span>
<span>Toggle Dark Mode</span>
</button>
</h2>

<div class="subtitle alert alert-light">
<h5 class="mb-2">
<span class="mdi mdi-information-outline"></span>
<strong>Menu Slots Demo with Custom Renderer</strong>
</h5>
<p class="mb-2">
Click on the menu buttons to see the new <strong>single slot functionality</strong> working across all menu types (Header Menu, Cell
Menu, Context Menu, Grid Menu):
</p>
<p class="mt-2">
<small
><strong>Note:</strong> The demo focuses on the custom rendering capability via <code>slotRenderer</code> and
<code>defaultMenuItemRenderer</code>, which work across all menu plugins (SlickHeaderMenu, SlickCellMenu, SlickContextMenu,
SlickGridMenu). Also note that the keyboard shortcuts displayed in the menus (e.g., <code>Alt+↑</code>, <code>F5</code>) are for
demo purposes only and do not actually trigger any actions.
</small>
</p>
</div>

<section class="row mb-2">
<div class="mb-1">
<button class="btn btn-outline-secondary btn-sm btn-icon" data-test="clear-grouping-btn" click.trigger="clearGrouping()">
<span>Clear grouping</span>
</button>
<button class="btn btn-outline-secondary btn-sm btn-icon" data-test="collapse-all-btn" click.trigger="collapseAllGroups()">
<span class="mdi mdi-arrow-collapse"></span>
<span>Collapse all groups</span>
</button>
<button class="btn btn-outline-secondary btn-sm btn-icon" data-test="expand-all-btn" click.trigger="expandAllGroups()">
<span class="mdi mdi-arrow-expand"></span>
<span>Expand all groups</span>
</button>
<button class="btn btn-outline-secondary btn-sm btn-icon" data-test="group-duration-sort-value-btn" click.trigger="groupByDuration()">
Group by Duration
</button>
</div>
</section>

<div id="grid-container" class="col-sm-12">
<aurelia-slickgrid
grid-id="grid51"
columns.bind="columnDefinitions"
options.bind="gridOptions"
dataset.bind="dataset"
on-aurelia-grid-created.trigger="aureliaGridReady($event.detail)"
>
</aurelia-slickgrid>
</div>
</div>
144 changes: 144 additions & 0 deletions demos/aurelia/src/examples/slickgrid/example51.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
body {
--slick-menu-item-height: 30px;
--slick-menu-line-height: 30px;
--slick-column-picker-item-height: 28px;
--slick-column-picker-line-height: 28px;
--slick-menu-item-border-radius: 4px;
--slick-menu-item-hover-border: 1px solid #148dff;
--slick-column-picker-item-hover-color: #fff;
--slick-column-picker-item-border-radius: 4px;
--slick-column-picker-item-hover-border: 1px solid #148dff;
--slick-menu-item-hover-color: #fff;
--slick-tooltip-background-color: #4c4c4c;
--slick-tooltip-color: #fff;
--slick-tooltip-font-size: 14px;
.slick-cell-menu,
.slick-context-menu,
.slick-grid-menu,
.slick-header-menu {
.slick-menu-item:hover:not(.slick-menu-item-disabled) {
color: #0a34b5;
}
}
.slick-menu-footer {
padding: 4px 6px;
border-top: 1px solid #c0c0c0;
}
}

kbd {
background-color: #eee;
color: #202020;
}
.key-hint {
background: #eee;
border: 1px solid #ccc;
border-radius: 2px;
padding: 2px 4px;
font-size: 10px;
margin-left: 10px;
white-space: nowrap;
display: inline-flex;
align-items: center;
height: 20px;

&.beta,
&.danger,
&.warn {
color: white;
font-size: 8px;
font-weight: bold;
}
&.beta {
background: #4444ff;
border: 1px solid #5454ff;
}

&.danger {
background: #ff4444;
border: 1px solid #fb5a5a;
}

&.warn {
background: #ff9800;
border: 1px solid #fba321;
}
}

.edit-cell {
// background: #eee;
border: 1px solid #ccc;
border-radius: 2px;
padding: 2px 4px;
font-size: 10px;
margin-left: 10px;
display: inline-flex;
align-items: center;
height: 18px;
}

.export-timestamp {
background-color: #4c4c4c;
color: #fff;
padding: 8px;
border-radius: 4px;
position: absolute;
z-index: 999999;
}

.advanced-export-icon,
.edit-cell-icon,
.recalc-icon {
width: 20px;
height: 20px;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 4px;
transition: transform 0.2s;
color: white;
font-size: 10px;
}
.advanced-export-icon {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.edit-cell-icon {
background: linear-gradient(135deg, #00c853 0%, #64dd17 100%);
}
.recalc-icon {
background: linear-gradient(135deg, #c800a3 0%, #a31189 100%);
}

.round-tag {
width: 6px;
height: 6px;
border-radius: 50%;
display: inline-block;
background: #44ff44;
box-shadow: 0 0 4px #44ff44;
margin-left: 10px;
}

.menu-item {
display: flex;
align-items: center;
flex: 1;
justify-content: space-between;

.menu-item-label.warn {
flex: 1;
color: #f09000;
}
}
.menu-item-icon {
margin-right: 4px;
font-size: 18px;
&.warn {
color: #ff9800;
}
}

.menu-item-label {
flex: 1;
}
Loading
Loading