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
+42
View File
@@ -0,0 +1,42 @@
import * as React from 'react';
import type { INav, INavProps } from './Nav.types';
import type { JSXElement } from '@fluentui/utilities';
export declare function isRelativeUrl(url: string): boolean;
export interface INavState {
isGroupCollapsed: {
[key: string]: boolean;
};
isLinkExpandStateChanged?: boolean;
selectedKey?: string;
}
export declare class NavBase extends React.Component<INavProps, INavState> implements INav {
static defaultProps: INavProps;
static contextType: React.Context<import("@fluentui/react-window-provider").WindowProviderProps>;
context: any;
private _focusZone;
constructor(props: INavProps);
render(): JSXElement | null;
get selectedKey(): string | undefined;
/**
* Sets focus to the first tabbable item in the zone.
* @param forceIntoFirstElement - If true, focus will be forced into the first element, even
* if focus is already in the focus zone.
* @returns True if focus could be set to an active element, false if no operation was taken.
*/
focus(forceIntoFirstElement?: boolean): boolean;
private _onRenderLink;
private _renderNavLink;
private _renderCompositeLink;
private _renderLink;
private _renderLinks;
private _renderGroup;
private _renderGroupHeader;
private _onGroupHeaderClicked;
private _onLinkExpandClicked;
private _preventBounce;
private _onNavAnchorLinkClicked;
private _onNavButtonLinkClicked;
private _isLinkSelected;
private _isGroupExpanded;
private _toggleCollapsed;
}
+305
View File
@@ -0,0 +1,305 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NavBase = void 0;
exports.isRelativeUrl = isRelativeUrl;
var tslib_1 = require("tslib");
var React = require("react");
var Button_1 = require("../../Button");
var Nav_styles_1 = require("./Nav.styles");
var Utilities_1 = require("../../Utilities");
var FocusZone_1 = require("../../FocusZone");
var Icon_1 = require("../../Icon");
var utilities_1 = require("@fluentui/utilities");
var react_window_provider_1 = require("@fluentui/react-window-provider");
var dom_1 = require("../../utilities/dom");
// The number pixels per indentation level for Nav links.
var _indentationSize = 14;
// The number of pixels of left margin
var _baseIndent = 3;
// global var used in _isLinkSelectedKey
var _urlResolver;
function isRelativeUrl(url) {
// A URL is relative if it has no protocol.
return !!url && !/^[a-z0-9+-.]+:\/\//i.test(url);
}
var getClassNames = (0, Utilities_1.classNamesFunction)();
var NavBase = /** @class */ (function (_super) {
tslib_1.__extends(NavBase, _super);
function NavBase(props) {
var _this = _super.call(this, props) || this;
_this._focusZone = React.createRef();
_this._onRenderLink = function (link) {
var _a = _this.props, styles = _a.styles, groups = _a.groups, theme = _a.theme;
var classNames = getClassNames(styles, { theme: theme, groups: groups });
return React.createElement("div", { className: classNames.linkText }, link.name);
};
_this._renderGroup = function (group, groupIndex) {
var _a = _this.props, styles = _a.styles, groups = _a.groups, theme = _a.theme, _b = _a.onRenderGroupHeader, onRenderGroupHeader = _b === void 0 ? _this._renderGroupHeader : _b;
var isExpanded = _this._isGroupExpanded(group);
var classNames = getClassNames(styles, {
theme: theme,
isGroup: true,
isExpanded: isExpanded,
groups: groups,
});
var finalOnHeaderClick = function (ev, isCollapsing) {
_this._onGroupHeaderClicked(group, ev);
};
var groupProps = tslib_1.__assign(tslib_1.__assign({}, group), { isExpanded: isExpanded, onHeaderClick: finalOnHeaderClick });
return (React.createElement("div", { key: groupIndex, className: classNames.group },
groupProps.name ? onRenderGroupHeader(groupProps, _this._renderGroupHeader) : null,
React.createElement("div", { className: classNames.groupContent }, _this._renderLinks(groupProps.links, 0 /* nestingLevel */))));
};
_this._renderGroupHeader = function (group) {
var _a;
// eslint-disable-next-line @typescript-eslint/no-deprecated
var _b = _this.props, styles = _b.styles, groups = _b.groups, theme = _b.theme, expandButtonAriaLabel = _b.expandButtonAriaLabel;
var isExpanded = group.isExpanded;
var classNames = getClassNames(styles, {
theme: theme,
isGroup: true,
isExpanded: isExpanded,
groups: groups,
});
// respect deprecated collapseAriaLabel, but default to expandAriaLabel for both states
// eslint-disable-next-line @typescript-eslint/no-deprecated
var collapseAriaLabel = (_a = group.collapseAriaLabel) !== null && _a !== void 0 ? _a : group.expandAriaLabel;
var label = (isExpanded ? collapseAriaLabel : group.expandAriaLabel) || expandButtonAriaLabel;
var onHeaderClick = group.onHeaderClick;
var onClick = onHeaderClick
? function (ev) {
onHeaderClick(ev, isExpanded);
}
: undefined;
return (React.createElement("button", { className: classNames.chevronButton, onClick: onClick, "aria-label": label, "aria-expanded": isExpanded },
React.createElement(Icon_1.Icon, { className: classNames.chevronIcon, iconName: "ChevronDown" }),
group.name));
};
(0, Utilities_1.initializeComponentRef)(_this);
_this.state = {
isGroupCollapsed: {},
isLinkExpandStateChanged: false,
selectedKey: props.initialSelectedKey || props.selectedKey,
};
return _this;
}
NavBase.prototype.render = function () {
var _a = this.props, styles = _a.styles, groups = _a.groups, className = _a.className, isOnTop = _a.isOnTop, _b = _a.role, role = _b === void 0 ? 'navigation' : _b, theme = _a.theme;
if (!groups) {
return null;
}
var groupElements = groups.map(this._renderGroup);
var classNames = getClassNames(styles, { theme: theme, className: className, isOnTop: isOnTop, groups: groups });
return (React.createElement(FocusZone_1.FocusZone, tslib_1.__assign({ direction: FocusZone_1.FocusZoneDirection.vertical, componentRef: this._focusZone }, this.props.focusZoneProps),
React.createElement("nav", { role: role, className: classNames.root, "aria-label": this.props.ariaLabel }, groupElements)));
};
Object.defineProperty(NavBase.prototype, "selectedKey", {
get: function () {
return this.state.selectedKey;
},
enumerable: false,
configurable: true
});
/**
* Sets focus to the first tabbable item in the zone.
* @param forceIntoFirstElement - If true, focus will be forced into the first element, even
* if focus is already in the focus zone.
* @returns True if focus could be set to an active element, false if no operation was taken.
*/
NavBase.prototype.focus = function (forceIntoFirstElement) {
if (forceIntoFirstElement === void 0) { forceIntoFirstElement = false; }
if (this._focusZone && this._focusZone.current) {
return this._focusZone.current.focus(forceIntoFirstElement);
}
return false;
};
NavBase.prototype._renderNavLink = function (link, linkIndex, nestingLevel) {
var _a = this.props, styles = _a.styles, groups = _a.groups, theme = _a.theme;
var isLinkWithIcon = link.icon || link.iconProps;
var isSelectedLink = this._isLinkSelected(link);
var _b = link.ariaCurrent, ariaCurrent = _b === void 0 ? 'page' : _b;
var classNames = getClassNames(styles, {
theme: theme,
isSelected: isSelectedLink,
isDisabled: link.disabled,
isButtonEntry: link.onClick && !link.forceAnchor,
leftPadding: _indentationSize * nestingLevel + _baseIndent + (isLinkWithIcon ? 0 : 24),
groups: groups,
});
// Prevent hijacking of the parent window if link.target is defined
var rel = link.url && link.target && !isRelativeUrl(link.url) ? 'noopener noreferrer' : undefined;
var LinkAs = this.props.linkAs ? (0, utilities_1.composeComponentAs)(this.props.linkAs, Button_1.ActionButton) : Button_1.ActionButton;
var onRenderLink = this.props.onRenderLink
? (0, utilities_1.composeRenderFunction)(this.props.onRenderLink, this._onRenderLink)
: this._onRenderLink;
return (React.createElement(LinkAs, { className: classNames.link, styles: Nav_styles_1.buttonStyles, href: link.url || (link.forceAnchor ? '#' : undefined), iconProps: link.iconProps || { iconName: link.icon },
// eslint-disable-next-line react/jsx-no-bind
onClick: link.onClick ? this._onNavButtonLinkClicked.bind(this, link) : this._onNavAnchorLinkClicked.bind(this, link), title: link.title !== undefined ? link.title : link.name, target: link.target, rel: rel, disabled: link.disabled, "aria-current": isSelectedLink ? ariaCurrent : undefined, "aria-label": link.ariaLabel ? link.ariaLabel : undefined, link: link }, onRenderLink(link)));
};
NavBase.prototype._renderCompositeLink = function (link, linkIndex, nestingLevel) {
var _a;
var divProps = tslib_1.__assign({}, (0, Utilities_1.getNativeProps)(link, Utilities_1.divProperties, ['onClick']));
// eslint-disable-next-line @typescript-eslint/no-deprecated
var _b = this.props, expandButtonAriaLabel = _b.expandButtonAriaLabel, styles = _b.styles, groups = _b.groups, theme = _b.theme;
var classNames = getClassNames(styles, {
theme: theme,
isExpanded: !!link.isExpanded,
isSelected: this._isLinkSelected(link),
isLink: true,
isDisabled: link.disabled,
position: _indentationSize * nestingLevel + 1,
groups: groups,
});
var finalExpandBtnAriaLabel = '';
if (link.links && link.links.length > 0) {
if (link.collapseAriaLabel || link.expandAriaLabel) {
// still respect link.collapseAriaLabel, even though it's deprecated in favor of expandAriaLabel
var collapseAriaLabel = (_a = link.collapseAriaLabel) !== null && _a !== void 0 ? _a : link.expandAriaLabel;
finalExpandBtnAriaLabel = link.isExpanded ? collapseAriaLabel : link.expandAriaLabel;
}
else {
// TODO remove when `expandButtonAriaLabel` is removed. This is not an ideal concatenation for localization.
finalExpandBtnAriaLabel = expandButtonAriaLabel ? "".concat(link.name, " ").concat(expandButtonAriaLabel) : link.name;
}
}
return (React.createElement("div", tslib_1.__assign({}, divProps, { key: link.key || linkIndex, className: classNames.compositeLink }),
link.links && link.links.length > 0 ? (React.createElement("button", { className: classNames.chevronButton, onClick: this._onLinkExpandClicked.bind(this, link), "aria-label": finalExpandBtnAriaLabel, "aria-expanded": link.isExpanded ? 'true' : 'false' },
React.createElement(Icon_1.Icon, { className: classNames.chevronIcon, iconName: "ChevronDown" }))) : null,
this._renderNavLink(link, linkIndex, nestingLevel)));
};
NavBase.prototype._renderLink = function (link, linkIndex, nestingLevel) {
var _a = this.props, styles = _a.styles, groups = _a.groups, theme = _a.theme;
var classNames = getClassNames(styles, { theme: theme, groups: groups });
return (React.createElement("li", { key: link.key || linkIndex, role: "listitem", className: classNames.navItem },
this._renderCompositeLink(link, linkIndex, nestingLevel),
link.isExpanded ? this._renderLinks(link.links, ++nestingLevel) : null));
};
NavBase.prototype._renderLinks = function (links, nestingLevel) {
var _this = this;
if (!links || !links.length) {
return null;
}
var linkElements = links.map(function (link, linkIndex) {
return _this._renderLink(link, linkIndex, nestingLevel);
});
var _a = this.props, styles = _a.styles, groups = _a.groups, theme = _a.theme;
var classNames = getClassNames(styles, { theme: theme, groups: groups });
return (React.createElement("ul", { role: "list", className: classNames.navItems }, linkElements));
};
NavBase.prototype._onGroupHeaderClicked = function (group, ev) {
if (group.onHeaderClick) {
group.onHeaderClick(ev, this._isGroupExpanded(group));
}
if (group.isExpanded === undefined) {
this._toggleCollapsed(group);
}
if (ev) {
ev.preventDefault();
ev.stopPropagation();
}
};
NavBase.prototype._onLinkExpandClicked = function (link, ev) {
var onLinkExpandClick = this.props.onLinkExpandClick;
if (onLinkExpandClick) {
onLinkExpandClick(ev, link);
}
if (!ev.defaultPrevented) {
link.isExpanded = !link.isExpanded;
this.setState({ isLinkExpandStateChanged: true });
}
ev.preventDefault();
ev.stopPropagation();
};
NavBase.prototype._preventBounce = function (link, ev) {
if (!link.url && link.forceAnchor) {
ev.preventDefault();
}
};
NavBase.prototype._onNavAnchorLinkClicked = function (link, ev) {
// If the href is "#" we should call preventDefault to prevent scrolling to the top of the page
this._preventBounce(link, ev);
if (this.props.onLinkClick) {
this.props.onLinkClick(ev, link);
}
if (!link.url && link.links && link.links.length > 0) {
this._onLinkExpandClicked(link, ev);
}
this.setState({ selectedKey: link.key });
};
NavBase.prototype._onNavButtonLinkClicked = function (link, ev) {
// If the href is "#" we should call preventDefault to prevent scrolling to the top of the page
this._preventBounce(link, ev);
if (link.onClick) {
link.onClick(ev, link);
}
if (!link.url && link.links && link.links.length > 0) {
this._onLinkExpandClicked(link, ev);
}
this.setState({ selectedKey: link.key });
};
NavBase.prototype._isLinkSelected = function (link) {
// if caller passes in selectedKey, use it as first choice or
// if current state.selectedKey (from addressbar) is match to the link or
// check if URL is matching location.href (if link.url exists)
if (this.props.selectedKey !== undefined) {
return link.key === this.props.selectedKey;
}
else if (this.state.selectedKey !== undefined) {
return link.key === this.state.selectedKey;
}
else if (typeof (0, Utilities_1.getWindow)() === 'undefined' || !link.url) {
// resolve is not supported for ssr
return false;
}
else {
var doc = (0, dom_1.getDocumentEx)(this.context); // there is an SSR check above so this is safe
// If selectedKey is undefined in props and state, then check URL
_urlResolver = _urlResolver || doc.createElement('a');
_urlResolver.href = link.url || '';
var target = _urlResolver.href;
if (location.href === target) {
return true;
}
// If selectedKey is not defined in state, then check URL to determine link selected status
if (location.protocol + '//' + location.host + location.pathname === target) {
return true;
}
if (location.hash) {
// Match the hash to the url.
if (location.hash === link.url) {
return true;
}
// Match a rebased url. (e.g. #foo becomes http://hostname/foo)
_urlResolver.href = location.hash.substring(1);
return _urlResolver.href === target;
}
}
return false;
};
NavBase.prototype._isGroupExpanded = function (group) {
if (group.isExpanded !== undefined) {
return group.isExpanded;
}
if (group.name && this.state.isGroupCollapsed.hasOwnProperty(group.name)) {
return !this.state.isGroupCollapsed[group.name];
}
if (group.collapseByDefault !== undefined) {
return !group.collapseByDefault;
}
return true;
};
NavBase.prototype._toggleCollapsed = function (group) {
var _a;
if (group.name) {
var newGroupCollapsed = tslib_1.__assign(tslib_1.__assign({}, this.state.isGroupCollapsed), (_a = {}, _a[group.name] = this._isGroupExpanded(group), _a));
this.setState({ isGroupCollapsed: newGroupCollapsed });
}
};
NavBase.defaultProps = {
groups: null,
};
NavBase.contextType = react_window_provider_1.WindowContext;
return NavBase;
}(React.Component));
exports.NavBase = NavBase;
//# sourceMappingURL=Nav.base.js.map
File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
import * as React from 'react';
import type { INavProps } from './Nav.types';
export declare const Nav: React.FunctionComponent<INavProps>;
+10
View File
@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Nav = void 0;
var Utilities_1 = require("../../Utilities");
var Nav_base_1 = require("./Nav.base");
var Nav_styles_1 = require("./Nav.styles");
exports.Nav = (0, Utilities_1.styled)(Nav_base_1.NavBase, Nav_styles_1.getStyles, undefined, {
scope: 'Nav',
});
//# sourceMappingURL=Nav.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Nav.js","sourceRoot":"../src/","sources":["components/Nav/Nav.tsx"],"names":[],"mappings":";;;AACA,6CAAyC;AACzC,uCAAqC;AACrC,2CAAyC;AAG5B,QAAA,GAAG,GAAuC,IAAA,kBAAM,EAC3D,kBAAO,EACP,sBAAS,EACT,SAAS,EACT;IACE,KAAK,EAAE,KAAK;CACb,CACF,CAAC","sourcesContent":["import * as React from 'react';\nimport { styled } from '../../Utilities';\nimport { NavBase } from './Nav.base';\nimport { getStyles } from './Nav.styles';\nimport type { INavProps, INavStyleProps, INavStyles } from './Nav.types';\n\nexport const Nav: React.FunctionComponent<INavProps> = styled<INavProps, INavStyleProps, INavStyles>(\n NavBase,\n getStyles,\n undefined,\n {\n scope: 'Nav',\n },\n);\n"]}
@@ -0,0 +1,4 @@
import type { INavStyleProps, INavStyles } from './Nav.types';
import type { IButtonStyles } from '../../Button';
export declare const buttonStyles: IButtonStyles;
export declare const getStyles: (props: INavStyleProps) => INavStyles;
+222
View File
@@ -0,0 +1,222 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getStyles = exports.buttonStyles = void 0;
var Styling_1 = require("../../Styling");
var GlobalClassNames = {
root: 'ms-Nav',
linkText: 'ms-Nav-linkText',
compositeLink: 'ms-Nav-compositeLink',
link: 'ms-Nav-link',
chevronButton: 'ms-Nav-chevronButton',
chevronIcon: 'ms-Nav-chevron',
navItem: 'ms-Nav-navItem',
navItems: 'ms-Nav-navItems',
group: 'ms-Nav-group',
groupContent: 'ms-Nav-groupContent',
};
exports.buttonStyles = {
textContainer: {
overflow: 'hidden',
},
label: {
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
overflow: 'hidden',
},
};
var getStyles = function (props) {
var _a;
var className = props.className, theme = props.theme, isOnTop = props.isOnTop, isExpanded = props.isExpanded, isGroup = props.isGroup, isLink = props.isLink, isSelected = props.isSelected, isDisabled = props.isDisabled, isButtonEntry = props.isButtonEntry, _b = props.navHeight, navHeight = _b === void 0 ? 44 : _b, position = props.position, _c = props.leftPadding, leftPadding = _c === void 0 ? 20 : _c, _d = props.leftPaddingExpanded, leftPaddingExpanded = _d === void 0 ? 28 : _d, _e = props.rightPadding, rightPadding = _e === void 0 ? 20 : _e;
var palette = theme.palette, semanticColors = theme.semanticColors, fonts = theme.fonts;
var classNames = (0, Styling_1.getGlobalClassNames)(GlobalClassNames, theme);
return {
root: [
classNames.root,
className,
fonts.medium,
{
overflowY: 'auto',
userSelect: 'none',
WebkitOverflowScrolling: 'touch',
},
isOnTop && [
{
position: 'absolute',
},
Styling_1.AnimationClassNames.slideRightIn40,
],
],
linkText: [
classNames.linkText,
{
margin: '0 4px',
overflow: 'hidden',
verticalAlign: 'middle',
textAlign: 'left',
textOverflow: 'ellipsis',
},
],
compositeLink: [
classNames.compositeLink,
{
display: 'block',
position: 'relative',
color: semanticColors.bodyText,
},
isExpanded && 'is-expanded',
isSelected && 'is-selected',
isDisabled && 'is-disabled',
isDisabled && {
color: semanticColors.disabledText,
},
],
link: [
classNames.link,
(0, Styling_1.getFocusStyle)(theme),
{
display: 'block',
position: 'relative',
height: navHeight,
width: '100%',
lineHeight: "".concat(navHeight, "px"),
textDecoration: 'none',
cursor: 'pointer',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
paddingLeft: leftPadding,
paddingRight: rightPadding,
color: semanticColors.bodyText,
selectors: (_a = {},
_a[Styling_1.HighContrastSelector] = {
border: 0,
selectors: {
':focus': {
border: '1px solid WindowText',
},
},
},
_a),
},
!isDisabled && {
selectors: {
'.ms-Nav-compositeLink:hover &': {
backgroundColor: semanticColors.bodyBackgroundHovered,
},
},
},
isSelected && {
color: semanticColors.bodyTextChecked,
fontWeight: Styling_1.FontWeights.semibold, // todo: get from theme
backgroundColor: semanticColors.bodyBackgroundChecked,
selectors: {
'&:after': {
borderLeft: "2px solid ".concat(palette.themePrimary),
content: '""',
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
pointerEvents: 'none',
},
},
},
isDisabled && {
color: semanticColors.disabledText,
},
isButtonEntry && {
color: palette.themePrimary,
},
],
chevronButton: [
classNames.chevronButton,
(0, Styling_1.getFocusStyle)(theme),
fonts.small,
{
display: 'block',
textAlign: 'left',
lineHeight: "".concat(navHeight, "px"),
margin: '5px 0',
padding: "0px, ".concat(rightPadding, "px, 0px, ").concat(leftPaddingExpanded, "px"),
border: 'none',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
cursor: 'pointer',
color: semanticColors.bodyText,
backgroundColor: 'transparent',
selectors: {
'&:visited': {
color: semanticColors.bodyText,
},
},
},
isGroup && {
fontSize: fonts.large.fontSize,
width: '100%',
height: navHeight,
borderBottom: "1px solid ".concat(semanticColors.bodyDivider),
},
isLink && {
display: 'block',
width: leftPaddingExpanded - 2,
height: navHeight - 2,
position: 'absolute',
top: '1px',
left: "".concat(position, "px"),
zIndex: Styling_1.ZIndexes.Nav,
padding: 0,
margin: 0,
},
],
chevronIcon: [
classNames.chevronIcon,
{
position: 'absolute',
left: '8px',
height: navHeight,
// inline-flex prevents the chevron from shifting with custom line height styles
display: 'inline-flex',
alignItems: 'center',
lineHeight: "".concat(navHeight, "px"),
fontSize: fonts.small.fontSize,
transition: 'transform .1s linear',
},
isExpanded && {
transform: 'rotate(-180deg)',
},
isLink && {
top: 0,
},
],
navItem: [
classNames.navItem,
{
padding: 0,
},
],
navItems: [
classNames.navItems,
{
listStyleType: 'none',
padding: 0,
margin: 0, // remove default <UL> styles
},
],
group: [classNames.group, isExpanded && 'is-expanded'],
groupContent: [
classNames.groupContent,
{
display: 'none',
marginBottom: '40px',
},
Styling_1.AnimationClassNames.slideDownIn20,
isExpanded && {
display: 'block',
},
],
};
};
exports.getStyles = getStyles;
//# sourceMappingURL=Nav.styles.js.map
File diff suppressed because one or more lines are too long
+371
View File
@@ -0,0 +1,371 @@
import * as React from 'react';
import type { IStyle, ITheme } from '../../Styling';
import type { IRefObject, IRenderFunction, IStyleFunctionOrObject, IComponentAs } from '../../Utilities';
import type { IIconProps } from '../Icon/Icon.types';
import type { IButtonProps } from '../../Button';
import type { IFocusZoneProps } from '../../FocusZone';
/**
* {@doccategory Nav}
*/
export interface IRenderGroupHeaderProps extends INavLinkGroup {
/**
* Whether or not the group is presently expanded.
*/
isExpanded?: boolean;
}
/**
* {@docCategory Nav}
*/
export interface INav {
/**
* The meta 'key' property of the currently selected NavItem of the Nav. Can return
* undefined if the currently selected nav item has no populated key property. Be aware
* that in order for Nav to properly understand which key is selected all NavItems in
* all groups of the Nav must have populated key properties.
*/
selectedKey: string | undefined;
/**
* Sets focus to the first tabbable item in the zone.
* @param forceIntoFirstElement - If true, focus will be forced into the first element, even
* if focus is already in the focus zone.
* @returns True if focus could be set to an active element, false if no operation was taken.
*/
focus(forceIntoFirstElement?: boolean): boolean;
}
/**
* {@docCategory Nav}
*/
export interface INavProps {
/**
* Optional callback to access the INav interface. Use this instead of ref for accessing
* the public methods and properties of the component.
*/
componentRef?: IRefObject<INav>;
/**
* Call to provide customized styling that will layer on top of the variant rules
*/
styles?: IStyleFunctionOrObject<INavStyleProps, INavStyles>;
/**
* Theme provided by HOC.
*/
theme?: ITheme;
/**
* Additional css class to apply to the Nav
* @defaultvalue undefined
*/
className?: string;
/**
* A collection of link groups to display in the navigation bar
*/
groups: INavLinkGroup[] | null;
/**
* Used to customize how content inside the group header is rendered
*/
onRenderGroupHeader?: IRenderFunction<IRenderGroupHeaderProps>;
/**
* Render a custom link in place of the normal one.
* This replaces the entire button rather than simply button content
*/
linkAs?: IComponentAs<INavButtonProps>;
/**
* Used to customize how content inside the link tag is rendered
*/
onRenderLink?: IRenderFunction<INavLink>;
/**
* Function callback invoked when a link in the navigation is clicked
*/
onLinkClick?: (ev?: React.MouseEvent<HTMLElement>, item?: INavLink) => void;
/**
* Function callback invoked when the chevron on a link is clicked
*/
onLinkExpandClick?: (ev?: React.MouseEvent<HTMLElement>, item?: INavLink) => void;
/**
* Indicates whether the navigation component renders on top of other content in the UI
*/
isOnTop?: boolean;
/**
* (Optional) The key of the nav item initially selected.
*/
initialSelectedKey?: string;
/**
* (Optional) Override the role of the `<nav>` element.
* This is only recommended if you're nesting `Nav` inside a parent navigation region.
*/
role?: string;
/**
* (Optional) The key of the nav item selected by caller.
*/
selectedKey?: string;
/**
* (Optional) The nav container aria label.
*/
ariaLabel?: string;
/**
* (Optional) The nav container aria label. The link name is prepended to this label.
* If not provided, the aria label will default to the link name.
*
* @deprecated Use `expandAriaLabel` and `collapseAriaLabel` on groups instead
*/
expandButtonAriaLabel?: string;
/**
* (Deprecated) Use ariaCurrent on links instead
* @deprecated Use ariaCurrent on links instead
*/
selectedAriaLabel?: string;
/**
* (Optional) Used to define the props of the FocusZone wrapper.
*/
focusZoneProps?: IFocusZoneProps;
}
/**
* {@docCategory Nav}
*/
export interface INavLinkGroup {
/**
* Text to render as the header of a group
*/
name?: string;
/**
* Links to render within this group
*/
links: INavLink[];
/**
* The name to use for functional automation tests
*/
automationId?: string;
/**
* If true, the group should render collapsed by default
*/
collapseByDefault?: boolean;
/**
* Callback invoked when a group header is clicked
*/
onHeaderClick?: (ev?: React.MouseEvent<HTMLElement>, isCollapsing?: boolean) => void;
/**
* ARIA label when group is collapsed and can be expanded.
*/
expandAriaLabel?: string;
/**
* ARIA label when group is collapsed and can be expanded.
* WARNING: using separate labels for expanded and collapsed state is not recommended.
*
* @deprecated Use `expandAriaLabel` on its own instead.
*/
collapseAriaLabel?: string;
/**
* (Optional) Any additional properties to apply to a group.
*/
groupData?: any;
/**
* Provides consumer control to update the collapsed/expanded state of the group.
*/
isExpanded?: boolean;
}
/**
* {@docCategory Nav}
*/
export interface INavLink {
/**
* Text to render for this link
*/
name: string;
/**
* URL to navigate to for this link
*/
url: string;
/**
* Unique, stable key for the link, used when rendering the list of links and for tracking
* the currently selected link.
*/
key?: string;
/**
* Child links to this link, if any
*/
links?: INavLink[];
/**
* Callback invoked when this link is clicked. Providing this callback will cause the link
* to render as a button (rather than an anchor) unless forceAnchor is set to true.
*/
onClick?: (ev?: React.MouseEvent<HTMLElement>, item?: INavLink) => void;
/**
* Name of an icon to render next to the link button.
*/
icon?: string;
/**
* @deprecated Use `iconProps.className` instead.
*/
iconClassName?: string;
/**
* Props for an icon to render next to the link button.
*/
iconProps?: IIconProps;
/**
* The name to use for functional automation tests
*/
automationId?: string;
/**
* Whether or not the link is in an expanded state
*/
isExpanded?: boolean;
/**
* Aria-current token for active nav links. Must be a valid token value, and defaults to 'page'.
*/
ariaCurrent?: 'page' | 'step' | 'location' | 'date' | 'time' | 'true';
/**
* Aria label for nav link. Ignored if `collapseAriaLabel` or `expandAriaLabel` is provided.
*/
ariaLabel?: string;
/**
* Text for title tooltip and ARIA description.
*/
title?: string;
/**
* Link <a> target.
*/
target?: string;
/**
* Whether or not the link is disabled.
*/
disabled?: boolean;
/**
* (Optional) By default, any link with onClick defined will render as a button.
* Set this property to true to override that behavior. (Links without onClick defined
* will render as anchors by default.)
*/
forceAnchor?: boolean;
/**
* ARIA label when group is collapsed and can be expanded.
*/
expandAriaLabel?: string;
/**
* ARIA label when group is collapsed and can be expanded.
*/
collapseAriaLabel?: string;
/**
* (Optional) Any additional properties to apply to the rendered links.
*/
[propertyName: string]: any;
}
/**
* {@docCategory Nav}
*/
export interface INavStyleProps {
/**
* Accept theme prop.
*/
theme: ITheme;
/**
* Accept custom classNames
*/
className?: string;
/**
* is element on top boolean
*/
isOnTop?: boolean;
/**
* is element a link boolean
*/
isLink?: boolean;
/**
* is element disabled
*/
isDisabled?: boolean;
/**
* is element a group boolean
*/
isGroup?: boolean;
/**
* is element expanded boolean
*/
isExpanded?: boolean;
/**
* is element selected boolean
*/
isSelected?: boolean;
/**
* is button
*/
isButtonEntry?: boolean;
/**
* Nav height value
*/
navHeight?: number;
/**
* left padding value
*/
leftPadding?: number;
/**
* left padding when expanded value
*/
leftPaddingExpanded?: number;
/**
* right padding value
*/
rightPadding?: number;
/**
* position value
*/
position?: number;
/**
* Inherited from INavProps
* A collection of link groups to display in the navigation bar
*/
groups: INavLinkGroup[] | null;
}
/**
* {@docCategory Nav}
*/
export interface INavStyles {
/**
* Style set for the root element.
*/
root: IStyle;
/**
* Style set for the link text container div element.
*/
linkText: IStyle;
/**
* Style set for the link element extending the
* root style set for ActionButton component.
*/
link: IStyle;
/**
* Style set for the composite link container div element
*/
compositeLink: IStyle;
/**
* Style set for the chevron button inside the composite
* link and group elements.
*/
chevronButton: IStyle;
/**
* Style set for the chevron icon inside the composite
* link and group elements.
*/
chevronIcon: IStyle;
/**
* Style set for the nav links ul element.
*/
navItems: IStyle;
/**
* Style set for the nav links li element.
*/
navItem: IStyle;
/**
* Style set for the group root div.
*/
group: IStyle;
/**
* Style set for the group content div inside group.
*/
groupContent: IStyle;
}
/**
* {@docCategory Nav}
*/
export interface INavButtonProps extends IButtonProps {
/**
* (Optional) Link to be rendered.
*/
link?: INavLink;
}
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=Nav.types.js.map
File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
export * from './Nav';
export * from './Nav.base';
export * from './Nav.types';
+7
View File
@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
tslib_1.__exportStar(require("./Nav"), exports);
tslib_1.__exportStar(require("./Nav.base"), exports);
tslib_1.__exportStar(require("./Nav.types"), exports);
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["components/Nav/index.ts"],"names":[],"mappings":";;;AAAA,gDAAsB;AACtB,qDAA2B;AAC3B,sDAA4B","sourcesContent":["export * from './Nav';\nexport * from './Nav.base';\nexport * from './Nav.types';\n"]}