Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add sub-menu(s) to CellMenu & ContextMenu plugins #867

Merged
merged 13 commits into from
Oct 20, 2023
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
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