Skip to content

Commit 91e24e9

Browse files
committed
Sync with Kendo UI Professional
1 parent ddd3712 commit 91e24e9

File tree

4 files changed

+198
-10
lines changed

4 files changed

+198
-10
lines changed

Diff for: docs/api/javascript/ui/menu.md

+100-2
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,15 @@ Refer to the example below for a list of the supported properties.
305305

306306
// handle event
307307
}
308+
},
309+
{
310+
text: "Item 6",
311+
icon: "gear"
312+
},
313+
{
314+
text: "Item 7",
315+
icon: "pencil",
316+
iconClass: "custom-icon-class"
308317
}]
309318
})
310319
});
@@ -427,15 +436,60 @@ Sets the field of the data item that provides the image url of the menu items.
427436
$("#menu").kendoMenu({
428437
dataSource: {
429438
data: [{
430-
Name: "Item 1",
439+
Name: "Item 1",
431440
imgUrl: "https://demos.telerik.com/kendo-ui/content/shared/icons/sports/golf.png"
432441
}]
433442
},
434-
dataTextField:"Name",
443+
dataTextField:"Name",
435444
dataImageUrlField:"imgUrl"
436445
});
437446
</script>
438447

448+
### dataIconField `String`
449+
450+
Sets the field of the data item that provides the icon name of the menu items.
451+
452+
#### Example
453+
454+
<ul id="menu"></ul>
455+
<script>
456+
$("#menu").kendoMenu({
457+
dataSource: {
458+
data: [{
459+
Name: "Item 1",
460+
IconName: "gear",
461+
IconClass: "custom-icon-class"
462+
}]
463+
},
464+
dataTextField:"Name",
465+
dataIconField:"IconName",
466+
dataIconClassField:"IconClass"
467+
});
468+
</script>
469+
470+
### dataIconClassField `String`
471+
472+
Sets the field of the data item that provides the icon class of the menu items.
473+
474+
475+
#### Example
476+
477+
<ul id="menu"></ul>
478+
<script>
479+
$("#menu").kendoMenu({
480+
dataSource: {
481+
data: [{
482+
Name: "Item 1",
483+
IconName: "gear",
484+
IconClass: "custom-icon-class"
485+
}]
486+
},
487+
dataTextField:"Name",
488+
dataIconField:"IconName",
489+
dataIconClassField:"IconClass"
490+
});
491+
</script>
492+
439493
### dataContentField `String`
440494

441495
Sets the field of the data item that provides the content of the menu items.
@@ -521,6 +575,25 @@ its sub menus to the left.
521575
});
522576
</script>
523577

578+
### iconPosition `String` *(default: "before")*
579+
580+
Specifies the position of the icon in the Menu items using the text content as a reference. The available options are:
581+
- `before` - the icon is positioned before the text
582+
- `after` - the icon is positioned after the text
583+
584+
#### Example
585+
586+
<ul id="menu"></ul>
587+
<script>
588+
$("#menu").kendoMenu({
589+
iconPosition: "after",
590+
dataSource: [
591+
{ text: "Item 1", icon: "gear" },
592+
{ text: "Item 2", icon: "pencil" }
593+
]
594+
});
595+
</script>
596+
524597
### openOnClick `Boolean|Object`*(default: false)*
525598

526599
Specifies that the root sub menus will be opened on item click.
@@ -719,6 +792,31 @@ Sets the scroll amount (in pixels) that the Menu scrolls when the scroll buttons
719792
});
720793
</script>
721794

795+
### scrollable.scrollButtonsPosition `string` *(default: "split")*
796+
797+
Determines where the scroll buttons appear when menu content overflows. Here's an explanation of the available options:
798+
799+
- "split" (default): Places one scroll button at the beginning and another at the end of the scrollable container
800+
- "start": Places both scroll buttons at the beginning of the scrollable container
801+
- "end": Places both scroll buttons at the end of the scrollable container
802+
803+
804+
#### Example
805+
806+
<ul id="menu" style="width:150px;">
807+
<li>Item 1</li>
808+
<li>Item 2</li>
809+
<li>Item 3</li>
810+
</ul>
811+
812+
<script>
813+
$("#menu").kendoMenu({
814+
scrollable: {
815+
scrollButtonsPosition: "start"
816+
}
817+
});
818+
</script>
819+
722820
## Methods
723821

724822
### append

Diff for: src/kendo.menu.js

+29-4
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ export const __meta__ = {
9090
text: "dataTextField",
9191
url: "dataUrlField",
9292
spriteCssClass: "dataSpriteCssClassField",
93+
icon: "dataIconField",
94+
iconClass: "dataIconClassField",
9395
imageUrl: "dataImageUrlField",
9496
imageAttr: "dataImageAttrField",
9597
content: "dataContentField"
@@ -260,7 +262,7 @@ export const __meta__ = {
260262
item
261263
.filter(".k-separator")
262264
.removeClass("k-menu-item")
263-
.addClass("k-menu-separator")
265+
.addClass("k-separator-horizontal")
264266
.empty()
265267
.append("&nbsp;");
266268

@@ -542,6 +544,7 @@ export const __meta__ = {
542544
scrollable: false,
543545
popupCollision: null,
544546
autoSize: false,
547+
iconPosition: "before", // "before" or "after" text content
545548
},
546549

547550
_initData: function() {
@@ -639,8 +642,19 @@ export const __meta__ = {
639642
backwardBtn = $(that.templates.scrollButton({ direction: backwardBtnIcon }));
640643
forwardBtn = $(that.templates.scrollButton({ direction: forwardBtnIcon }));
641644

642-
backwardBtn.prependTo(that._scrollWrapper);
643-
forwardBtn.appendTo(that._scrollWrapper);
645+
switch (options.scrollable.scrollButtonsPosition) {
646+
case "start":
647+
forwardBtn.prependTo(that._scrollWrapper);
648+
backwardBtn.prependTo(that._scrollWrapper);
649+
break;
650+
case "end":
651+
backwardBtn.appendTo(that._scrollWrapper);
652+
forwardBtn.appendTo(that._scrollWrapper);
653+
break;
654+
default:
655+
backwardBtn.prependTo(that._scrollWrapper);
656+
forwardBtn.appendTo(that._scrollWrapper);
657+
}
644658

645659
that._initScrolling(that.element, backwardBtn, forwardBtn, isHorizontal, isRtl);
646660

@@ -687,7 +701,10 @@ export const __meta__ = {
687701
_reinitOverflow: function(options) {
688702
var that = this;
689703
var overflowChanged = ((options.scrollable && !that.options.scrollable) || (!options.scrollable && that.options.scrollable)) ||
690-
(options.scrollable && that.options.scrollable && options.scrollable.distance != that.options.scrollable.distance) ||
704+
(options.scrollable && that.options.scrollable && (
705+
options.scrollable.distance != that.options.scrollable.distance ||
706+
options.scrollable.scrollButtonsPosition != that.options.scrollable.scrollButtonsPosition
707+
)) ||
691708
options.orientation != that.options.orientation;
692709

693710
if (overflowChanged) {
@@ -2306,6 +2323,8 @@ export const __meta__ = {
23062323
{ field: "url" },
23072324
{ field: "cssClass" },
23082325
{ field: "spriteCssClass" },
2326+
{ field: "icon" },
2327+
{ field: "iconClass" },
23092328
{ field: "imageUrl" },
23102329
{ field: "imageAttr" },
23112330
{ field: "attr" },
@@ -2485,15 +2504,21 @@ export const __meta__ = {
24852504
),
24862505
itemWrapper: template((data) => {
24872506
var item = data.item;
2507+
var iconPosition = this.options.iconPosition;
24882508
var url = fieldAccessor("url")(item);
24892509
var imageUrl = fieldAccessor("imageUrl")(item);
2510+
var icon = fieldAccessor("icon")(item);
2511+
var iconClass = fieldAccessor("iconClass")(item);
2512+
var iconString = (icon ? kendo.ui.icon({ icon: icon, iconClass: iconClass }) : '' );
24902513
var imgAttributes = fieldAccessor("imageAttr")(item);
24912514
var tag = url ? 'a' : 'span';
24922515

24932516
return `<${tag} class='${rendering.textClass(item)}' role='none' ${url ? `href='${kendo.sanitizeLink(url)}'` : ''} >` +
24942517
(imageUrl ? `<img ${rendering.imageCssAttributes(imgAttributes)} alt='' src='${imageUrl}' />` : '') +
2518+
(iconPosition == "before" ? iconString : '') +
24952519
this.templates.sprite(item) +
24962520
this.options.template(data) +
2521+
(iconPosition == "after" ? iconString : '') +
24972522
data.arrow(data) +
24982523
`</${tag}>`;
24992524
}),

Diff for: src/kendo.toolbar.js

-4
Original file line numberDiff line numberDiff line change
@@ -962,10 +962,6 @@ export const __meta__ = {
962962
that.overflowMenu?.append(options);
963963
menuitem = that.overflowMenu.element.find(DOT + MENU_ITEM).last();
964964

965-
if (options.icon) {
966-
menuitem.find(DOT + MENU_LINK).prepend(kendo.ui.icon(options.icon));
967-
}
968-
969965
if (component === "ToggleButton" || (component === "Button" && options.togglable === true)) {
970966
menuitem.find(DOT + MENU_LINK).addClass(MENU_LINK_TOGGLE);
971967

Diff for: tests/unit/menu/init.js

+69
Original file line numberDiff line numberDiff line change
@@ -157,5 +157,74 @@ describe("menu init", function() {
157157

158158
m.destroy();
159159
});
160+
});
161+
162+
describe("menu icons", function() {
163+
164+
let menuElement;
165+
let menu;
166+
167+
beforeEach(function() {
168+
Mocha.fixture.append('<ul id="menu"></ul>');
169+
menuElement = $("#menu");
170+
menu = menuElement.kendoMenu({
171+
iconPosition: "after",
172+
dataSource: [
173+
{ text: "Item 1", icon: "gear", iconClass: "custom-gear-icon-class" },
174+
{ text: "Item 2", icon: "pencil" }
175+
]
176+
}).data("kendoMenu");
177+
});
178+
179+
afterEach(function() {
180+
menu.destroy();
181+
menuElement.remove();
182+
});
183+
184+
it("applies icon classes if specified", function() {
185+
assert.equal(menuElement.find('.k-icon.custom-gear-icon-class').length, 1);
186+
});
187+
188+
it("places icons after text if iconPosition is 'after'", function() {
189+
assert.equal(menuElement.find(".k-menu-link > .k-menu-link-text + .k-svg-i-gear").length, 1);
190+
});
191+
});
160192

193+
describe("menu scrollable", function() {
194+
let menuElement;
195+
let menu;
196+
197+
function initMenu(options) {
198+
menu = menuElement.kendoMenu(options).data("kendoMenu");
199+
}
200+
201+
beforeEach(function() {
202+
Mocha.fixture.append(`<ul id="menu" style="width: 50px"> <li>Item 1</li>
203+
<li>Item 2</li>
204+
<li>Item 3</li></ul>`);
205+
menuElement = $("#menu");
206+
});
207+
208+
afterEach(function() {
209+
menu.destroy();
210+
menuElement.remove();
211+
});
212+
213+
it("places scroll buttons at the start when scrollButtonsPosition is 'start'", function() {
214+
initMenu({ scrollable: { scrollButtonsPosition: "start" } });
215+
assert.isOk(menu.element.prev().prev().is(".k-menu-scroll-button-prev"));
216+
assert.isOk(menu.element.prev().is(".k-menu-scroll-button-next"));
217+
});
218+
219+
it("places scroll buttons at the end when scrollButtonsPosition is 'end'", function() {
220+
initMenu({ scrollable: { scrollButtonsPosition: "end" } });
221+
assert.isOk(menu.element.next().is(".k-menu-scroll-button-prev"));
222+
assert.isOk(menu.element.next().next().is(".k-menu-scroll-button-next"));
223+
});
224+
225+
it("places scroll buttons at the end when scrollButtonsPosition is 'split'", function() {
226+
initMenu({ scrollable: { scrollButtonsPosition: "split" } });
227+
assert.isOk(menu.element.prev().is(".k-menu-scroll-button-prev"));
228+
assert.isOk(menu.element.next().is(".k-menu-scroll-button-next"));
229+
});
161230
});

0 commit comments

Comments
 (0)