Skip to content

Commit

Permalink
feat: add sub-menu(s) to CellMenu & ContextMenu plugins (#867)
Browse files Browse the repository at this point in the history
* feat: add sub-menus to CellMenu/ContextMenu plugins
- also merge command/option code since we had a lot of duplicate code to do roughly the same thing but with different list (command/options)
  • Loading branch information
ghiscoding authored Oct 20, 2023
1 parent d6e5386 commit 0309ec4
Show file tree
Hide file tree
Showing 11 changed files with 1,292 additions and 567 deletions.
534 changes: 517 additions & 17 deletions cypress/e2e/example-plugin-contextmenu.cy.ts

Large diffs are not rendered by default.

106 changes: 98 additions & 8 deletions examples/example-plugin-contextmenu.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,24 @@

.slick-context-menu {
border: 1px solid #718BB7;
box-shadow: 2px 2px 2px silver;
}
.slick-cell-menu.slick-submenu,
.slick-context-menu.slick-submenu {
background-color: #fbfbfb;
/* border-width: 2px; */
box-shadow: 0 2px 4px 2px rgba(146, 152, 163, 0.4);
min-width: 150px;
}
</style>
</head>

<body>
<table width="100%">
<tr>
<td valign="top" width="50%">
<td valign="top" width="50%" style="padding-left: 0px">
<div id="myGrid" class="slick-container" style="width:650px;height:700px;"></div>
</td>
<td valign="top">
<td valign="top" style="display: block">
<h2>
<h2>
<a href="/examples/index.html" style="text-decoration: none; font-size: 22px">&#x2302;</a>
Expand Down Expand Up @@ -285,10 +291,13 @@ <h2>View Source:</h2>

switch (command) {
case "command1":
alert('Command 1');
break;
case "command2":
alert('Command 2');
alert(args.item.title);
break;
case "export-csv":
case "export-txt":
case "export-xls":
alert("Exporting as " + args.item.title);
break;
case "copy-text":
copyCellValue(args.value);
Expand All @@ -301,6 +310,9 @@ <h2>View Source:</h2>
dataView.deleteItem(dataContext.id);
}
break;
default:
alert("Command: " + args.command);
break;
}
}

Expand Down Expand Up @@ -352,7 +364,37 @@ <h2>View Source:</h2>
"divider",
// { divider: true },
{ command: "help", title: "Help", iconCssClass: "sgi sgi-help-circle-outline" },
{ command: "something", title: "Disabled Command", disabled: true }
{ command: "something", title: "Disabled Command", disabled: true },
"divider",
{
// we can also have multiple nested sub-menus
command: 'export', title: 'Export',
commandItems: [
{ command: "export-txt", title: "Text" },
{
command: 'sub-menu', title: 'Excel', cssClass: "green", subMenuTitle: "available formats", subMenuTitleCssClass: "italic orange",
commandItems: [
{ command: "export-csv", title: "Excel (csv)" },
{ command: "export-xls", title: "Excel (xls)" },
]
}
]
},
{
command: 'feedback', title: 'Feedback',
commandItems: [
{ command: "request-update", title: "Request update from shipping team", iconCssClass: "sgi sgi-star", tooltip: "this will automatically send an alert to the shipping team to contact the user for an update" },
"divider",
{
command: 'sub-menu', title: 'Contact Us', iconCssClass: "sgi sgi-user", subMenuTitle: "contact us...", subMenuTitleCssClass: "italic",
commandItems: [
{ command: "contact-email", title: "Email us", iconCssClass: "sgi sgi-pencil-outline" },
{ command: "contact-chat", title: "Chat with us", iconCssClass: "sgi sgi-message-outline" },
{ command: "contact-meeting", title: "Book an appointment", iconCssClass: "sgi sgi-coffee-outline" },
]
}
]
}
],
optionTitle: "Change Effort Driven",
optionItems: [
Expand All @@ -373,6 +415,13 @@ <h2>View Source:</h2>
return (!args.dataContext.effortDriven);
}
},
{
// we can also have multiple nested sub-menus
option: null, title: "Sub-Options (demo)", subMenuTitle: "Set Effort Driven", optionItems: [
{ option: true, title: "True", iconCssClass: 'sgi sgi-checkbox-marked-outline green' },
{ option: false, title: "False", iconCssClass: 'sgi sgi-checkbox-blank-outline pink' },
]
}
]
}
}
Expand All @@ -388,6 +437,8 @@ <h2>View Source:</h2>
};

var contextMenuOptions = {
// subItemChevronClass: 'sgi sgi-chevron-right',

// 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: function (args) {
Expand All @@ -412,6 +463,36 @@ <h2>View Source:</h2>
}
},
{ command: "something", title: "Command (always disabled)", disabled: true },
"divider",
{
// we can also have multiple nested sub-menus
command: 'export', title: 'Export',
commandItems: [
{ command: "export-txt", title: "Text" },
{
command: 'sub-menu', title: 'Excel', cssClass: "green", subMenuTitle: "available formats", subMenuTitleCssClass: "italic orange",
commandItems: [
{ command: "export-csv", title: "Excel (csv)" },
{ command: "export-xls", title: "Excel (xls)" },
]
}
]
},
{
command: 'feedback', title: 'Feedback',
commandItems: [
{ command: "column-love", title: "Request update from shipping team", iconCssClass: "sgi sgi-tag-outline", tooltip: "this will automatically send an alert to the shipping team to contact the user for an update" },
"divider",
{
command: 'sub-menu', title: 'Contact Us', iconCssClass: "sgi sgi-user", subMenuTitle: "contact us...", subMenuTitleCssClass: "italic",
commandItems: [
{ command: "contact-email", title: "Email us", iconCssClass: "sgi sgi-pencil-outline" },
{ command: "contact-chat", title: "Chat with us", iconCssClass: "sgi sgi-message-outline" },
{ command: "contact-meeting", title: "Book an appointment", iconCssClass: "sgi sgi-coffee-outline" },
]
}
]
}
],

// Options allows you to edit a column from an option chose a list
Expand Down Expand Up @@ -444,13 +525,22 @@ <h2>View Source:</h2>
return (!args.dataContext.effortDriven);
}
},
"divider",
{
// we can also have multiple nested sub-menus
option: null, title: "Sub-Options (demo)", subMenuTitle: "Set Priority", optionItems: [
{ option: 1, iconCssClass: "sgi sgi-star-outline", title: "Low" },
{ option: 2, iconCssClass: "sgi sgi-star orange", title: "Medium" },
{ option: 3, iconCssClass: "sgi sgi-star red", title: "High" },
]
}
]
};

document.addEventListener("DOMContentLoaded", function() {
dataView = new Slick.Data.DataView();
grid = new Slick.Grid("#myGrid", dataView, columns, gridOptions);
cellMenuPlugin = new Slick.Plugins.CellMenu({ hideMenuOnScroll: true });
cellMenuPlugin = new Slick.Plugins.CellMenu({ hideMenuOnScroll: true, subItemChevronClass: 'sgi sgi-chevron-right' });
contextMenuPlugin = new Slick.Plugins.ContextMenu(contextMenuOptions);
var columnpicker = new Slick.Controls.ColumnPicker(columns, grid, gridOptions);

Expand Down
3 changes: 3 additions & 0 deletions src/models/cellMenuOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ export interface CellMenuOption {
/** Optional Title of the Option section, it will be hidden when nothing is provided */
optionTitle?: string;

/** CSS class that can be added on the right side of a sub-item parent (typically a chevron-right icon) */
subItemChevronClass?: string;

// --
// action/override callbacks

Expand Down
3 changes: 3 additions & 0 deletions src/models/contextMenuOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ export interface ContextMenuOption {
/** Optional Title of the Option section, it will be hidden when nothing is provided */
optionTitle?: string;

/** CSS class that can be added on the right side of a sub-item parent (typically a chevron-right icon) */
subItemChevronClass?: string;

// --
// action/override callbacks

Expand Down
3 changes: 3 additions & 0 deletions src/models/menuCommandItem.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export interface MenuCommandItem<A = MenuCommandItemCallbackArgs, R = MenuCallba
/** A command identifier to be passed to the onCommand event callback handler (when using "commandItems"). */
command: string;

/** Array of Command Items (title, command, disabled, ...) */
commandItems?: Array<MenuCommandItem | 'divider'>;

// --
// action/override callbacks

Expand Down
8 changes: 8 additions & 0 deletions src/models/menuItem.interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { MenuCallbackArgs } from './menuCallbackArgs.interface';

export type MenuType = 'command' | 'option';

export interface MenuItem<O = MenuCallbackArgs> {
/** A CSS class to be added to the menu item container. */
cssClass?: string;
Expand All @@ -22,6 +24,12 @@ export interface MenuItem<O = MenuCallbackArgs> {
/** position order in the list, a lower number will make it on top of the list. Internal commands starts at 50. */
positionOrder?: number;

/** Optional sub-menu title that will shows up when sub-menu commmands/options list is opened */
subMenuTitle?: string;

/** Optional sub-menu title CSS class to use with `subMenuTitle` */
subMenuTitleCssClass?: string;

/** CSS class to be added to the menu item text. */
textCssClass?: string;

Expand Down
3 changes: 3 additions & 0 deletions src/models/menuOptionItem.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export interface MenuOptionItem extends MenuItem {
/** An option returned by the onOptionSelected (or action) event callback handler. */
option: any;

/** Array of Option Items (title, command, disabled, ...) */
optionItems?: Array<MenuOptionItem | 'divider'>;

// --
// action/override callbacks

Expand Down
Loading

0 comments on commit 0309ec4

Please sign in to comment.