first commit

This commit is contained in:
Stefan Hacker
2026-04-03 09:38:48 +02:00
commit 37ad745546
47450 changed files with 3120798 additions and 0 deletions
@@ -0,0 +1,12 @@
import * as React from 'react';
import { ContextualMenuItemWrapper } from './ContextualMenuItemWrapper';
import type { JSXElement } from '@fluentui/utilities';
export declare class ContextualMenuAnchor extends ContextualMenuItemWrapper {
private _anchor;
private _ariaDescriptionId;
private _getMemoizedMenuButtonKeytipProps;
render(): JSXElement;
protected _getSubmenuTarget: () => HTMLElement | undefined;
protected _onItemClick: (ev: React.MouseEvent<HTMLElement>) => void;
protected _renderAriaDescription: (ariaDescription?: string, className?: string) => JSXElement | null;
}
@@ -0,0 +1,70 @@
define(["require", "exports", "tslib", "react", "../../../Utilities", "./ContextualMenuItemWrapper", "../../../KeytipData", "../../../utilities/contextualMenu/index", "../ContextualMenuItem"], function (require, exports, tslib_1, React, Utilities_1, ContextualMenuItemWrapper_1, KeytipData_1, index_1, ContextualMenuItem_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContextualMenuAnchor = void 0;
var ContextualMenuAnchor = /** @class */ (function (_super) {
tslib_1.__extends(ContextualMenuAnchor, _super);
function ContextualMenuAnchor() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this._anchor = React.createRef();
_this._getMemoizedMenuButtonKeytipProps = (0, Utilities_1.memoizeFunction)(function (keytipProps) {
return tslib_1.__assign(tslib_1.__assign({}, keytipProps), { hasMenu: true });
});
_this._getSubmenuTarget = function () {
return _this._anchor.current ? _this._anchor.current : undefined;
};
_this._onItemClick = function (ev) {
var _a = _this.props, item = _a.item, onItemClick = _a.onItemClick;
if (onItemClick) {
onItemClick(item, ev);
}
};
_this._renderAriaDescription = function (ariaDescription, className) {
// If ariaDescription is given, descriptionId will be assigned to ariaDescriptionSpan
return ariaDescription ? (React.createElement("span", { id: _this._ariaDescriptionId, className: className }, ariaDescription)) : null;
};
return _this;
}
ContextualMenuAnchor.prototype.render = function () {
var _this = this;
var _a = this.props, item = _a.item, classNames = _a.classNames, index = _a.index, focusableElementIndex = _a.focusableElementIndex, totalItemCount = _a.totalItemCount, hasCheckmarks = _a.hasCheckmarks, hasIcons = _a.hasIcons, expandedMenuItemKey = _a.expandedMenuItemKey, onItemClick = _a.onItemClick, openSubMenu = _a.openSubMenu, dismissSubMenu = _a.dismissSubMenu, dismissMenu = _a.dismissMenu;
var ChildrenRenderer = ContextualMenuItem_1.ContextualMenuItem;
if (this.props.item.contextualMenuItemAs) {
ChildrenRenderer = (0, Utilities_1.composeComponentAs)(this.props.item.contextualMenuItemAs, ChildrenRenderer);
}
if (this.props.contextualMenuItemAs) {
ChildrenRenderer = (0, Utilities_1.composeComponentAs)(this.props.contextualMenuItemAs, ChildrenRenderer);
}
var anchorRel = item.rel;
if (item.target && item.target.toLowerCase() === '_blank') {
anchorRel = anchorRel ? anchorRel : 'nofollow noopener noreferrer'; // Safe default to prevent tabjacking
}
var itemHasSubmenu = (0, index_1.hasSubmenu)(item);
var nativeProps = (0, Utilities_1.getNativeProps)(item, Utilities_1.anchorProperties);
var disabled = (0, index_1.isItemDisabled)(item);
var itemProps = item.itemProps, ariaDescription = item.ariaDescription;
var keytipProps = item.keytipProps;
if (keytipProps && itemHasSubmenu) {
keytipProps = this._getMemoizedMenuButtonKeytipProps(keytipProps);
}
// Check for ariaDescription to set the _ariaDescriptionId and render a hidden span with
// the description in it to be added to ariaDescribedBy
if (ariaDescription) {
this._ariaDescriptionId = (0, Utilities_1.getId)();
}
var ariaDescribedByIds = (0, Utilities_1.mergeAriaAttributeValues)(item.ariaDescribedBy, ariaDescription ? this._ariaDescriptionId : undefined, nativeProps['aria-describedby']);
var additionalItemProperties = {
'aria-describedby': ariaDescribedByIds,
};
return (React.createElement("div", null,
React.createElement(KeytipData_1.KeytipData, { keytipProps: item.keytipProps, ariaDescribedBy: ariaDescribedByIds, disabled: disabled }, function (keytipAttributes) { return (React.createElement("a", tslib_1.__assign({}, additionalItemProperties, nativeProps, keytipAttributes, { ref: _this._anchor, href: item.href, target: item.target, rel: anchorRel, className: classNames.root, role: "menuitem", "aria-haspopup": itemHasSubmenu || undefined, "aria-expanded": itemHasSubmenu ? item.key === expandedMenuItemKey : undefined, "aria-posinset": focusableElementIndex + 1, "aria-setsize": totalItemCount, "aria-disabled": (0, index_1.isItemDisabled)(item),
// eslint-disable-next-line @typescript-eslint/no-deprecated
style: item.style, onClick: _this._onItemClick, onMouseEnter: _this._onItemMouseEnter, onMouseLeave: _this._onItemMouseLeave, onMouseMove: _this._onItemMouseMove, onKeyDown: itemHasSubmenu ? _this._onItemKeyDown : undefined }),
React.createElement(ChildrenRenderer, tslib_1.__assign({ componentRef: item.componentRef, item: item, classNames: classNames, index: index, onCheckmarkClick: hasCheckmarks && onItemClick ? onItemClick : undefined, hasIcons: hasIcons, openSubMenu: openSubMenu, dismissSubMenu: dismissSubMenu, dismissMenu: dismissMenu, getSubmenuTarget: _this._getSubmenuTarget }, itemProps)),
_this._renderAriaDescription(ariaDescription, classNames.screenReaderText))); })));
};
return ContextualMenuAnchor;
}(ContextualMenuItemWrapper_1.ContextualMenuItemWrapper));
exports.ContextualMenuAnchor = ContextualMenuAnchor;
});
//# sourceMappingURL=ContextualMenuAnchor.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,10 @@
import { ContextualMenuItemWrapper } from './ContextualMenuItemWrapper';
import type { JSXElement } from '@fluentui/utilities';
export declare class ContextualMenuButton extends ContextualMenuItemWrapper {
private _btn;
private _ariaDescriptionId;
private _getMemoizedMenuButtonKeytipProps;
render(): JSXElement;
protected _renderAriaDescription: (ariaDescription?: string, className?: string) => JSXElement | null;
protected _getSubmenuTarget: () => HTMLElement | undefined;
}
@@ -0,0 +1,84 @@
define(["require", "exports", "tslib", "react", "../../../Utilities", "./ContextualMenuItemWrapper", "../../../KeytipData", "../../../utilities/contextualMenu/index", "../ContextualMenuItem"], function (require, exports, tslib_1, React, Utilities_1, ContextualMenuItemWrapper_1, KeytipData_1, index_1, ContextualMenuItem_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContextualMenuButton = void 0;
var ContextualMenuButton = /** @class */ (function (_super) {
tslib_1.__extends(ContextualMenuButton, _super);
function ContextualMenuButton() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this._btn = React.createRef();
_this._getMemoizedMenuButtonKeytipProps = (0, Utilities_1.memoizeFunction)(function (keytipProps) {
return tslib_1.__assign(tslib_1.__assign({}, keytipProps), { hasMenu: true });
});
_this._renderAriaDescription = function (ariaDescription, className) {
// If ariaDescription is given, descriptionId will be assigned to ariaDescriptionSpan
return ariaDescription ? (React.createElement("span", { id: _this._ariaDescriptionId, className: className }, ariaDescription)) : null;
};
_this._getSubmenuTarget = function () {
return _this._btn.current ? _this._btn.current : undefined;
};
return _this;
}
ContextualMenuButton.prototype.render = function () {
var _this = this;
var _a = this.props, item = _a.item, classNames = _a.classNames, index = _a.index, focusableElementIndex = _a.focusableElementIndex, totalItemCount = _a.totalItemCount, hasCheckmarks = _a.hasCheckmarks, hasIcons = _a.hasIcons, contextualMenuItemAs = _a.contextualMenuItemAs, expandedMenuItemKey = _a.expandedMenuItemKey, onItemMouseDown = _a.onItemMouseDown, onItemClick = _a.onItemClick, openSubMenu = _a.openSubMenu, dismissSubMenu = _a.dismissSubMenu, dismissMenu = _a.dismissMenu;
var ChildrenRenderer = ContextualMenuItem_1.ContextualMenuItem;
if (item.contextualMenuItemAs) {
ChildrenRenderer = (0, Utilities_1.composeComponentAs)(item.contextualMenuItemAs, ChildrenRenderer);
}
if (contextualMenuItemAs) {
ChildrenRenderer = (0, Utilities_1.composeComponentAs)(contextualMenuItemAs, ChildrenRenderer);
}
var isChecked = (0, index_1.getIsChecked)(item);
var canCheck = isChecked !== null;
var defaultRole = (0, index_1.getMenuItemAriaRole)(item);
var itemHasSubmenu = (0, index_1.hasSubmenu)(item);
var itemProps = item.itemProps, ariaLabel = item.ariaLabel, ariaDescription = item.ariaDescription;
var buttonNativeProperties = (0, Utilities_1.getNativeProps)(item, Utilities_1.buttonProperties);
// Do not add the disabled attribute to the button so that it is focusable
delete buttonNativeProperties.disabled;
var itemRole = item.role || defaultRole;
// Check for ariaDescription to set the _ariaDescriptionId and render a hidden span with
// the description in it to be added to ariaDescribedBy
if (ariaDescription) {
this._ariaDescriptionId = (0, Utilities_1.getId)();
}
var ariaDescribedByIds = (0, Utilities_1.mergeAriaAttributeValues)(item.ariaDescribedBy, ariaDescription ? this._ariaDescriptionId : undefined, buttonNativeProperties['aria-describedby']);
var itemButtonProperties = {
className: classNames.root,
onClick: this._onItemClick,
onKeyDown: itemHasSubmenu ? this._onItemKeyDown : undefined,
onMouseEnter: this._onItemMouseEnter,
onMouseLeave: this._onItemMouseLeave,
onMouseDown: function (ev) {
return onItemMouseDown ? onItemMouseDown(item, ev) : undefined;
},
onMouseMove: this._onItemMouseMove,
href: item.href,
title: item.title,
'aria-label': ariaLabel,
'aria-describedby': ariaDescribedByIds,
'aria-haspopup': itemHasSubmenu || undefined,
'aria-expanded': itemHasSubmenu ? item.key === expandedMenuItemKey : undefined,
'aria-posinset': focusableElementIndex + 1,
'aria-setsize': totalItemCount,
'aria-disabled': (0, index_1.isItemDisabled)(item),
'aria-checked': (itemRole === 'menuitemcheckbox' || itemRole === 'menuitemradio') && canCheck ? !!isChecked : undefined,
'aria-selected': itemRole === 'menuitem' && canCheck ? !!isChecked : undefined,
role: itemRole,
// eslint-disable-next-line @typescript-eslint/no-deprecated
style: item.style,
};
var keytipProps = item.keytipProps;
if (keytipProps && itemHasSubmenu) {
keytipProps = this._getMemoizedMenuButtonKeytipProps(keytipProps);
}
return (React.createElement(KeytipData_1.KeytipData, { keytipProps: keytipProps, ariaDescribedBy: ariaDescribedByIds, disabled: (0, index_1.isItemDisabled)(item) }, function (keytipAttributes) { return (React.createElement("button", tslib_1.__assign({ ref: _this._btn }, buttonNativeProperties, itemButtonProperties, keytipAttributes),
React.createElement(ChildrenRenderer, tslib_1.__assign({ componentRef: item.componentRef, item: item, classNames: classNames, index: index, onCheckmarkClick: hasCheckmarks && onItemClick ? onItemClick : undefined, hasIcons: hasIcons, openSubMenu: openSubMenu, dismissSubMenu: dismissSubMenu, dismissMenu: dismissMenu, getSubmenuTarget: _this._getSubmenuTarget }, itemProps)),
_this._renderAriaDescription(ariaDescription, classNames.screenReaderText))); }));
};
return ContextualMenuButton;
}(ContextualMenuItemWrapper_1.ContextualMenuItemWrapper));
exports.ContextualMenuButton = ContextualMenuButton;
});
//# sourceMappingURL=ContextualMenuButton.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,12 @@
import * as React from 'react';
import type { IContextualMenuItemWrapperProps } from './ContextualMenuItemWrapper.types';
export declare class ContextualMenuItemWrapper extends React.Component<IContextualMenuItemWrapperProps> {
constructor(props: IContextualMenuItemWrapperProps);
shouldComponentUpdate(newProps: IContextualMenuItemWrapperProps): boolean;
protected _onItemMouseEnter: (ev: React.MouseEvent<HTMLElement>) => void;
protected _onItemClick: (ev: React.MouseEvent<HTMLElement>) => void;
protected _onItemMouseLeave: (ev: React.MouseEvent<HTMLElement>) => void;
protected _onItemKeyDown: (ev: React.KeyboardEvent<HTMLElement>) => void;
protected _onItemMouseMove: (ev: React.MouseEvent<HTMLElement>) => void;
protected _getSubmenuTarget: () => HTMLElement | undefined;
}
@@ -0,0 +1,52 @@
define(["require", "exports", "tslib", "react", "../../../Utilities"], function (require, exports, tslib_1, React, Utilities_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContextualMenuItemWrapper = void 0;
var ContextualMenuItemWrapper = /** @class */ (function (_super) {
tslib_1.__extends(ContextualMenuItemWrapper, _super);
function ContextualMenuItemWrapper(props) {
var _this = _super.call(this, props) || this;
_this._onItemMouseEnter = function (ev) {
var _a = _this.props, item = _a.item, onItemMouseEnter = _a.onItemMouseEnter;
if (onItemMouseEnter) {
onItemMouseEnter(item, ev, ev.currentTarget);
}
};
_this._onItemClick = function (ev) {
var _a = _this.props, item = _a.item, onItemClickBase = _a.onItemClickBase;
if (onItemClickBase) {
onItemClickBase(item, ev, ev.currentTarget);
}
};
_this._onItemMouseLeave = function (ev) {
var _a = _this.props, item = _a.item, onItemMouseLeave = _a.onItemMouseLeave;
if (onItemMouseLeave) {
onItemMouseLeave(item, ev);
}
};
_this._onItemKeyDown = function (ev) {
var _a = _this.props, item = _a.item, onItemKeyDown = _a.onItemKeyDown;
if (onItemKeyDown) {
onItemKeyDown(item, ev);
}
};
_this._onItemMouseMove = function (ev) {
var _a = _this.props, item = _a.item, onItemMouseMove = _a.onItemMouseMove;
if (onItemMouseMove) {
onItemMouseMove(item, ev, ev.currentTarget);
}
};
_this._getSubmenuTarget = function () {
return undefined;
};
(0, Utilities_1.initializeComponentRef)(_this);
return _this;
}
ContextualMenuItemWrapper.prototype.shouldComponentUpdate = function (newProps) {
return !(0, Utilities_1.shallowCompare)(newProps, this.props);
};
return ContextualMenuItemWrapper;
}(React.Component));
exports.ContextualMenuItemWrapper = ContextualMenuItemWrapper;
});
//# sourceMappingURL=ContextualMenuItemWrapper.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ContextualMenuItemWrapper.js","sourceRoot":"../src/","sources":["components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuItemWrapper.tsx"],"names":[],"mappings":";;;;IAIA;QAA+C,qDAAgD;QAC7F,mCAAY,KAAsC;YAChD,YAAA,MAAK,YAAC,KAAK,CAAC,SAAC;YAQL,uBAAiB,GAAG,UAAC,EAAiC;gBACxD,IAAA,KAA6B,KAAI,CAAC,KAAK,EAArC,IAAI,UAAA,EAAE,gBAAgB,sBAAe,CAAC;gBAC9C,IAAI,gBAAgB,EAAE,CAAC;oBACrB,gBAAgB,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,aAA4B,CAAC,CAAC;gBAC9D,CAAC;YACH,CAAC,CAAC;YAEQ,kBAAY,GAAG,UAAC,EAAiC;gBACnD,IAAA,KAA4B,KAAI,CAAC,KAAK,EAApC,IAAI,UAAA,EAAE,eAAe,qBAAe,CAAC;gBAC7C,IAAI,eAAe,EAAE,CAAC;oBACpB,eAAe,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,aAA4B,CAAC,CAAC;gBAC7D,CAAC;YACH,CAAC,CAAC;YAEQ,uBAAiB,GAAG,UAAC,EAAiC;gBACxD,IAAA,KAA6B,KAAI,CAAC,KAAK,EAArC,IAAI,UAAA,EAAE,gBAAgB,sBAAe,CAAC;gBAC9C,IAAI,gBAAgB,EAAE,CAAC;oBACrB,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC7B,CAAC;YACH,CAAC,CAAC;YAEQ,oBAAc,GAAG,UAAC,EAAoC;gBACxD,IAAA,KAA0B,KAAI,CAAC,KAAK,EAAlC,IAAI,UAAA,EAAE,aAAa,mBAAe,CAAC;gBAC3C,IAAI,aAAa,EAAE,CAAC;oBAClB,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC,CAAC;YAEQ,sBAAgB,GAAG,UAAC,EAAiC;gBACvD,IAAA,KAA4B,KAAI,CAAC,KAAK,EAApC,IAAI,UAAA,EAAE,eAAe,qBAAe,CAAC;gBAC7C,IAAI,eAAe,EAAE,CAAC;oBACpB,eAAe,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,aAA4B,CAAC,CAAC;gBAC7D,CAAC;YACH,CAAC,CAAC;YAEQ,uBAAiB,GAAG;gBAC5B,OAAO,SAAS,CAAC;YACnB,CAAC,CAAC;YA5CA,IAAA,kCAAsB,EAAC,KAAI,CAAC,CAAC;;QAC/B,CAAC;QAEM,yDAAqB,GAA5B,UAA6B,QAAyC;YACpE,OAAO,CAAC,IAAA,0BAAc,EAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/C,CAAC;QAwCH,gCAAC;IAAD,CAAC,AAhDD,CAA+C,KAAK,CAAC,SAAS,GAgD7D;IAhDY,8DAAyB","sourcesContent":["import * as React from 'react';\nimport { initializeComponentRef, shallowCompare } from '../../../Utilities';\nimport type { IContextualMenuItemWrapperProps } from './ContextualMenuItemWrapper.types';\n\nexport class ContextualMenuItemWrapper extends React.Component<IContextualMenuItemWrapperProps> {\n constructor(props: IContextualMenuItemWrapperProps) {\n super(props);\n initializeComponentRef(this);\n }\n\n public shouldComponentUpdate(newProps: IContextualMenuItemWrapperProps): boolean {\n return !shallowCompare(newProps, this.props);\n }\n\n protected _onItemMouseEnter = (ev: React.MouseEvent<HTMLElement>): void => {\n const { item, onItemMouseEnter } = this.props;\n if (onItemMouseEnter) {\n onItemMouseEnter(item, ev, ev.currentTarget as HTMLElement);\n }\n };\n\n protected _onItemClick = (ev: React.MouseEvent<HTMLElement>): void => {\n const { item, onItemClickBase } = this.props;\n if (onItemClickBase) {\n onItemClickBase(item, ev, ev.currentTarget as HTMLElement);\n }\n };\n\n protected _onItemMouseLeave = (ev: React.MouseEvent<HTMLElement>): void => {\n const { item, onItemMouseLeave } = this.props;\n if (onItemMouseLeave) {\n onItemMouseLeave(item, ev);\n }\n };\n\n protected _onItemKeyDown = (ev: React.KeyboardEvent<HTMLElement>): void => {\n const { item, onItemKeyDown } = this.props;\n if (onItemKeyDown) {\n onItemKeyDown(item, ev);\n }\n };\n\n protected _onItemMouseMove = (ev: React.MouseEvent<HTMLElement>): void => {\n const { item, onItemMouseMove } = this.props;\n if (onItemMouseMove) {\n onItemMouseMove(item, ev, ev.currentTarget as HTMLElement);\n }\n };\n\n protected _getSubmenuTarget = (): HTMLElement | undefined => {\n return undefined;\n };\n}\n"]}
@@ -0,0 +1,104 @@
import * as React from 'react';
import { ContextualMenuItemWrapper } from './ContextualMenuItemWrapper';
import type { IContextualMenuItem, IContextualMenuItemProps } from '../../../ContextualMenu';
import type { IMenuItemClassNames } from '../ContextualMenu.classNames';
import type { IComponentAs, IRefObject } from '../../../Utilities';
export interface IContextualMenuItemWrapperProps extends React.ClassAttributes<IContextualMenuItem> {
/**
* Optional callback to access the ContextualMenuSplitButton interface. Use this instead of ref for accessing
* the public methods and properties of the component.
*/
componentRef?: IRefObject<ContextualMenuItemWrapper>;
/**
* The IContextualMenuItem that is used to render the item in the menu.
*/
item: IContextualMenuItem;
/**
* CSS class to apply to the context menu.
*/
classNames: IMenuItemClassNames;
/**
* The index number of the wrapper among all items in the contextual menu including things like dividers and headers.
*/
index: number;
/**
* The index number of the wrapper among all items in the contextual menu excluding dividers and headers.
*/
focusableElementIndex: number;
/**
* The total number of items in the contextual menu.
*/
totalItemCount: number;
/**
* Whether or not if the item for the wrapper uses checkmarks.
*/
hasCheckmarks?: boolean;
/**
* Whether or not the item for the wrapper uses icons.
*/
hasIcons?: boolean;
/**
* Method to override the render of the individual menu items.
* @defaultvalue ContextualMenuItem
*/
contextualMenuItemAs?: IComponentAs<IContextualMenuItemProps>;
/**
* Callback for when the user's mouse enters the wrapper.
*/
onItemMouseEnter?: (item: IContextualMenuItem, ev: React.MouseEvent<HTMLElement>, target: HTMLElement) => boolean | void;
/**
* Callback for when the user's mouse leaves the wrapper.
*/
onItemMouseLeave?: (item: IContextualMenuItem, ev: React.MouseEvent<HTMLElement>) => void;
/**
* Callback for when the user's mouse moves in the wrapper.
*/
onItemMouseMove?: (item: IContextualMenuItem, ev: React.MouseEvent<HTMLElement>, target: HTMLElement) => void;
/**
* Callback for the mousedown event on the icon button in the wrapper.
*/
onItemMouseDown?: (item: IContextualMenuItem, ev: React.MouseEvent<HTMLElement>) => void;
/**
* Callback for when the click event on the primary button.
*/
executeItemClick?: (item: IContextualMenuItem, ev: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => void;
/**
* Callback for when the click event on the icon button from the wrapper.
*/
onItemClick?: (item: IContextualMenuItem, ev: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => void;
/**
* Callback for when the click event on the icon button which also takes in a specific HTMLElement
* that will be focused.
*/
onItemClickBase?: (item: IContextualMenuItem, ev: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>, target: HTMLElement) => void;
/**
* Callback for keyboard events on the wrapper.
*/
onItemKeyDown?: (item: IContextualMenuItem, ev: React.KeyboardEvent<HTMLElement>) => void;
/**
* Callback to get the subMenu ID for an IContextualMenuItem.
* @deprecated ID relationship between a menu button and menu isn't necessary
*/
getSubMenuId?: (item: IContextualMenuItem) => string | undefined;
/**
* Key of the currently expanded subMenu.
*/
expandedMenuItemKey?: string;
/**
* Callback for touch/pointer events on the split button.
*/
onTap?: (ev: React.TouchEvent<HTMLElement> | PointerEvent) => void;
/**
* This prop will get set by ContextualMenu and can be called to open this item's subMenu, if present.
*/
openSubMenu?: (item: any, target: HTMLElement) => void;
/**
* This prop will get set by ContextualMenu and can be called to close this item's subMenu, if present.
*/
dismissSubMenu?: () => void;
/**
* This prop will get set by ContextualMenu and can be called to close the menu this item belongs to.
* If dismissAll is true, all menus will be closed.
*/
dismissMenu?: (ev?: any, dismissAll?: boolean) => void;
}
@@ -0,0 +1,5 @@
define(["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
});
//# sourceMappingURL=ContextualMenuItemWrapper.types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ContextualMenuItemWrapper.types.js","sourceRoot":"../src/","sources":["components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuItemWrapper.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { ContextualMenuItemWrapper } from './ContextualMenuItemWrapper';\nimport type { IContextualMenuItem, IContextualMenuItemProps } from '../../../ContextualMenu';\nimport type { IMenuItemClassNames } from '../ContextualMenu.classNames';\nimport type { IComponentAs, IRefObject } from '../../../Utilities';\n\nexport interface IContextualMenuItemWrapperProps extends React.ClassAttributes<IContextualMenuItem> {\n /**\n * Optional callback to access the ContextualMenuSplitButton interface. Use this instead of ref for accessing\n * the public methods and properties of the component.\n */\n componentRef?: IRefObject<ContextualMenuItemWrapper>;\n\n /**\n * The IContextualMenuItem that is used to render the item in the menu.\n */\n item: IContextualMenuItem;\n\n /**\n * CSS class to apply to the context menu.\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n classNames: IMenuItemClassNames;\n\n /**\n * The index number of the wrapper among all items in the contextual menu including things like dividers and headers.\n */\n index: number;\n\n /**\n * The index number of the wrapper among all items in the contextual menu excluding dividers and headers.\n */\n focusableElementIndex: number;\n\n /**\n * The total number of items in the contextual menu.\n */\n totalItemCount: number;\n\n /**\n * Whether or not if the item for the wrapper uses checkmarks.\n */\n hasCheckmarks?: boolean;\n\n /**\n * Whether or not the item for the wrapper uses icons.\n */\n hasIcons?: boolean;\n\n /**\n * Method to override the render of the individual menu items.\n * @defaultvalue ContextualMenuItem\n */\n contextualMenuItemAs?: IComponentAs<IContextualMenuItemProps>;\n\n /**\n * Callback for when the user's mouse enters the wrapper.\n */\n onItemMouseEnter?: (\n item: IContextualMenuItem,\n ev: React.MouseEvent<HTMLElement>,\n target: HTMLElement,\n ) => boolean | void;\n\n /**\n * Callback for when the user's mouse leaves the wrapper.\n */\n onItemMouseLeave?: (item: IContextualMenuItem, ev: React.MouseEvent<HTMLElement>) => void;\n\n /**\n * Callback for when the user's mouse moves in the wrapper.\n */\n onItemMouseMove?: (item: IContextualMenuItem, ev: React.MouseEvent<HTMLElement>, target: HTMLElement) => void;\n\n /**\n * Callback for the mousedown event on the icon button in the wrapper.\n */\n onItemMouseDown?: (item: IContextualMenuItem, ev: React.MouseEvent<HTMLElement>) => void;\n\n /**\n * Callback for when the click event on the primary button.\n */\n executeItemClick?: (\n item: IContextualMenuItem,\n ev: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>,\n ) => void;\n\n /**\n * Callback for when the click event on the icon button from the wrapper.\n */\n onItemClick?: (\n item: IContextualMenuItem,\n ev: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>,\n ) => void;\n\n /**\n * Callback for when the click event on the icon button which also takes in a specific HTMLElement\n * that will be focused.\n */\n onItemClickBase?: (\n item: IContextualMenuItem,\n ev: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>,\n target: HTMLElement,\n ) => void;\n\n /**\n * Callback for keyboard events on the wrapper.\n */\n onItemKeyDown?: (item: IContextualMenuItem, ev: React.KeyboardEvent<HTMLElement>) => void;\n\n /**\n * Callback to get the subMenu ID for an IContextualMenuItem.\n * @deprecated ID relationship between a menu button and menu isn't necessary\n */\n getSubMenuId?: (item: IContextualMenuItem) => string | undefined;\n\n /**\n * Key of the currently expanded subMenu.\n */\n expandedMenuItemKey?: string;\n\n /**\n * Callback for touch/pointer events on the split button.\n */\n onTap?: (ev: React.TouchEvent<HTMLElement> | PointerEvent) => void;\n\n /**\n * This prop will get set by ContextualMenu and can be called to open this item's subMenu, if present.\n */\n openSubMenu?: (item: any, target: HTMLElement) => void;\n\n /**\n * This prop will get set by ContextualMenu and can be called to close this item's subMenu, if present.\n */\n dismissSubMenu?: () => void;\n\n /**\n * This prop will get set by ContextualMenu and can be called to close the menu this item belongs to.\n * If dismissAll is true, all menus will be closed.\n */\n dismissMenu?: (ev?: any, dismissAll?: boolean) => void;\n}\n"]}
@@ -0,0 +1,35 @@
import * as React from 'react';
import { ContextualMenuItemWrapper } from './ContextualMenuItemWrapper';
import type { IContextualMenuItemWrapperProps } from './ContextualMenuItemWrapper.types';
import type { JSXElement } from '@fluentui/utilities';
export interface IContextualMenuSplitButtonState {
}
export declare class ContextualMenuSplitButton extends ContextualMenuItemWrapper {
private _splitButton;
private _lastTouchTimeoutId;
private _processingTouch;
private _ariaDescriptionId;
private _dismissLabelId;
private _async;
private _events;
private _getMemoizedMenuButtonKeytipProps;
constructor(props: IContextualMenuItemWrapperProps);
componentDidMount(): void;
componentWillUnmount(): void;
render(): JSXElement | null;
protected _onItemKeyDown: (ev: React.KeyboardEvent<HTMLElement>) => void;
protected _getSubmenuTarget: () => HTMLElement | undefined;
protected _renderAriaDescription: (ariaDescription?: string, className?: string) => JSXElement | null;
private _renderSplitPrimaryButton;
private _renderSplitDivider;
private _renderSplitIconButton;
private _onItemMouseEnterPrimary;
private _onItemMouseEnterIcon;
private _onItemMouseMovePrimary;
private _onItemMouseMoveIcon;
private _onIconItemClick;
private _executeItemClick;
private _onTouchStart;
private _onPointerDown;
private _handleTouchAndPointerEvent;
}
@@ -0,0 +1,215 @@
define(["require", "exports", "tslib", "react", "../../../Utilities", "../ContextualMenuItem", "../ContextualMenu.classNames", "../../../KeytipData", "../../../utilities/contextualMenu/index", "../../../Divider", "./ContextualMenuItemWrapper"], function (require, exports, tslib_1, React, Utilities_1, ContextualMenuItem_1, ContextualMenu_classNames_1, KeytipData_1, index_1, Divider_1, ContextualMenuItemWrapper_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContextualMenuSplitButton = void 0;
var TouchIdleDelay = 500; /* ms */
var ContextualMenuSplitButton = /** @class */ (function (_super) {
tslib_1.__extends(ContextualMenuSplitButton, _super);
function ContextualMenuSplitButton(props) {
var _this = _super.call(this, props) || this;
_this._getMemoizedMenuButtonKeytipProps = (0, Utilities_1.memoizeFunction)(function (keytipProps) {
return tslib_1.__assign(tslib_1.__assign({}, keytipProps), { hasMenu: true });
});
_this._onItemKeyDown = function (ev) {
var _a = _this.props, item = _a.item, onItemKeyDown = _a.onItemKeyDown;
// eslint-disable-next-line @typescript-eslint/no-deprecated
if (ev.which === Utilities_1.KeyCodes.enter) {
_this._executeItemClick(ev);
ev.preventDefault();
ev.stopPropagation();
}
else if (onItemKeyDown) {
onItemKeyDown(item, ev);
}
};
_this._getSubmenuTarget = function () {
return _this._splitButton;
};
_this._renderAriaDescription = function (ariaDescription, className) {
// If ariaDescription is given, descriptionId will be assigned to ariaDescriptionSpan
return ariaDescription ? (React.createElement("span", { id: _this._ariaDescriptionId, className: className }, ariaDescription)) : null;
};
_this._onItemMouseEnterPrimary = function (ev) {
var _a = _this.props, item = _a.item, onItemMouseEnter = _a.onItemMouseEnter;
if (onItemMouseEnter) {
onItemMouseEnter(tslib_1.__assign(tslib_1.__assign({}, item), { subMenuProps: undefined, items: undefined }), ev, _this._splitButton);
}
};
_this._onItemMouseEnterIcon = function (ev) {
var _a = _this.props, item = _a.item, onItemMouseEnter = _a.onItemMouseEnter;
if (onItemMouseEnter) {
onItemMouseEnter(item, ev, _this._splitButton);
}
};
_this._onItemMouseMovePrimary = function (ev) {
var _a = _this.props, item = _a.item, onItemMouseMove = _a.onItemMouseMove;
if (onItemMouseMove) {
onItemMouseMove(tslib_1.__assign(tslib_1.__assign({}, item), { subMenuProps: undefined, items: undefined }), ev, _this._splitButton);
}
};
_this._onItemMouseMoveIcon = function (ev) {
var _a = _this.props, item = _a.item, onItemMouseMove = _a.onItemMouseMove;
if (onItemMouseMove) {
onItemMouseMove(item, ev, _this._splitButton);
}
};
_this._onIconItemClick = function (ev) {
var _a = _this.props, item = _a.item, onItemClickBase = _a.onItemClickBase;
if (onItemClickBase) {
onItemClickBase(item, ev, (_this._splitButton ? _this._splitButton : ev.currentTarget));
}
};
_this._executeItemClick = function (ev) {
var _a = _this.props, item = _a.item, executeItemClick = _a.executeItemClick, onItemClick = _a.onItemClick;
if (item.disabled || item.isDisabled) {
return;
}
if (_this._processingTouch && !item.canCheck && onItemClick) {
return onItemClick(item, ev);
}
if (executeItemClick) {
executeItemClick(item, ev);
}
};
_this._onTouchStart = function (ev) {
if (_this._splitButton && !('onpointerdown' in _this._splitButton)) {
_this._handleTouchAndPointerEvent(ev);
}
};
_this._onPointerDown = function (ev) {
if (ev.pointerType === 'touch') {
_this._handleTouchAndPointerEvent(ev);
ev.preventDefault();
ev.stopImmediatePropagation();
}
};
_this._async = new Utilities_1.Async(_this);
_this._events = new Utilities_1.EventGroup(_this);
_this._dismissLabelId = (0, Utilities_1.getId)();
return _this;
}
ContextualMenuSplitButton.prototype.componentDidMount = function () {
if (this._splitButton && 'onpointerdown' in this._splitButton) {
this._events.on(this._splitButton, 'pointerdown', this._onPointerDown, true);
}
};
ContextualMenuSplitButton.prototype.componentWillUnmount = function () {
this._async.dispose();
this._events.dispose();
};
ContextualMenuSplitButton.prototype.render = function () {
var _this = this;
var _a;
var _b = this.props, item = _b.item, classNames = _b.classNames, index = _b.index, focusableElementIndex = _b.focusableElementIndex, totalItemCount = _b.totalItemCount, hasCheckmarks = _b.hasCheckmarks, hasIcons = _b.hasIcons, onItemMouseLeave = _b.onItemMouseLeave, expandedMenuItemKey = _b.expandedMenuItemKey;
var itemHasSubmenu = (0, index_1.hasSubmenu)(item);
var keytipProps = item.keytipProps;
if (keytipProps) {
keytipProps = this._getMemoizedMenuButtonKeytipProps(keytipProps);
}
// Check for ariaDescription to set the _ariaDescriptionId and render a hidden span with
// the description in it to be added to ariaDescribedBy
var ariaDescription = item.ariaDescription;
if (ariaDescription) {
this._ariaDescriptionId = (0, Utilities_1.getId)();
}
var ariaChecked = (_a = (0, index_1.getIsChecked)(item)) !== null && _a !== void 0 ? _a : undefined;
return (React.createElement(KeytipData_1.KeytipData, { keytipProps: keytipProps, disabled: (0, index_1.isItemDisabled)(item) }, function (keytipAttributes) { return (React.createElement("div", { "data-ktp-target": keytipAttributes['data-ktp-target'], ref: function (splitButton) {
_this._splitButton = splitButton;
}, role: (0, index_1.getMenuItemAriaRole)(item), "aria-label": item.ariaLabel, className: classNames.splitContainer, "aria-disabled": (0, index_1.isItemDisabled)(item), "aria-expanded": itemHasSubmenu ? item.key === expandedMenuItemKey : undefined, "aria-haspopup": true, "aria-describedby": (0, Utilities_1.mergeAriaAttributeValues)(item.ariaDescribedBy, ariaDescription ? _this._ariaDescriptionId : undefined, keytipAttributes['aria-describedby']), "aria-checked": ariaChecked, "aria-posinset": focusableElementIndex + 1, "aria-setsize": totalItemCount, onMouseEnter: _this._onItemMouseEnterPrimary, onMouseLeave: onItemMouseLeave ? onItemMouseLeave.bind(_this, tslib_1.__assign(tslib_1.__assign({}, item), { subMenuProps: null, items: null })) : undefined, onMouseMove: _this._onItemMouseMovePrimary, onKeyDown: _this._onItemKeyDown, onClick: _this._executeItemClick, onTouchStart: _this._onTouchStart, tabIndex: 0, "data-is-focusable": true, "aria-roledescription": item['aria-roledescription'] },
_this._renderSplitPrimaryButton(item, classNames, index, hasCheckmarks, hasIcons),
_this._renderSplitDivider(item),
_this._renderSplitIconButton(item, classNames, index, keytipAttributes),
_this._renderAriaDescription(ariaDescription, classNames.screenReaderText))); }));
};
ContextualMenuSplitButton.prototype._renderSplitPrimaryButton = function (item,
// eslint-disable-next-line @typescript-eslint/no-deprecated
classNames, index, hasCheckmarks, hasIcons) {
var _a = this.props, _b = _a.contextualMenuItemAs, ChildrenRenderer = _b === void 0 ? ContextualMenuItem_1.ContextualMenuItem : _b, onItemClick = _a.onItemClick;
var itemProps = {
key: item.key,
disabled: (0, index_1.isItemDisabled)(item) || item.primaryDisabled,
/* eslint-disable @typescript-eslint/no-deprecated */
name: item.name,
text: item.text || item.name,
secondaryText: item.secondaryText,
/* eslint-enable @typescript-eslint/no-deprecated */
className: classNames.splitPrimary,
canCheck: item.canCheck,
isChecked: item.isChecked,
checked: item.checked,
iconProps: item.iconProps,
id: this._dismissLabelId,
onRenderIcon: item.onRenderIcon,
data: item.data,
'data-is-focusable': false,
};
var itemComponentProps = item.itemProps;
return (React.createElement("button", tslib_1.__assign({}, (0, Utilities_1.getNativeProps)(itemProps, Utilities_1.buttonProperties)),
React.createElement(ChildrenRenderer, tslib_1.__assign({ "data-is-focusable": false, item: tslib_1.__assign(tslib_1.__assign({}, itemProps), { onClick: item.onClick }), classNames: classNames, index: index, onCheckmarkClick: hasCheckmarks && onItemClick ? onItemClick : undefined, hasIcons: hasIcons }, itemComponentProps))));
};
ContextualMenuSplitButton.prototype._renderSplitDivider = function (item) {
var getDividerClassNames = item.getSplitButtonVerticalDividerClassNames || ContextualMenu_classNames_1.getSplitButtonVerticalDividerClassNames;
return (React.createElement(Divider_1.VerticalDivider
// eslint-disable-next-line @typescript-eslint/no-deprecated
, {
// eslint-disable-next-line @typescript-eslint/no-deprecated
getClassNames: getDividerClassNames }));
};
ContextualMenuSplitButton.prototype._renderSplitIconButton = function (item, classNames, // eslint-disable-line @typescript-eslint/no-deprecated
index, keytipAttributes) {
var _a = this.props, onItemMouseLeave = _a.onItemMouseLeave, onItemMouseDown = _a.onItemMouseDown, openSubMenu = _a.openSubMenu, dismissSubMenu = _a.dismissSubMenu, dismissMenu = _a.dismissMenu;
var ChildrenRenderer = ContextualMenuItem_1.ContextualMenuItem;
if (this.props.item.contextualMenuItemAs) {
ChildrenRenderer = (0, Utilities_1.composeComponentAs)(this.props.item.contextualMenuItemAs, ChildrenRenderer);
}
if (this.props.contextualMenuItemAs) {
ChildrenRenderer = (0, Utilities_1.composeComponentAs)(this.props.contextualMenuItemAs, ChildrenRenderer);
}
var itemProps = {
onClick: this._onIconItemClick,
disabled: (0, index_1.isItemDisabled)(item),
className: classNames.splitMenu,
subMenuProps: item.subMenuProps,
submenuIconProps: item.submenuIconProps,
split: true,
key: item.key,
'aria-labelledby': this._dismissLabelId,
};
var buttonProps = tslib_1.__assign(tslib_1.__assign({}, (0, Utilities_1.getNativeProps)(itemProps, Utilities_1.buttonProperties)), {
onMouseEnter: this._onItemMouseEnterIcon,
onMouseLeave: onItemMouseLeave ? onItemMouseLeave.bind(this, item) : undefined,
onMouseDown: function (ev) {
return onItemMouseDown ? onItemMouseDown(item, ev) : undefined;
},
onMouseMove: this._onItemMouseMoveIcon,
'data-is-focusable': false,
'data-ktp-execute-target': keytipAttributes['data-ktp-execute-target'],
'aria-haspopup': true,
});
var itemComponentProps = item.itemProps;
return (React.createElement("button", tslib_1.__assign({}, buttonProps),
React.createElement(ChildrenRenderer, tslib_1.__assign({ componentRef: item.componentRef, item: itemProps, classNames: classNames, index: index, hasIcons: false, openSubMenu: openSubMenu, dismissSubMenu: dismissSubMenu, dismissMenu: dismissMenu, getSubmenuTarget: this._getSubmenuTarget }, itemComponentProps))));
};
ContextualMenuSplitButton.prototype._handleTouchAndPointerEvent = function (ev) {
var _this = this;
var onTap = this.props.onTap;
if (onTap) {
onTap(ev);
}
// If we already have an existing timeout from a previous touch/pointer event
// cancel that timeout so we can set a new one.
if (this._lastTouchTimeoutId) {
this._async.clearTimeout(this._lastTouchTimeoutId);
this._lastTouchTimeoutId = undefined;
}
this._processingTouch = true;
this._lastTouchTimeoutId = this._async.setTimeout(function () {
_this._processingTouch = false;
_this._lastTouchTimeoutId = undefined;
}, TouchIdleDelay);
};
return ContextualMenuSplitButton;
}(ContextualMenuItemWrapper_1.ContextualMenuItemWrapper));
exports.ContextualMenuSplitButton = ContextualMenuSplitButton;
});
//# sourceMappingURL=ContextualMenuSplitButton.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,5 @@
export * from './ContextualMenuAnchor';
export * from './ContextualMenuButton';
export * from './ContextualMenuSplitButton';
export * from './ContextualMenuItemWrapper';
export * from './ContextualMenuItemWrapper.types';
@@ -0,0 +1,10 @@
define(["require", "exports", "tslib", "./ContextualMenuAnchor", "./ContextualMenuButton", "./ContextualMenuSplitButton", "./ContextualMenuItemWrapper", "./ContextualMenuItemWrapper.types"], function (require, exports, tslib_1, ContextualMenuAnchor_1, ContextualMenuButton_1, ContextualMenuSplitButton_1, ContextualMenuItemWrapper_1, ContextualMenuItemWrapper_types_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
tslib_1.__exportStar(ContextualMenuAnchor_1, exports);
tslib_1.__exportStar(ContextualMenuButton_1, exports);
tslib_1.__exportStar(ContextualMenuSplitButton_1, exports);
tslib_1.__exportStar(ContextualMenuItemWrapper_1, exports);
tslib_1.__exportStar(ContextualMenuItemWrapper_types_1, exports);
});
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["components/ContextualMenu/ContextualMenuItemWrapper/index.ts"],"names":[],"mappings":";;;IAAA,sDAAuC;IACvC,sDAAuC;IACvC,2DAA4C;IAC5C,2DAA4C;IAC5C,iEAAkD","sourcesContent":["export * from './ContextualMenuAnchor';\nexport * from './ContextualMenuButton';\nexport * from './ContextualMenuSplitButton';\nexport * from './ContextualMenuItemWrapper';\nexport * from './ContextualMenuItemWrapper.types';\n"]}