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,14 @@
import type { IActivityItemStyles } from './ActivityItem.types';
import type { IPersonaProps } from '../../Persona';
export interface IActivityItemClassNames {
root?: string;
activityContent?: string;
activityText?: string;
personaContainer?: string;
activityPersona?: string;
activityTypeIcon?: string;
commentText?: string;
timeStamp?: string;
pulsingBeacon?: string;
}
export declare const getClassNames: (styles: IActivityItemStyles, className: string, activityPersonas: Array<IPersonaProps>, isCompact: boolean) => IActivityItemClassNames;
@@ -0,0 +1,16 @@
import { mergeStyles } from '../../Styling';
import { memoizeFunction } from '../../Utilities';
export var getClassNames = memoizeFunction(function (styles, className, activityPersonas, isCompact) {
return {
root: mergeStyles(styles.__shadowConfig__, 'ms-ActivityItem', className, styles.root, isCompact && styles.isCompactRoot),
pulsingBeacon: mergeStyles(styles.__shadowConfig__, 'ms-ActivityItem-pulsingBeacon', styles.pulsingBeacon),
personaContainer: mergeStyles(styles.__shadowConfig__, 'ms-ActivityItem-personaContainer', styles.personaContainer, isCompact && styles.isCompactPersonaContainer),
activityPersona: mergeStyles(styles.__shadowConfig__, 'ms-ActivityItem-activityPersona', styles.activityPersona, isCompact && styles.isCompactPersona, !isCompact && activityPersonas && activityPersonas.length === 2 && styles.doublePersona),
activityTypeIcon: mergeStyles(styles.__shadowConfig__, 'ms-ActivityItem-activityTypeIcon', styles.activityTypeIcon, isCompact && styles.isCompactIcon),
activityContent: mergeStyles(styles.__shadowConfig__, 'ms-ActivityItem-activityContent', styles.activityContent, isCompact && styles.isCompactContent),
activityText: mergeStyles(styles.__shadowConfig__, 'ms-ActivityItem-activityText', styles.activityText),
commentText: mergeStyles(styles.__shadowConfig__, 'ms-ActivityItem-commentText', styles.commentText),
timeStamp: mergeStyles(styles.__shadowConfig__, 'ms-ActivityItem-timeStamp', styles.timeStamp, isCompact && styles.isCompactTimeStamp),
};
});
//# sourceMappingURL=ActivityItem.classNames.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ActivityItem.classNames.js","sourceRoot":"../src/","sources":["components/ActivityItem/ActivityItem.classNames.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAgBlD,MAAM,CAAC,IAAM,aAAa,GAAG,eAAe,CAC1C,UACE,MAA2B,EAC3B,SAAiB,EACjB,gBAAsC,EACtC,SAAkB;IAElB,OAAO;QACL,IAAI,EAAE,WAAW,CACf,MAAM,CAAC,gBAAgB,EACvB,iBAAiB,EACjB,SAAS,EACT,MAAM,CAAC,IAAI,EACX,SAAS,IAAI,MAAM,CAAC,aAAa,CAClC;QAED,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,gBAAgB,EAAE,+BAA+B,EAAE,MAAM,CAAC,aAAa,CAAC;QAE1G,gBAAgB,EAAE,WAAW,CAC3B,MAAM,CAAC,gBAAgB,EACvB,kCAAkC,EAClC,MAAM,CAAC,gBAAgB,EACvB,SAAS,IAAI,MAAM,CAAC,yBAAyB,CAC9C;QAED,eAAe,EAAE,WAAW,CAC1B,MAAM,CAAC,gBAAgB,EACvB,iCAAiC,EACjC,MAAM,CAAC,eAAe,EACtB,SAAS,IAAI,MAAM,CAAC,gBAAgB,EACpC,CAAC,SAAS,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,aAAa,CACxF;QAED,gBAAgB,EAAE,WAAW,CAC3B,MAAM,CAAC,gBAAgB,EACvB,kCAAkC,EAClC,MAAM,CAAC,gBAAgB,EACvB,SAAS,IAAI,MAAM,CAAC,aAAa,CAClC;QAED,eAAe,EAAE,WAAW,CAC1B,MAAM,CAAC,gBAAgB,EACvB,iCAAiC,EACjC,MAAM,CAAC,eAAe,EACtB,SAAS,IAAI,MAAM,CAAC,gBAAgB,CACrC;QAED,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,gBAAgB,EAAE,8BAA8B,EAAE,MAAM,CAAC,YAAY,CAAC;QACvG,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,gBAAgB,EAAE,6BAA6B,EAAE,MAAM,CAAC,WAAW,CAAC;QACpG,SAAS,EAAE,WAAW,CACpB,MAAM,CAAC,gBAAgB,EACvB,2BAA2B,EAC3B,MAAM,CAAC,SAAS,EAChB,SAAS,IAAI,MAAM,CAAC,kBAAkB,CACvC;KACF,CAAC;AACJ,CAAC,CACF,CAAC","sourcesContent":["import { mergeStyles } from '../../Styling';\nimport { memoizeFunction } from '../../Utilities';\nimport type { IActivityItemStyles } from './ActivityItem.types';\nimport type { IPersonaProps } from '../../Persona';\n\nexport interface IActivityItemClassNames {\n root?: string;\n activityContent?: string;\n activityText?: string;\n personaContainer?: string;\n activityPersona?: string;\n activityTypeIcon?: string;\n commentText?: string;\n timeStamp?: string;\n pulsingBeacon?: string;\n}\n\nexport const getClassNames = memoizeFunction(\n (\n styles: IActivityItemStyles,\n className: string,\n activityPersonas: Array<IPersonaProps>,\n isCompact: boolean,\n ): IActivityItemClassNames => {\n return {\n root: mergeStyles(\n styles.__shadowConfig__,\n 'ms-ActivityItem',\n className,\n styles.root,\n isCompact && styles.isCompactRoot,\n ),\n\n pulsingBeacon: mergeStyles(styles.__shadowConfig__, 'ms-ActivityItem-pulsingBeacon', styles.pulsingBeacon),\n\n personaContainer: mergeStyles(\n styles.__shadowConfig__,\n 'ms-ActivityItem-personaContainer',\n styles.personaContainer,\n isCompact && styles.isCompactPersonaContainer,\n ),\n\n activityPersona: mergeStyles(\n styles.__shadowConfig__,\n 'ms-ActivityItem-activityPersona',\n styles.activityPersona,\n isCompact && styles.isCompactPersona,\n !isCompact && activityPersonas && activityPersonas.length === 2 && styles.doublePersona,\n ),\n\n activityTypeIcon: mergeStyles(\n styles.__shadowConfig__,\n 'ms-ActivityItem-activityTypeIcon',\n styles.activityTypeIcon,\n isCompact && styles.isCompactIcon,\n ),\n\n activityContent: mergeStyles(\n styles.__shadowConfig__,\n 'ms-ActivityItem-activityContent',\n styles.activityContent,\n isCompact && styles.isCompactContent,\n ),\n\n activityText: mergeStyles(styles.__shadowConfig__, 'ms-ActivityItem-activityText', styles.activityText),\n commentText: mergeStyles(styles.__shadowConfig__, 'ms-ActivityItem-commentText', styles.commentText),\n timeStamp: mergeStyles(\n styles.__shadowConfig__,\n 'ms-ActivityItem-timeStamp',\n styles.timeStamp,\n isCompact && styles.isCompactTimeStamp,\n ),\n };\n },\n);\n"]}
@@ -0,0 +1,16 @@
import * as React from 'react';
import type { IActivityItemProps } from './ActivityItem.types';
import type { JSXElement } from '@fluentui/utilities';
/**
* {@docCategory ActivityItem}
*/
export declare class ActivityItem extends React.Component<IActivityItemProps, {}> {
constructor(props: IActivityItemProps);
render(): JSXElement;
private _onRenderIcon;
private _onRenderActivityDescription;
private _onRenderComments;
private _onRenderTimeStamp;
private _onRenderPersonaArray;
private _getClassNames;
}
@@ -0,0 +1,95 @@
import { __assign, __extends } from "tslib";
import * as React from 'react';
import { getClassNames } from './ActivityItem.classNames';
import { getStyles } from './ActivityItem.styles';
import { PersonaSize, PersonaCoin } from '../../Persona';
/**
* {@docCategory ActivityItem}
*/
var ActivityItem = /** @class */ (function (_super) {
__extends(ActivityItem, _super);
function ActivityItem(props) {
var _this = _super.call(this, props) || this;
_this._onRenderIcon = function (props) {
if (props.activityPersonas) {
return _this._onRenderPersonaArray(props);
}
else {
return _this.props.activityIcon;
}
};
_this._onRenderActivityDescription = function (props) {
var classNames = _this._getClassNames(props);
// eslint-disable-next-line @typescript-eslint/no-deprecated
var activityDescription = props.activityDescription || props.activityDescriptionText;
if (activityDescription) {
return React.createElement("span", { className: classNames.activityText }, activityDescription);
}
return null;
};
_this._onRenderComments = function (props) {
var classNames = _this._getClassNames(props);
// eslint-disable-next-line @typescript-eslint/no-deprecated
var comments = props.comments || props.commentText;
if (!props.isCompact && comments) {
return React.createElement("div", { className: classNames.commentText }, comments);
}
return null;
};
_this._onRenderTimeStamp = function (props) {
var classNames = _this._getClassNames(props);
if (!props.isCompact && props.timeStamp) {
return React.createElement("div", { className: classNames.timeStamp }, props.timeStamp);
}
return null;
};
// If activityPersonas is an array of persona props, build the persona cluster element.
_this._onRenderPersonaArray = function (props) {
var classNames = _this._getClassNames(props);
var personaElement = null;
var activityPersonas = props.activityPersonas;
if (activityPersonas[0].imageUrl || activityPersonas[0].imageInitials) {
var personaList_1 = [];
var showSize16Personas_1 = activityPersonas.length > 1 || props.isCompact;
var personaLimit_1 = props.isCompact ? 3 : 4;
var style_1 = undefined;
if (props.isCompact) {
style_1 = {
display: 'inline-block',
width: '10px',
minWidth: '10px',
overflow: 'visible',
};
}
activityPersonas
.filter(function (person, index) { return index < personaLimit_1; })
.forEach(function (person, index) {
personaList_1.push(React.createElement(PersonaCoin, __assign({}, person, { key: person.key || index, className: classNames.activityPersona,
// eslint-disable-next-line @typescript-eslint/no-deprecated
size: showSize16Personas_1 ? PersonaSize.size16 : PersonaSize.size32, style: style_1 })));
});
personaElement = React.createElement("div", { className: classNames.personaContainer }, personaList_1);
}
return personaElement;
};
return _this;
}
ActivityItem.prototype.render = function () {
var _a = this.props, _b = _a.onRenderIcon, onRenderIcon = _b === void 0 ? this._onRenderIcon : _b, _c = _a.onRenderActivityDescription, onRenderActivityDescription = _c === void 0 ? this._onRenderActivityDescription : _c, _d = _a.onRenderComments, onRenderComments = _d === void 0 ? this._onRenderComments : _d, _e = _a.onRenderTimeStamp, onRenderTimeStamp = _e === void 0 ? this._onRenderTimeStamp : _e, animateBeaconSignal = _a.animateBeaconSignal, isCompact = _a.isCompact;
var classNames = this._getClassNames(this.props);
return (React.createElement("div", { className: classNames.root, style: this.props.style },
(this.props.activityPersonas || this.props.activityIcon || this.props.onRenderIcon) && (React.createElement("div", { className: classNames.activityTypeIcon },
animateBeaconSignal && isCompact && React.createElement("div", { className: classNames.pulsingBeacon }),
onRenderIcon(this.props))),
React.createElement("div", { className: classNames.activityContent },
onRenderActivityDescription(this.props, this._onRenderActivityDescription),
onRenderComments(this.props, this._onRenderComments),
onRenderTimeStamp(this.props, this._onRenderTimeStamp))));
};
ActivityItem.prototype._getClassNames = function (props) {
return getClassNames(getStyles(undefined, props.styles, props.animateBeaconSignal, props.beaconColorOne, props.beaconColorTwo, props.isCompact), props.className, props.activityPersonas, props.isCompact);
};
return ActivityItem;
}(React.Component));
export { ActivityItem };
//# sourceMappingURL=ActivityItem.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
import type { ITheme } from '../../Styling';
import type { IActivityItemStyles, IActivityItemProps } from './ActivityItem.types';
export declare const getStyles: (theme?: ITheme, customStyles?: IActivityItemStyles, animateBeaconSignal?: IActivityItemProps["animateBeaconSignal"], beaconColorOne?: IActivityItemProps["beaconColorOne"], beaconColorTwo?: IActivityItemProps["beaconColorTwo"], isCompact?: IActivityItemProps["isCompact"]) => IActivityItemStyles;
@@ -0,0 +1,173 @@
import { __rest } from "tslib";
import { concatStyleSets, getTheme, HighContrastSelector, keyframes, PulsingBeaconAnimationStyles, } from '../../Styling';
import { memoizeFunction } from '../../Utilities';
var DEFAULT_PERSONA_SIZE = '32px';
var COMPACT_PERSONA_SIZE = '16px';
var DEFAULT_ICON_SIZE = '16px';
var COMPACT_ICON_SIZE = '13px';
var ANIMATION_INNER_DIMENSION = '4px';
var ANIMATION_OUTER_DIMENSION = '28px';
var ANIMATION_BORDER_WIDTH = '4px';
var fadeIn = memoizeFunction(function () {
return keyframes({
from: { opacity: 0 },
to: { opacity: 1 },
});
});
var slideIn = memoizeFunction(function () {
return keyframes({
from: { transform: 'translateX(-10px)' },
to: { transform: 'translateX(0)' },
});
});
export var getStyles = memoizeFunction(function (theme, customStyles, animateBeaconSignal, beaconColorOne, beaconColorTwo, isCompact) {
var _a;
if (theme === void 0) { theme = getTheme(); }
var continuousPulse = PulsingBeaconAnimationStyles.continuousPulseAnimationSingle(beaconColorOne ? beaconColorOne : theme.palette.themePrimary, beaconColorTwo ? beaconColorTwo : theme.palette.themeTertiary, ANIMATION_INNER_DIMENSION, ANIMATION_OUTER_DIMENSION, ANIMATION_BORDER_WIDTH);
var continuousPulseAnimation = {
animationName: continuousPulse,
animationIterationCount: '1',
animationDuration: '.8s',
zIndex: 1,
};
var slideInAnimation = {
animationName: slideIn(),
animationIterationCount: '1',
animationDuration: '.5s',
};
var fadeInAnimation = {
animationName: fadeIn(),
animationIterationCount: '1',
animationDuration: '.5s',
};
var ActivityItemStyles = {
root: [
theme.fonts.small,
{
display: 'flex',
justifyContent: 'flex-start',
alignItems: 'flex-start',
boxSizing: 'border-box',
color: theme.palette.neutralSecondary,
},
isCompact && animateBeaconSignal && fadeInAnimation,
],
pulsingBeacon: [
{
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: '0px',
height: '0px',
borderRadius: '225px',
borderStyle: 'solid',
opacity: 0,
},
isCompact && animateBeaconSignal && continuousPulseAnimation,
],
isCompactRoot: {
alignItems: 'center',
},
personaContainer: {
display: 'flex',
flexWrap: 'wrap',
minWidth: DEFAULT_PERSONA_SIZE,
width: DEFAULT_PERSONA_SIZE,
height: DEFAULT_PERSONA_SIZE,
},
isCompactPersonaContainer: {
display: 'inline-flex',
flexWrap: 'nowrap',
flexBasis: 'auto',
height: COMPACT_PERSONA_SIZE,
width: 'auto',
minWidth: '0',
paddingRight: '6px',
},
activityTypeIcon: {
height: DEFAULT_PERSONA_SIZE,
fontSize: DEFAULT_ICON_SIZE,
lineHeight: DEFAULT_ICON_SIZE,
marginTop: '3px',
},
isCompactIcon: {
height: COMPACT_PERSONA_SIZE,
minWidth: COMPACT_PERSONA_SIZE,
fontSize: COMPACT_ICON_SIZE,
lineHeight: COMPACT_ICON_SIZE,
color: theme.palette.themePrimary,
marginTop: '1px',
position: 'relative',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
selectors: {
'.ms-Persona-imageArea': {
margin: '-2px 0 0 -2px',
border: '2px solid' + theme.palette.white,
borderRadius: '50%',
selectors: (_a = {},
_a[HighContrastSelector] = {
border: 'none',
margin: '0',
},
_a),
},
},
},
activityPersona: {
display: 'block',
},
doublePersona: {
selectors: {
':first-child': {
alignSelf: 'flex-end',
},
},
},
isCompactPersona: {
display: 'inline-block',
width: '8px',
minWidth: '8px',
overflow: 'visible',
},
activityContent: [
{
padding: '0 8px',
},
isCompact && animateBeaconSignal && slideInAnimation,
],
activityText: {
display: 'inline',
},
isCompactContent: {
flex: '1',
padding: '0 4px',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
overflowX: 'hidden',
},
commentText: {
color: theme.palette.neutralPrimary,
},
timeStamp: [
theme.fonts.tiny,
{
fontWeight: 400,
color: theme.palette.neutralSecondary,
},
],
isCompactTimeStamp: {
display: 'inline-block',
paddingLeft: '0.3em', // One space character
fontSize: '1em',
},
};
var _b = customStyles || {}, __shadowConfig__ = _b.__shadowConfig__, restStyles = __rest(_b, ["__shadowConfig__"]);
if (__shadowConfig__) {
return concatStyleSets(__shadowConfig__, ActivityItemStyles, restStyles);
}
return concatStyleSets(ActivityItemStyles, customStyles);
});
//# sourceMappingURL=ActivityItem.styles.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,149 @@
import * as React from 'react';
import type { IShadowDomStyle, IStyle } from '../../Styling';
import type { IRenderFunction } from '../../Utilities';
import type { IPersonaSharedProps } from '../../Persona';
/**
* {@docCategory ActivityItem}
*/
export interface IActivityItemProps extends React.AllHTMLAttributes<HTMLElement> {
/**
* An element describing the activity that took place. If no `activityDescription`, `activityDescriptionText`, or
* `onRenderActivityDescription` are included, no description of the activity is shown.
*/
activityDescription?: React.ReactNode[] | React.ReactNode;
/**
* Text describing the activity that occurred and naming the people involved in it.
* @deprecated Use `activityDescription` instead.
*/
activityDescriptionText?: string;
/**
* An element containing an icon shown next to the activity item.
*/
activityIcon?: React.ReactNode;
/**
* If `activityIcon` is not set, the personas in this array will be used as the icon for the this activity item.
*/
activityPersonas?: IPersonaSharedProps[];
/**
* An element containing the text of comments or \@mention messages.
* If no `comments`, `commentText`, or `onRenderComments` are included, no comments are shown.
*/
comments?: React.ReactNode[] | React.ReactNode;
/**
* Text of comments or \@mention messages.
* @deprecated Use `comments` instead.
*/
commentText?: string;
/**
* Indicated if the compact styling should be used.
*/
isCompact?: boolean;
/**
* A renderer for the description of the current activity.
*/
onRenderActivityDescription?: IRenderFunction<IActivityItemProps>;
/**
* A renderer that adds the text of a comment below the activity description.
*/
onRenderComments?: IRenderFunction<IActivityItemProps>;
/**
* A renderer to create the icon next to the activity item.
*/
onRenderIcon?: IRenderFunction<IActivityItemProps>;
/**
* Custom renderer for a time stamp. If not included, `timeStamp` is shown as plain text below the activity.
*/
onRenderTimeStamp?: IRenderFunction<IActivityItemProps>;
/**
* Optional styling for the elements within the activity item.
*/
styles?: IActivityItemStyles;
/**
* Element shown as a timestamp on this activity. If not included, no timestamp is shown.
*/
timeStamp?: string | React.ReactNode[] | React.ReactNode;
/**
* Beacon color one
*/
beaconColorOne?: string;
/**
* Beacon color two
*/
beaconColorTwo?: string;
/**
* Enables/disables the beacon that radiates from the center of the center of the activity icon.
* Signals an activity has started.
* @defaultvalue false
*/
animateBeaconSignal?: boolean;
}
/**
* {@docCategory ActivityItem}
*/
export interface IActivityItemStyles extends IShadowDomStyle {
/**
* Styles applied to the root activity item container.
*/
root?: IStyle;
/**
* Styles applied to the root activity item container.
*/
pulsingBeacon?: IStyle;
/**
* Styles applied to the main container of the activity's description.
*/
activityContent?: IStyle;
/**
* Styles applied to the persona of the user that did this activity.
*/
activityPersona?: IStyle;
/**
* Styles applied to the activity's description.
*/
activityText?: IStyle;
/**
* Styles applied to the icon indicating the type of the activity. Only shown when personas are unavailable.
*/
activityTypeIcon?: IStyle;
/**
* Styles applied to the text of comments.
*/
commentText?: IStyle;
/**
* Styles applied to personas when two users are involved in a single activity.
*/
doublePersona?: IStyle;
/**
* Styles applied to root in the compact variant.
*/
isCompactRoot?: IStyle;
/**
* Styles applied to personas and icons in the compact variant.
*/
isCompactIcon?: IStyle;
/**
* Styles applied to main text container in the compact variant.
*/
isCompactContent?: IStyle;
/**
* Styles applied to personas in the compact variant.
*/
isCompactPersona?: IStyle;
/**
* Styles applied to a wrapper around personas in the compact variant.
*/
isCompactPersonaContainer?: IStyle;
/**
* Styles applied to the container of the persona image or activity type icon.
*/
personaContainer?: IStyle;
/**
* Styles applied to the timestamp at the end of each activity item.
*/
timeStamp?: IStyle;
/**
* Styles applied to the timestamp in compact mode.
* This can occur if a host overrides the render behavior to force the timestamp to render.
*/
isCompactTimeStamp?: IStyle;
}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=ActivityItem.types.js.map
File diff suppressed because one or more lines are too long
+5
View File
@@ -0,0 +1,5 @@
export { getStyles as getActivityItemStyles } from './ActivityItem.styles';
export { getClassNames as getActivityItemClassNames } from './ActivityItem.classNames';
export type { IActivityItemClassNames } from './ActivityItem.classNames';
export * from './ActivityItem';
export * from './ActivityItem.types';
+5
View File
@@ -0,0 +1,5 @@
export { getStyles as getActivityItemStyles } from './ActivityItem.styles';
export { getClassNames as getActivityItemClassNames } from './ActivityItem.classNames';
export * from './ActivityItem';
export * from './ActivityItem.types';
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["components/ActivityItem/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,aAAa,IAAI,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAGvF,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC","sourcesContent":["export { getStyles as getActivityItemStyles } from './ActivityItem.styles';\nexport { getClassNames as getActivityItemClassNames } from './ActivityItem.classNames';\nexport type { IActivityItemClassNames } from './ActivityItem.classNames';\n\nexport * from './ActivityItem';\nexport * from './ActivityItem.types';\n"]}
@@ -0,0 +1,10 @@
import * as React from 'react';
import type { IAnnouncedProps } from './Announced.types';
import type { JSXElement } from '@fluentui/utilities';
/**
* {@docCategory Announced}
*/
export declare class AnnouncedBase extends React.Component<IAnnouncedProps> {
static defaultProps: Partial<IAnnouncedProps>;
render(): JSXElement;
}
@@ -0,0 +1,26 @@
import { __assign, __extends } from "tslib";
import * as React from 'react';
import { DelayedRender, classNamesFunction, getNativeProps, divProperties } from '../../Utilities';
var getClassNames = classNamesFunction();
/**
* {@docCategory Announced}
*/
var AnnouncedBase = /** @class */ (function (_super) {
__extends(AnnouncedBase, _super);
function AnnouncedBase() {
return _super !== null && _super.apply(this, arguments) || this;
}
AnnouncedBase.prototype.render = function () {
var _a = this.props, message = _a.message, styles = _a.styles, _b = _a.as, Root = _b === void 0 ? 'div' : _b, className = _a.className;
var classNames = getClassNames(styles, { className: className });
return (React.createElement(Root, __assign({ role: "status", className: classNames.root }, getNativeProps(this.props, divProperties, ['className'])),
React.createElement(DelayedRender, null,
React.createElement("div", { className: classNames.screenReaderText }, message))));
};
AnnouncedBase.defaultProps = {
'aria-live': 'polite',
};
return AnnouncedBase;
}(React.Component));
export { AnnouncedBase };
//# sourceMappingURL=Announced.base.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Announced.base.js","sourceRoot":"../src/","sources":["components/Announced/Announced.base.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKnG,IAAM,aAAa,GAAG,kBAAkB,EAAwB,CAAC;AAEjE;;GAEG;AACH;IAAmC,iCAAgC;IAAnE;;IAkBA,CAAC;IAbQ,8BAAM,GAAb;QACQ,IAAA,KAAmD,IAAI,CAAC,KAAK,EAA3D,OAAO,aAAA,EAAE,MAAM,YAAA,EAAE,UAAgB,EAAZ,IAAI,mBAAG,KAAK,KAAA,EAAE,SAAS,eAAe,CAAC;QAEpE,IAAM,UAAU,GAAG,aAAa,CAAC,MAAM,EAAE,EAAE,SAAS,WAAA,EAAE,CAAC,CAAC;QAExD,OAAO,CACL,oBAAC,IAAI,aAAC,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAE,UAAU,CAAC,IAAI,IAAM,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC,WAAW,CAAC,CAAC;YAC1G,oBAAC,aAAa;gBACZ,6BAAK,SAAS,EAAE,UAAU,CAAC,gBAAgB,IAAG,OAAO,CAAO,CAC9C,CACX,CACR,CAAC;IACJ,CAAC;IAhBa,0BAAY,GAA6B;QACrD,WAAW,EAAE,QAAQ;KACtB,CAAC;IAeJ,oBAAC;CAAA,AAlBD,CAAmC,KAAK,CAAC,SAAS,GAkBjD;SAlBY,aAAa","sourcesContent":["import * as React from 'react';\nimport { DelayedRender, classNamesFunction, getNativeProps, divProperties } from '../../Utilities';\nimport type { IAnnouncedProps, IAnnouncedStyles } from './Announced.types';\n\nimport type { JSXElement } from '@fluentui/utilities';\n\nconst getClassNames = classNamesFunction<{}, IAnnouncedStyles>();\n\n/**\n * {@docCategory Announced}\n */\nexport class AnnouncedBase extends React.Component<IAnnouncedProps> {\n public static defaultProps: Partial<IAnnouncedProps> = {\n 'aria-live': 'polite',\n };\n\n public render(): JSXElement {\n const { message, styles, as: Root = 'div', className } = this.props;\n\n const classNames = getClassNames(styles, { className });\n\n return (\n <Root role=\"status\" className={classNames.root} {...getNativeProps(this.props, divProperties, ['className'])}>\n <DelayedRender>\n <div className={classNames.screenReaderText}>{message}</div>\n </DelayedRender>\n </Root>\n );\n }\n}\n"]}
+3
View File
@@ -0,0 +1,3 @@
import * as React from 'react';
import type { IAnnouncedProps } from './Announced.types';
export declare const Announced: React.FunctionComponent<IAnnouncedProps>;
+5
View File
@@ -0,0 +1,5 @@
import { styled } from '../../Utilities';
import { AnnouncedBase } from './Announced.base';
import { getStyles } from './Announced.styles';
export var Announced = styled(AnnouncedBase, getStyles, undefined, { scope: 'Announced' });
//# sourceMappingURL=Announced.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Announced.js","sourceRoot":"../src/","sources":["components/Announced/Announced.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,MAAM,CAAC,IAAM,SAAS,GAA6C,MAAM,CACvE,aAAa,EACb,SAAS,EACT,SAAS,EACT,EAAE,KAAK,EAAE,WAAW,EAAE,CACvB,CAAC","sourcesContent":["import * as React from 'react';\nimport { styled } from '../../Utilities';\nimport { AnnouncedBase } from './Announced.base';\nimport { getStyles } from './Announced.styles';\nimport type { IAnnouncedProps, IAnnouncedStyles } from './Announced.types';\n\nexport const Announced: React.FunctionComponent<IAnnouncedProps> = styled<IAnnouncedProps, {}, IAnnouncedStyles>(\n AnnouncedBase,\n getStyles,\n undefined,\n { scope: 'Announced' },\n);\n"]}
@@ -0,0 +1,3 @@
import type { IStyleFunction } from '../../Utilities';
import type { IAnnouncedStyles, IAnnouncedStyleProps } from './Announced.types';
export declare const getStyles: IStyleFunction<IAnnouncedStyleProps, IAnnouncedStyles>;
@@ -0,0 +1,8 @@
import { hiddenContentStyle } from '../../Styling';
export var getStyles = function (props) {
return {
root: props.className,
screenReaderText: hiddenContentStyle,
};
};
//# sourceMappingURL=Announced.styles.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Announced.styles.js","sourceRoot":"../src/","sources":["components/Announced/Announced.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAInD,MAAM,CAAC,IAAM,SAAS,GAA2D,UAAA,KAAK;IACpF,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,SAAS;QACrB,gBAAgB,EAAE,kBAAkB;KACrC,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { hiddenContentStyle } from '../../Styling';\nimport type { IStyleFunction } from '../../Utilities';\nimport type { IAnnouncedStyles, IAnnouncedStyleProps } from './Announced.types';\n\nexport const getStyles: IStyleFunction<IAnnouncedStyleProps, IAnnouncedStyles> = props => {\n return {\n root: props.className,\n screenReaderText: hiddenContentStyle,\n };\n};\n"]}
@@ -0,0 +1,43 @@
import * as React from 'react';
import { AnnouncedBase } from './Announced.base';
import type { IStyle } from '../../Styling';
import type { IReactProps, IStyleFunctionOrObject } from '../../Utilities';
/**
* {@docCategory Announced}
*/
export interface IAnnouncedProps extends IReactProps<AnnouncedBase>, React.HTMLAttributes<HTMLDivElement> {
/**
* The status message the screen reader should announce.
*/
message?: string;
/**
* Priority with which the screen reader should treat updates to this region.
* @default 'polite'
*/
'aria-live'?: 'off' | 'polite' | 'assertive';
/**
* Optionally render the root of this component as another component type or primitive.
* The custom type **must** preserve any children or native props passed in.
* @default 'div'
*/
as?: React.ElementType;
/** Call to provide customized styling that will layer on top of the variant rules. */
styles?: IStyleFunctionOrObject<{}, IAnnouncedStyles>;
}
/**
* {@docCategory Announced}
*/
export type IAnnouncedStyleProps = Pick<IAnnouncedProps, 'className'>;
/**
* {@docCategory Announced}
*/
export interface IAnnouncedStyles {
/**
* Style override for the root element.
*/
root: IStyle;
/**
* Style override for the screen reader text.
*/
screenReaderText: IStyle;
}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=Announced.types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Announced.types.js","sourceRoot":"../src/","sources":["components/Announced/Announced.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { AnnouncedBase } from './Announced.base';\nimport type { IStyle } from '../../Styling';\nimport type { IReactProps, IStyleFunctionOrObject } from '../../Utilities';\n\n/**\n * {@docCategory Announced}\n */\nexport interface IAnnouncedProps extends IReactProps<AnnouncedBase>, React.HTMLAttributes<HTMLDivElement> {\n /**\n * The status message the screen reader should announce.\n */\n message?: string;\n\n /**\n * Priority with which the screen reader should treat updates to this region.\n * @default 'polite'\n */\n 'aria-live'?: 'off' | 'polite' | 'assertive';\n\n /**\n * Optionally render the root of this component as another component type or primitive.\n * The custom type **must** preserve any children or native props passed in.\n * @default 'div'\n */\n as?: React.ElementType;\n\n /** Call to provide customized styling that will layer on top of the variant rules. */\n styles?: IStyleFunctionOrObject<{}, IAnnouncedStyles>;\n}\n\n/**\n * {@docCategory Announced}\n */\nexport type IAnnouncedStyleProps = Pick<IAnnouncedProps, 'className'>;\n\n/**\n * {@docCategory Announced}\n */\nexport interface IAnnouncedStyles {\n /**\n * Style override for the root element.\n */\n root: IStyle;\n\n /**\n * Style override for the screen reader text.\n */\n screenReaderText: IStyle;\n}\n"]}
+3
View File
@@ -0,0 +1,3 @@
export * from './Announced';
export * from './Announced.base';
export * from './Announced.types';
+4
View File
@@ -0,0 +1,4 @@
export * from './Announced';
export * from './Announced.base';
export * from './Announced.types';
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["components/Announced/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC","sourcesContent":["export * from './Announced';\nexport * from './Announced.base';\nexport * from './Announced.types';\n"]}
+68
View File
@@ -0,0 +1,68 @@
import * as React from 'react';
import { KeyCodes } from '../../Utilities';
import type { IAutofill, IAutofillProps } from './Autofill.types';
import type { JSXElement } from '@fluentui/utilities';
export interface IAutofillState {
inputValue: string;
isComposing: boolean;
}
interface ICursorLocation {
start: number;
end: number;
dir: 'forward' | 'backward' | 'none' | undefined;
}
/**
* {@docCategory Autofill}
*/
export declare class Autofill extends React.Component<IAutofillProps, IAutofillState> implements IAutofill {
static defaultProps: {
enableAutofillOnKeyPress: KeyCodes[];
};
static contextType: React.Context<import("@fluentui/react-window-provider").WindowProviderProps>;
context: any;
private _inputElement;
private _autoFillEnabled;
private _async;
static getDerivedStateFromProps(props: IAutofillProps, state: IAutofillState): IAutofillState | null;
constructor(props: IAutofillProps);
get cursorLocation(): number | null;
get isValueSelected(): boolean;
get value(): string;
get selectionStart(): number | null;
get selectionEnd(): number | null;
get inputElement(): HTMLInputElement | null;
componentDidUpdate(_: any, _1: any, cursor: ICursorLocation | null): void;
componentWillUnmount(): void;
render(): JSXElement;
focus(): void;
clear(): void;
getSnapshotBeforeUpdate(): ICursorLocation | null;
private _onCompositionStart;
private _onCompositionUpdate;
private _onCompositionEnd;
private _onClick;
private _onKeyDown;
private _onInputChanged;
private _onChanged;
private _getCurrentInputValue;
/**
* Attempts to enable autofill. Whether or not autofill is enabled depends on the input value,
* whether or not any text is selected, and only if the new input value is longer than the old input value.
* Autofill should never be set to true if the value is composing. Once compositionEnd is called, then
* it should be completed.
* See https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent for more information on composition.
* @param newValue - new input value
* @param oldValue - old input value
* @param isComposing - if true then the text is actively being composed and it has not completed.
* @param isComposed - if the text is a composed text value.
*/
private _tryEnableAutofill;
/**
* Updates the current input value as well as getting a new display value.
* @param newValue - The new value from the input
*/
private _updateValue;
private _getDisplayValue;
private _getControlledValue;
}
export {};
+343
View File
@@ -0,0 +1,343 @@
import { __assign, __extends } from "tslib";
import * as React from 'react';
import { Async, getDocument, getNativeProps, initializeComponentRef, inputProperties, isIE11, KeyCodes, } from '../../Utilities';
import { WindowContext } from '@fluentui/react-window-provider';
var SELECTION_FORWARD = 'forward';
var SELECTION_BACKWARD = 'backward';
/**
* {@docCategory Autofill}
*/
var Autofill = /** @class */ (function (_super) {
__extends(Autofill, _super);
function Autofill(props) {
var _this = _super.call(this, props) || this;
_this._inputElement = React.createRef();
_this._autoFillEnabled = true;
// Composition events are used when the character/text requires several keystrokes to be completed.
// Some examples of this are mobile text input and languages like Japanese or Arabic.
// Find out more at https://developer.mozilla.org/en-US/docs/Web/Events/compositionstart
_this._onCompositionStart = function (ev) {
_this.setState({ isComposing: true });
_this._autoFillEnabled = false;
};
// Composition events are used when the character/text requires several keystrokes to be completed.
// Some examples of this are mobile text input and languages like Japanese or Arabic.
// Find out more at https://developer.mozilla.org/en-US/docs/Web/Events/compositionstart
_this._onCompositionUpdate = function () {
if (isIE11()) {
_this._updateValue(_this._getCurrentInputValue(), true);
}
};
// Composition events are used when the character/text requires several keystrokes to be completed.
// Some examples of this are mobile text input and languages like Japanese or Arabic.
// Find out more at https://developer.mozilla.org/en-US/docs/Web/Events/compositionstart
_this._onCompositionEnd = function (ev) {
var inputValue = _this._getCurrentInputValue();
_this._tryEnableAutofill(inputValue, _this.value, false, true);
_this.setState({ isComposing: false });
// Due to timing, this needs to be async, otherwise no text will be selected.
_this._async.setTimeout(function () {
// it's technically possible that the value of isComposing is reset during this timeout,
// so explicitly trigger this with composing=true here, since it is supposed to be the
// update for composition end
_this._updateValue(_this._getCurrentInputValue(), false);
}, 0);
};
_this._onClick = function () {
if (_this.value && _this.value !== '' && _this._autoFillEnabled) {
_this._autoFillEnabled = false;
}
};
_this._onKeyDown = function (ev) {
if (_this.props.onKeyDown) {
_this.props.onKeyDown(ev);
}
// If the event is actively being composed, then don't alert autofill.
// Right now typing does not have isComposing, once that has been fixed any should be removed.
if (!ev.nativeEvent.isComposing) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
switch (ev.which) {
case KeyCodes.backspace:
_this._autoFillEnabled = false;
break;
case KeyCodes.left:
case KeyCodes.right:
if (_this._autoFillEnabled) {
_this.setState(function (prev) { return ({
inputValue: _this.props.suggestedDisplayValue || prev.inputValue,
}); });
_this._autoFillEnabled = false;
}
break;
default:
if (!_this._autoFillEnabled) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
if (_this.props.enableAutofillOnKeyPress.indexOf(ev.which) !== -1) {
_this._autoFillEnabled = true;
}
}
break;
}
}
};
_this._onInputChanged = function (ev) {
var value = _this._getCurrentInputValue(ev);
if (!_this.state.isComposing) {
_this._tryEnableAutofill(value, _this.value, ev.nativeEvent.isComposing);
}
// If it is not IE11 and currently composing, update the value
if (!(isIE11() && _this.state.isComposing)) {
var nativeEventComposing = ev.nativeEvent.isComposing;
var isComposing = nativeEventComposing === undefined ? _this.state.isComposing : nativeEventComposing;
_this._updateValue(value, isComposing);
}
};
_this._onChanged = function () {
// Swallow this event, we don't care about it
// We must provide it because React PropTypes marks it as required, but onInput serves the correct purpose
return;
};
/**
* Updates the current input value as well as getting a new display value.
* @param newValue - The new value from the input
*/
_this._updateValue = function (newValue, composing) {
// Only proceed if the value is nonempty and is different from the old value
// This is to work around the fact that, in IE 11, inputs with a placeholder fire an onInput event on focus
if (!newValue && newValue === _this.value) {
return;
}
// eslint-disable-next-line @typescript-eslint/no-deprecated
var _a = _this.props, onInputChange = _a.onInputChange, onInputValueChange = _a.onInputValueChange;
if (onInputChange) {
newValue = (onInputChange === null || onInputChange === void 0 ? void 0 : onInputChange(newValue, composing)) || '';
}
_this.setState({ inputValue: newValue }, function () { return onInputValueChange === null || onInputValueChange === void 0 ? void 0 : onInputValueChange(newValue, composing); });
};
initializeComponentRef(_this);
_this._async = new Async(_this);
_this.state = {
inputValue: props.defaultVisibleValue || '',
isComposing: false,
};
return _this;
}
Autofill.getDerivedStateFromProps = function (props, state) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
if (props.updateValueInWillReceiveProps) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
var updatedInputValue = props.updateValueInWillReceiveProps();
// Don't update if we have a null value or the value isn't changing
// the value should still update if an empty string is passed in
if (updatedInputValue !== null && updatedInputValue !== state.inputValue && !state.isComposing) {
return __assign(__assign({}, state), { inputValue: updatedInputValue });
}
}
return null;
};
Object.defineProperty(Autofill.prototype, "cursorLocation", {
get: function () {
if (this._inputElement.current) {
var inputElement = this._inputElement.current;
if (inputElement.selectionDirection !== SELECTION_FORWARD) {
return inputElement.selectionEnd;
}
else {
return inputElement.selectionStart;
}
}
else {
return -1;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Autofill.prototype, "isValueSelected", {
get: function () {
return Boolean(this.inputElement && this.inputElement.selectionStart !== this.inputElement.selectionEnd);
},
enumerable: false,
configurable: true
});
Object.defineProperty(Autofill.prototype, "value", {
get: function () {
return this._getControlledValue() || this.state.inputValue || '';
},
enumerable: false,
configurable: true
});
Object.defineProperty(Autofill.prototype, "selectionStart", {
get: function () {
return this._inputElement.current ? this._inputElement.current.selectionStart : -1;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Autofill.prototype, "selectionEnd", {
get: function () {
return this._inputElement.current ? this._inputElement.current.selectionEnd : -1;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Autofill.prototype, "inputElement", {
get: function () {
return this._inputElement.current;
},
enumerable: false,
configurable: true
});
Autofill.prototype.componentDidUpdate = function (_, _1, cursor) {
var _a;
var _b = this.props, suggestedDisplayValue = _b.suggestedDisplayValue, shouldSelectFullInputValueInComponentDidUpdate = _b.shouldSelectFullInputValueInComponentDidUpdate, preventValueSelection = _b.preventValueSelection;
var differenceIndex = 0;
if (preventValueSelection) {
return;
}
var document = ((_a = this.context) === null || _a === void 0 ? void 0 : _a.window.document) || getDocument(this._inputElement.current);
var isFocused = this._inputElement.current && this._inputElement.current === (document === null || document === void 0 ? void 0 : document.activeElement);
if (isFocused &&
this._autoFillEnabled &&
this.value &&
suggestedDisplayValue &&
_doesTextStartWith(suggestedDisplayValue, this.value)) {
var shouldSelectFullRange = false;
if (shouldSelectFullInputValueInComponentDidUpdate) {
shouldSelectFullRange = shouldSelectFullInputValueInComponentDidUpdate();
}
if (shouldSelectFullRange) {
this._inputElement.current.setSelectionRange(0, suggestedDisplayValue.length, SELECTION_BACKWARD);
}
else {
while (differenceIndex < this.value.length &&
this.value[differenceIndex].toLocaleLowerCase() === suggestedDisplayValue[differenceIndex].toLocaleLowerCase()) {
differenceIndex++;
}
if (differenceIndex > 0) {
this._inputElement.current.setSelectionRange(differenceIndex, suggestedDisplayValue.length, SELECTION_BACKWARD);
}
}
}
else if (this._inputElement.current) {
if (cursor !== null && !this._autoFillEnabled && !this.state.isComposing) {
this._inputElement.current.setSelectionRange(cursor.start, cursor.end, cursor.dir);
}
}
};
Autofill.prototype.componentWillUnmount = function () {
this._async.dispose();
};
Autofill.prototype.render = function () {
var nativeProps = getNativeProps(this.props, inputProperties);
var style = __assign(__assign({}, this.props.style), { fontFamily: 'inherit' });
return (React.createElement("input", __assign({ autoCapitalize: "off", autoComplete: "off", "aria-autocomplete": 'both' }, nativeProps, { style: style, ref: this._inputElement, value: this._getDisplayValue(), onCompositionStart: this._onCompositionStart, onCompositionUpdate: this._onCompositionUpdate, onCompositionEnd: this._onCompositionEnd,
// TODO (Fabric 8?) - switch to calling only onChange. See notes in TextField._onInputChange.
onChange: this._onChanged, onInput: this._onInputChanged, onKeyDown: this._onKeyDown, onClick: this.props.onClick ? this.props.onClick : this._onClick, "data-lpignore": true })));
};
Autofill.prototype.focus = function () {
this._inputElement.current && this._inputElement.current.focus();
};
Autofill.prototype.clear = function () {
this._autoFillEnabled = true;
this._updateValue('', false);
this._inputElement.current && this._inputElement.current.setSelectionRange(0, 0);
};
Autofill.prototype.getSnapshotBeforeUpdate = function () {
var _a, _b;
var inel = this._inputElement.current;
if (inel && inel.selectionStart !== this.value.length) {
return {
start: (_a = inel.selectionStart) !== null && _a !== void 0 ? _a : inel.value.length,
end: (_b = inel.selectionEnd) !== null && _b !== void 0 ? _b : inel.value.length,
dir: inel.selectionDirection || 'backward' || 'none',
};
}
return null;
};
Autofill.prototype._getCurrentInputValue = function (ev) {
if (ev && ev.target && ev.target.value) {
return ev.target.value;
}
else if (this.inputElement && this.inputElement.value) {
return this.inputElement.value;
}
else {
return '';
}
};
/**
* Attempts to enable autofill. Whether or not autofill is enabled depends on the input value,
* whether or not any text is selected, and only if the new input value is longer than the old input value.
* Autofill should never be set to true if the value is composing. Once compositionEnd is called, then
* it should be completed.
* See https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent for more information on composition.
* @param newValue - new input value
* @param oldValue - old input value
* @param isComposing - if true then the text is actively being composed and it has not completed.
* @param isComposed - if the text is a composed text value.
*/
Autofill.prototype._tryEnableAutofill = function (newValue, oldValue, isComposing, isComposed) {
if (!isComposing &&
newValue &&
this._inputElement.current &&
this._inputElement.current.selectionStart === newValue.length &&
!this._autoFillEnabled &&
(newValue.length > oldValue.length || isComposed)) {
this._autoFillEnabled = true;
}
};
Autofill.prototype._getDisplayValue = function () {
if (this._autoFillEnabled) {
return _getDisplayValue(this.value, this.props.suggestedDisplayValue);
}
return this.value;
};
Autofill.prototype._getControlledValue = function () {
var value = this.props.value;
if (value === undefined || typeof value === 'string') {
return value;
}
// eslint-disable-next-line no-console
console.warn("props.value of Autofill should be a string, but it is ".concat(value, " with type of ").concat(typeof value));
return value.toString();
};
Autofill.defaultProps = {
enableAutofillOnKeyPress: [KeyCodes.down, KeyCodes.up],
};
// need to check WindowContext to get the provided document
Autofill.contextType = WindowContext;
return Autofill;
}(React.Component));
export { Autofill };
/**
* Returns a string that should be used as the display value.
* It evaluates this based on whether or not the suggested value starts with the input value
* and whether or not autofill is enabled.
* @param inputValue - the value that the input currently has.
* @param suggestedDisplayValue - the possible full value
*/
function _getDisplayValue(inputValue, suggestedDisplayValue) {
var displayValue = inputValue;
if (suggestedDisplayValue && inputValue && _doesTextStartWith(suggestedDisplayValue, displayValue)) {
displayValue = suggestedDisplayValue;
}
return displayValue;
}
function _doesTextStartWith(text, startWith) {
if (!text || !startWith) {
return false;
}
if (process.env.NODE_ENV !== 'production') {
for (var _i = 0, _a = [text, startWith]; _i < _a.length; _i++) {
var val = _a[_i];
if (typeof val !== 'string') {
throw new Error("".concat(Autofill.name
// eslint-disable-next-line @fluentui/max-len
, " received non-string value \"").concat(val, "\" of type ").concat(typeof val, " from either input's value or suggestedDisplayValue"));
}
}
}
return text.toLocaleLowerCase().indexOf(startWith.toLocaleLowerCase()) === 0;
}
//# sourceMappingURL=Autofill.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,110 @@
import * as React from 'react';
import { Autofill } from './Autofill';
import { KeyCodes } from '../../Utilities';
import type { IRefObject } from '../../Utilities';
/**
* {@docCategory Autofill}
*/
export interface IAutofill {
/**
* The current index of the cursor in the input area. Returns -1 if the input element
* is not ready.
*/
cursorLocation: number | null;
/**
* Whether there is a value selected in the input area.
*/
isValueSelected: boolean;
/**
* The current text value that the user has entered.
*/
value: string;
/**
* The current index of where the selection starts. Returns -1 if the input element
* is not ready.
*/
selectionStart: number | null;
/**
* The current index of where the selection ends. Returns -1 if the input element
* is not ready.
*/
selectionEnd: number | null;
/**
* The current input element.
*/
inputElement: HTMLInputElement | null;
/**
* Focus the input element.
*/
focus(): void;
/**
* Clear all text in the input. Sets value to `''`.
*/
clear(): void;
}
/**
* {@docCategory Autofill}
*/
export interface IAutofillProps extends React.InputHTMLAttributes<HTMLInputElement | Autofill> {
/**
* Gets the component ref.
*/
componentRef?: IRefObject<IAutofill>;
/**
* The suggested autofill value that will display.
*/
suggestedDisplayValue?: string;
/**
* A callback for when the current input value changes. Called after
* the state has been changed.
*
* @param composing - true if the change event was triggered while the
* inner input was in the middle of a multi-character composition.
* (for example, jp-hiragana IME input)
*/
onInputValueChange?: (newValue?: string, composing?: boolean) => void;
/**
* When the user uses left arrow, right arrow, clicks, or deletes text, autofill is disabled
* since the user has taken control. It is automatically re-enabled when the user enters text and the
* cursor is at the end of the text in the input box. This prop can be used to override the
* default list of key presses that will re-enable autofill.
* @defaultvalue [KeyCodes.down, KeyCodes.up]
*/
enableAutofillOnKeyPress?: KeyCodes[];
/**
* The default value to be visible. This is different from placeholder
* because it actually sets the current value of the picker.
* Note: Updates to this prop will not be respected.
*/
defaultVisibleValue?: string;
/**
* Handler for checking and updating the value if needed in `componentWillReceiveProps`.
* Returns the updated value to set, if needed.
*
* @deprecated use standard input `value` prop instead if the autofill should act like a controlled component
*/
updateValueInWillReceiveProps?: () => string | null;
/**
* Handler for checking if the full value of the input should be selected in `componentDidUpdate`.
* Returns whether the full value of the input should be selected.
*/
shouldSelectFullInputValueInComponentDidUpdate?: () => boolean;
/**
* A callback used to modify the input string. Will entirely override the default behavior if provided.
* If you just want to be notified of changes, use `onInputValueChange` instead.
* Called before the state has been updated.
*
* @param composing - true if the change event was triggered while the
* inner input was in the middle of a multi-character composition.
* (for example, jp-hiragana IME input)
* @deprecated To control the value, pass in `value` like in any other controlled component.
* To be notified of changes, use `onInputValueChange`.
*/
onInputChange?: (value: string, composing: boolean) => string | void;
/**
* Should the value of the input be selected? True if we're focused on our input, false otherwise.
* We need to explicitly not select the text in the autofill if we are no longer focused.
* In IE11, selecting an input will also focus the input, causing other element's focus to be stolen.
*/
preventValueSelection?: boolean;
}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=Autofill.types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Autofill.types.js","sourceRoot":"../src/","sources":["components/Autofill/Autofill.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { Autofill } from './Autofill';\nimport { KeyCodes } from '../../Utilities';\nimport type { IRefObject } from '../../Utilities';\n\n/**\n * {@docCategory Autofill}\n */\nexport interface IAutofill {\n /**\n * The current index of the cursor in the input area. Returns -1 if the input element\n * is not ready.\n */\n cursorLocation: number | null;\n /**\n * Whether there is a value selected in the input area.\n */\n isValueSelected: boolean;\n /**\n * The current text value that the user has entered.\n */\n value: string;\n /**\n * The current index of where the selection starts. Returns -1 if the input element\n * is not ready.\n */\n selectionStart: number | null;\n /**\n * The current index of where the selection ends. Returns -1 if the input element\n * is not ready.\n */\n selectionEnd: number | null;\n /**\n * The current input element.\n */\n inputElement: HTMLInputElement | null;\n /**\n * Focus the input element.\n */\n focus(): void;\n /**\n * Clear all text in the input. Sets value to `''`.\n */\n clear(): void;\n}\n\n/**\n * {@docCategory Autofill}\n */\nexport interface IAutofillProps extends React.InputHTMLAttributes<HTMLInputElement | Autofill> {\n /**\n * Gets the component ref.\n */\n componentRef?: IRefObject<IAutofill>;\n\n /**\n * The suggested autofill value that will display.\n */\n suggestedDisplayValue?: string;\n\n /**\n * A callback for when the current input value changes. Called after\n * the state has been changed.\n *\n * @param composing - true if the change event was triggered while the\n * inner input was in the middle of a multi-character composition.\n * (for example, jp-hiragana IME input)\n */\n onInputValueChange?: (newValue?: string, composing?: boolean) => void;\n\n /**\n * When the user uses left arrow, right arrow, clicks, or deletes text, autofill is disabled\n * since the user has taken control. It is automatically re-enabled when the user enters text and the\n * cursor is at the end of the text in the input box. This prop can be used to override the\n * default list of key presses that will re-enable autofill.\n * @defaultvalue [KeyCodes.down, KeyCodes.up]\n */\n enableAutofillOnKeyPress?: KeyCodes[];\n\n /**\n * The default value to be visible. This is different from placeholder\n * because it actually sets the current value of the picker.\n * Note: Updates to this prop will not be respected.\n */\n defaultVisibleValue?: string;\n\n /**\n * Handler for checking and updating the value if needed in `componentWillReceiveProps`.\n * Returns the updated value to set, if needed.\n *\n * @deprecated use standard input `value` prop instead if the autofill should act like a controlled component\n */\n updateValueInWillReceiveProps?: () => string | null;\n\n /**\n * Handler for checking if the full value of the input should be selected in `componentDidUpdate`.\n * Returns whether the full value of the input should be selected.\n */\n shouldSelectFullInputValueInComponentDidUpdate?: () => boolean;\n\n /**\n * A callback used to modify the input string. Will entirely override the default behavior if provided.\n * If you just want to be notified of changes, use `onInputValueChange` instead.\n * Called before the state has been updated.\n *\n * @param composing - true if the change event was triggered while the\n * inner input was in the middle of a multi-character composition.\n * (for example, jp-hiragana IME input)\n * @deprecated To control the value, pass in `value` like in any other controlled component.\n * To be notified of changes, use `onInputValueChange`.\n */\n onInputChange?: (value: string, composing: boolean) => string | void;\n\n /**\n * Should the value of the input be selected? True if we're focused on our input, false otherwise.\n * We need to explicitly not select the text in the autofill if we are no longer focused.\n * In IE11, selecting an input will also focus the input, causing other element's focus to be stolen.\n */\n preventValueSelection?: boolean;\n}\n"]}
+2
View File
@@ -0,0 +1,2 @@
export * from './Autofill';
export * from './Autofill.types';
+3
View File
@@ -0,0 +1,3 @@
export * from './Autofill';
export * from './Autofill.types';
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["components/Autofill/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC","sourcesContent":["export * from './Autofill';\nexport * from './Autofill.types';\n"]}
@@ -0,0 +1,36 @@
import * as React from 'react';
import type { IBreadcrumbProps, IBreadcrumbData } from './Breadcrumb.types';
import type { JSXElement } from '@fluentui/utilities';
/** @deprecated Use IBreadcrumbData */
export type IBreadCrumbData = IBreadcrumbData;
/**
* {@docCategory Breadcrumb}
*/
export declare class BreadcrumbBase extends React.Component<IBreadcrumbProps, any> {
static defaultProps: IBreadcrumbProps;
private _classNames;
private _focusZone;
constructor(props: IBreadcrumbProps);
/**
* Sets focus to the first breadcrumb link.
*/
focus(): void;
render(): JSXElement;
/**
* Remove the first rendered item past the overlow point and put it and the end the overflow set.
*/
private _onReduceData;
/**
* Remove the last item of the overflow set and insert the item as the start of the rendered set past the overflow
* point.
*/
private _onGrowData;
private _onRenderBreadcrumb;
private _onRenderItem;
private _onBreadcrumbClicked;
/**
* Validate incoming props
* @param props - Props to validate
*/
private _validateProps;
}
@@ -0,0 +1,197 @@
import { __assign, __extends, __rest, __spreadArray } from "tslib";
import * as React from 'react';
import { initializeComponentRef, getRTL, classNamesFunction, getNativeProps, htmlElementProperties, } from '../../Utilities';
import { FocusZone, FocusZoneDirection } from '../../FocusZone';
import { Link } from '../../Link';
import { Icon } from '../../Icon';
import { IconButton } from '../../Button';
import { DirectionalHint } from '../../common/DirectionalHint';
import { ResizeGroup } from '../../ResizeGroup';
import { TooltipHost, TooltipOverflowMode } from '../../Tooltip';
import { composeRenderFunction } from '../../Utilities';
var getClassNames = classNamesFunction();
var OVERFLOW_KEY = 'overflow';
var nullFunction = function () { return null; };
var nonActionableItemProps = {
styles: function (props) {
var theme = props.theme;
return {
root: {
selectors: {
'&.is-disabled': {
color: theme.semanticColors.bodyText,
},
},
},
};
},
};
/**
* {@docCategory Breadcrumb}
*/
var BreadcrumbBase = /** @class */ (function (_super) {
__extends(BreadcrumbBase, _super);
function BreadcrumbBase(props) {
var _this = _super.call(this, props) || this;
_this._focusZone = React.createRef();
/**
* Remove the first rendered item past the overlow point and put it and the end the overflow set.
*/
_this._onReduceData = function (data) {
var renderedItems = data.renderedItems, renderedOverflowItems = data.renderedOverflowItems;
var overflowIndex = data.props.overflowIndex;
var movedItem = renderedItems[overflowIndex];
if (!movedItem) {
return undefined;
}
renderedItems = __spreadArray([], renderedItems, true);
renderedItems.splice(overflowIndex, 1);
renderedOverflowItems = __spreadArray(__spreadArray([], renderedOverflowItems, true), [movedItem], false);
return __assign(__assign({}, data), { renderedItems: renderedItems, renderedOverflowItems: renderedOverflowItems });
};
/**
* Remove the last item of the overflow set and insert the item as the start of the rendered set past the overflow
* point.
*/
_this._onGrowData = function (data) {
var renderedItems = data.renderedItems, renderedOverflowItems = data.renderedOverflowItems;
var _a = data.props, overflowIndex = _a.overflowIndex, maxDisplayedItems = _a.maxDisplayedItems;
renderedOverflowItems = __spreadArray([], renderedOverflowItems, true);
var movedItem = renderedOverflowItems.pop();
if (!movedItem || renderedItems.length >= maxDisplayedItems) {
return undefined;
}
renderedItems = __spreadArray([], renderedItems, true);
renderedItems.splice(overflowIndex, 0, movedItem);
return __assign(__assign({}, data), { renderedItems: renderedItems, renderedOverflowItems: renderedOverflowItems });
};
_this._onRenderBreadcrumb = function (data) {
var _a = data.props, ariaLabel = _a.ariaLabel, _b = _a.dividerAs, DividerType = _b === void 0 ? Icon : _b, onRenderItem = _a.onRenderItem, overflowAriaLabel = _a.overflowAriaLabel, overflowIndex = _a.overflowIndex, onRenderOverflowIcon = _a.onRenderOverflowIcon, overflowButtonAs = _a.overflowButtonAs;
var renderedOverflowItems = data.renderedOverflowItems, renderedItems = data.renderedItems;
var contextualItems = renderedOverflowItems.map(function (item) {
var isActionable = !!(item.onClick || item.href);
return {
text: item.text,
name: item.text,
key: item.key,
onClick: item.onClick ? _this._onBreadcrumbClicked.bind(_this, item) : null,
href: item.href,
disabled: !isActionable,
itemProps: isActionable ? undefined : nonActionableItemProps,
};
});
// Find index of last rendered item so the divider icon
// knows not to render on that item
var lastItemIndex = renderedItems.length - 1;
var hasOverflowItems = renderedOverflowItems && renderedOverflowItems.length !== 0;
var itemElements = renderedItems.map(function (item, index) {
var finalOnRenderItem = _this._onRenderItem;
if (item.onRender) {
finalOnRenderItem = composeRenderFunction(item.onRender, finalOnRenderItem);
}
if (onRenderItem) {
finalOnRenderItem = composeRenderFunction(onRenderItem, finalOnRenderItem);
}
return (React.createElement("li", { className: _this._classNames.listItem, key: item.key || String(index) },
finalOnRenderItem(item),
(index !== lastItemIndex || (hasOverflowItems && index === overflowIndex - 1)) && (React.createElement(DividerType, { className: _this._classNames.chevron, iconName: getRTL(_this.props.theme) ? 'ChevronLeft' : 'ChevronRight', item: item }))));
});
if (hasOverflowItems) {
var iconProps = !onRenderOverflowIcon ? { iconName: 'More' } : {};
var onRenderMenuIcon = onRenderOverflowIcon ? onRenderOverflowIcon : nullFunction;
var OverflowButton = overflowButtonAs ? overflowButtonAs : IconButton;
itemElements.splice(overflowIndex, 0, React.createElement("li", { className: _this._classNames.overflow, key: OVERFLOW_KEY },
React.createElement(OverflowButton, { className: _this._classNames.overflowButton, iconProps: iconProps, role: "button", "aria-haspopup": "true", ariaLabel: overflowAriaLabel, onRenderMenuIcon: onRenderMenuIcon, menuProps: {
items: contextualItems,
directionalHint: DirectionalHint.bottomLeftEdge,
} }),
overflowIndex !== lastItemIndex + 1 && (React.createElement(DividerType, { className: _this._classNames.chevron, iconName: getRTL(_this.props.theme) ? 'ChevronLeft' : 'ChevronRight', item: renderedOverflowItems[renderedOverflowItems.length - 1] }))));
}
var nativeProps = getNativeProps(_this.props, htmlElementProperties, [
'className',
]);
return (React.createElement("div", __assign({ className: _this._classNames.root, role: "navigation", "aria-label": ariaLabel }, nativeProps),
React.createElement(FocusZone, __assign({ componentRef: _this._focusZone, direction: FocusZoneDirection.horizontal }, _this.props.focusZoneProps),
React.createElement("ol", { className: _this._classNames.list }, itemElements))));
};
_this._onRenderItem = function (item) {
if (!item) {
return null;
}
var as = item.as, href = item.href, onClick = item.onClick, isCurrentItem = item.isCurrentItem, text = item.text, onRenderContent = item.onRenderContent, additionalProps = __rest(item, ["as", "href", "onClick", "isCurrentItem", "text", "onRenderContent"]);
var finalOnRenderContent = defaultOnRenderCrumbContent;
if (onRenderContent) {
finalOnRenderContent = composeRenderFunction(onRenderContent, finalOnRenderContent);
}
if (_this.props.onRenderItemContent) {
finalOnRenderContent = composeRenderFunction(_this.props.onRenderItemContent, finalOnRenderContent);
}
if (onClick || href) {
return (React.createElement(Link, __assign({}, additionalProps, { as: as, className: _this._classNames.itemLink, href: href, "aria-current": isCurrentItem ? 'page' : undefined,
// eslint-disable-next-line react/jsx-no-bind
onClick: _this._onBreadcrumbClicked.bind(_this, item) }),
React.createElement(TooltipHost, __assign({ content: text, overflowMode: TooltipOverflowMode.Parent }, _this.props.tooltipHostProps), finalOnRenderContent(item))));
}
else {
var Tag = as || 'span';
return (React.createElement(Tag, __assign({}, additionalProps, { className: _this._classNames.item }),
React.createElement(TooltipHost, __assign({ content: text, overflowMode: TooltipOverflowMode.Parent }, _this.props.tooltipHostProps), finalOnRenderContent(item))));
}
};
_this._onBreadcrumbClicked = function (item, ev) {
if (item.onClick) {
item.onClick(ev, item);
}
};
initializeComponentRef(_this);
_this._validateProps(props);
return _this;
}
/**
* Sets focus to the first breadcrumb link.
*/
BreadcrumbBase.prototype.focus = function () {
if (this._focusZone.current) {
this._focusZone.current.focus();
}
};
BreadcrumbBase.prototype.render = function () {
this._validateProps(this.props);
var _a = this.props, _b = _a.onReduceData, onReduceData = _b === void 0 ? this._onReduceData : _b, _c = _a.onGrowData, onGrowData = _c === void 0 ? this._onGrowData : _c, overflowIndex = _a.overflowIndex, maxDisplayedItems = _a.maxDisplayedItems, items = _a.items, className = _a.className, theme = _a.theme, styles = _a.styles;
var renderedItems = __spreadArray([], items, true);
var renderedOverflowItems = renderedItems.splice(overflowIndex, renderedItems.length - maxDisplayedItems);
var breadcrumbData = {
props: this.props,
renderedItems: renderedItems,
renderedOverflowItems: renderedOverflowItems,
};
this._classNames = getClassNames(styles, {
className: className,
theme: theme,
});
return (React.createElement(ResizeGroup, { onRenderData: this._onRenderBreadcrumb, onReduceData: onReduceData, onGrowData: onGrowData, data: breadcrumbData }));
};
/**
* Validate incoming props
* @param props - Props to validate
*/
BreadcrumbBase.prototype._validateProps = function (props) {
var maxDisplayedItems = props.maxDisplayedItems, overflowIndex = props.overflowIndex, items = props.items;
if (overflowIndex < 0 ||
(maxDisplayedItems > 1 && overflowIndex > maxDisplayedItems - 1) ||
(items.length > 0 && overflowIndex > items.length - 1)) {
throw new Error('Breadcrumb: overflowIndex out of range');
}
};
BreadcrumbBase.defaultProps = {
items: [],
maxDisplayedItems: 999,
overflowIndex: 0,
};
return BreadcrumbBase;
}(React.Component));
export { BreadcrumbBase };
function defaultOnRenderCrumbContent(item) {
return item ? React.createElement(React.Fragment, null, item.text) : null;
}
//# sourceMappingURL=Breadcrumb.base.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
import * as React from 'react';
import type { IBreadcrumbProps } from './Breadcrumb.types';
export declare const Breadcrumb: React.FunctionComponent<IBreadcrumbProps>;
+5
View File
@@ -0,0 +1,5 @@
import { styled } from '../../Utilities';
import { BreadcrumbBase } from './Breadcrumb.base';
import { getStyles } from './Breadcrumb.styles';
export var Breadcrumb = styled(BreadcrumbBase, getStyles, undefined, { scope: 'Breadcrumb' });
//# sourceMappingURL=Breadcrumb.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Breadcrumb.js","sourceRoot":"../src/","sources":["components/Breadcrumb/Breadcrumb.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhD,MAAM,CAAC,IAAM,UAAU,GAA8C,MAAM,CAIzE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { styled } from '../../Utilities';\nimport { BreadcrumbBase } from './Breadcrumb.base';\nimport { getStyles } from './Breadcrumb.styles';\nimport type { IBreadcrumbProps, IBreadcrumbStyleProps, IBreadcrumbStyles } from './Breadcrumb.types';\n\nexport const Breadcrumb: React.FunctionComponent<IBreadcrumbProps> = styled<\n IBreadcrumbProps,\n IBreadcrumbStyleProps,\n IBreadcrumbStyles\n>(BreadcrumbBase, getStyles, undefined, { scope: 'Breadcrumb' });\n"]}
@@ -0,0 +1,2 @@
import type { IBreadcrumbStyleProps, IBreadcrumbStyles } from './Breadcrumb.types';
export declare const getStyles: (props: IBreadcrumbStyleProps) => IBreadcrumbStyles;
@@ -0,0 +1,178 @@
import { __assign } from "tslib";
import { HighContrastSelector, ScreenWidthMaxMedium, ScreenWidthMaxSmall, ScreenWidthMinMedium, getFocusStyle, getScreenSelector, getGlobalClassNames, FontWeights, getHighContrastNoAdjustStyle, } from '../../Styling';
import { IsFocusVisibleClassName } from '../../Utilities';
var GlobalClassNames = {
root: 'ms-Breadcrumb',
list: 'ms-Breadcrumb-list',
listItem: 'ms-Breadcrumb-listItem',
chevron: 'ms-Breadcrumb-chevron',
overflow: 'ms-Breadcrumb-overflow',
overflowButton: 'ms-Breadcrumb-overflowButton',
itemLink: 'ms-Breadcrumb-itemLink',
item: 'ms-Breadcrumb-item',
};
var SingleLineTextStyle = {
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
overflow: 'hidden',
};
var overflowButtonFontSize = 16;
var chevronSmallFontSize = 8;
var itemLineHeight = 36;
var itemFontSize = 18;
var MinimumScreenSelector = getScreenSelector(0, ScreenWidthMaxSmall);
var MediumScreenSelector = getScreenSelector(ScreenWidthMinMedium, ScreenWidthMaxMedium);
export var getStyles = function (props) {
var _a, _b, _c, _d, _e;
var className = props.className, theme = props.theme;
var palette = theme.palette, semanticColors = theme.semanticColors, fonts = theme.fonts;
var classNames = getGlobalClassNames(GlobalClassNames, theme);
// Tokens
var itemBackgroundHoveredColor = semanticColors.menuItemBackgroundHovered;
var itemBackgroundPressedColor = semanticColors.menuItemBackgroundPressed;
var itemTextColor = palette.neutralSecondary;
var itemTextFontWeight = FontWeights.regular;
var itemTextHoveredOrPressedColor = palette.neutralPrimary;
var itemLastChildTextColor = palette.neutralPrimary;
var itemLastChildTextFontWeight = FontWeights.semibold;
var chevronButtonColor = palette.neutralSecondary;
var overflowButtonColor = palette.neutralSecondary;
var lastChildItemStyles = {
fontWeight: itemLastChildTextFontWeight,
color: itemLastChildTextColor,
};
var itemStateSelectors = {
':hover': {
color: itemTextHoveredOrPressedColor,
backgroundColor: itemBackgroundHoveredColor,
cursor: 'pointer',
selectors: (_a = {},
_a[HighContrastSelector] = {
color: 'Highlight',
backgroundColor: 'transparent',
},
_a),
},
':active': {
backgroundColor: itemBackgroundPressedColor,
color: itemTextHoveredOrPressedColor,
},
'&:active:hover': {
color: itemTextHoveredOrPressedColor,
backgroundColor: itemBackgroundPressedColor,
},
'&:active, &:hover, &:active:hover': {
textDecoration: 'none',
},
};
var commonItemStyles = {
color: itemTextColor,
padding: '0 8px',
lineHeight: itemLineHeight,
fontSize: itemFontSize,
fontWeight: itemTextFontWeight,
};
var overflowButtonHighContrastFocus = {
left: 1,
right: 1,
top: 1,
bottom: 1,
};
return {
root: [
classNames.root,
fonts.medium,
{
margin: '11px 0 1px',
},
className,
],
list: [
classNames.list,
{
whiteSpace: 'nowrap',
padding: 0,
margin: 0,
display: 'flex',
alignItems: 'stretch',
},
],
listItem: [
classNames.listItem,
{
listStyleType: 'none',
margin: '0',
padding: '0',
display: 'flex',
position: 'relative',
alignItems: 'center',
selectors: {
'&:last-child .ms-Breadcrumb-itemLink': __assign(__assign({}, lastChildItemStyles), (_b = {}, _b[HighContrastSelector] = {
MsHighContrastAdjust: 'auto',
forcedColorAdjust: 'auto',
}, _b)),
'&:last-child .ms-Breadcrumb-item': lastChildItemStyles,
},
},
],
chevron: [
classNames.chevron,
{
color: chevronButtonColor,
fontSize: fonts.small.fontSize,
selectors: (_c = {},
_c[HighContrastSelector] = __assign({ color: 'WindowText' }, getHighContrastNoAdjustStyle()),
_c[MediumScreenSelector] = {
fontSize: chevronSmallFontSize,
},
_c[MinimumScreenSelector] = {
fontSize: chevronSmallFontSize,
},
_c),
},
],
overflow: [
classNames.overflow,
{
position: 'relative',
display: 'flex',
alignItems: 'center',
},
],
overflowButton: [
classNames.overflowButton,
getFocusStyle(theme, { highContrastStyle: overflowButtonHighContrastFocus }),
SingleLineTextStyle,
{
fontSize: overflowButtonFontSize,
color: overflowButtonColor,
height: '100%',
cursor: 'pointer',
selectors: __assign(__assign({}, itemStateSelectors), (_d = {}, _d[MinimumScreenSelector] = {
padding: '4px 6px',
}, _d[MediumScreenSelector] = {
fontSize: fonts.mediumPlus.fontSize,
}, _d)),
},
],
itemLink: [
classNames.itemLink,
getFocusStyle(theme),
SingleLineTextStyle,
__assign(__assign({}, commonItemStyles), { selectors: __assign((_e = { ':focus': {
color: palette.neutralDark,
} }, _e[".".concat(IsFocusVisibleClassName, " &:focus, :host(.").concat(IsFocusVisibleClassName, ") &:focus")] = {
outline: "none",
}, _e), itemStateSelectors) }),
],
item: [
classNames.item,
__assign(__assign({}, commonItemStyles), { selectors: {
':hover': {
cursor: 'default',
},
} }),
],
};
};
//# sourceMappingURL=Breadcrumb.styles.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,175 @@
import * as React from 'react';
import type { IIconProps } from '../../Icon';
import type { IRefObject, IRenderFunction, IComponentAs, IStyleFunctionOrObject } from '../../Utilities';
import type { ITheme, IStyle } from '../../Styling';
import type { IFocusZoneProps } from '../../FocusZone';
import type { ITooltipHostProps } from '../../Tooltip';
import type { IButtonProps } from '../../Button';
/**
* {@docCategory Breadcrumb}
*/
export interface IBreadcrumbData {
props: IBreadcrumbProps;
renderedItems: IBreadcrumbItem[];
renderedOverflowItems: IBreadcrumbItem[];
}
/**
* {@docCategory Breadcrumb}
*/
export interface IBreadcrumb {
/**
* Sets focus to the first breadcrumb link.
*/
focus(): void;
}
/**
* {@docCategory Breadcrumb}
*/
export interface IBreadcrumbProps extends React.HTMLAttributes<HTMLElement> {
/**
* Optional callback to access the `IBreadcrumb` interface. Use this instead of `ref` for accessing
* the public methods and properties of the component.
*/
componentRef?: IRefObject<IBreadcrumb>;
/**
* Collection of breadcrumbs to render
*/
items: IBreadcrumbItem[];
/**
* Optional class for the root breadcrumb element.
*/
className?: string;
/**
* Render a custom divider in place of the default chevron `>`
*/
dividerAs?: IComponentAs<IDividerAsProps>;
/**
* Render a custom overflow icon in place of the default icon `...`
*/
onRenderOverflowIcon?: IRenderFunction<IButtonProps>;
/**
* Custom component for the overflow button.
*/
overflowButtonAs?: IComponentAs<IButtonProps>;
/**
* The maximum number of breadcrumbs to display before coalescing.
* If not specified, all breadcrumbs will be rendered.
*/
maxDisplayedItems?: number;
/** Custom render function to render each crumb. Default renders as a link. */
onRenderItem?: IRenderFunction<IBreadcrumbItem>;
/**
* Custom render function to render the content within a crumb. Default renders the text.
*/
onRenderItemContent?: IRenderFunction<IBreadcrumbItem>;
/**
* Method that determines how to reduce the length of the breadcrumb.
* Return undefined to never reduce breadcrumb length.
*/
onReduceData?: (data: IBreadcrumbData) => IBreadcrumbData | undefined;
/**
* Method that determines how to group the length of the breadcrumb.
* Return undefined to never increase breadcrumb length.
*/
onGrowData?: (data: IBreadcrumbData) => IBreadcrumbData | undefined;
/**
* Aria label for the root element of the breadcrumb (which is a navigation landmark).
*/
ariaLabel?: string;
/**
* Aria label for the overflow button.
*/
overflowAriaLabel?: string;
/**
* Optional index where overflow items will be collapsed.
* @default 0
*/
overflowIndex?: number;
styles?: IStyleFunctionOrObject<IBreadcrumbStyleProps, IBreadcrumbStyles>;
theme?: ITheme;
/**
* Extra props for the root FocusZone.
*/
focusZoneProps?: IFocusZoneProps;
/**
* Extra props for the TooltipHost which wraps each breadcrumb item.
*/
tooltipHostProps?: ITooltipHostProps;
}
/**
* {@docCategory Breadcrumb}
*/
export interface IBreadcrumbItem extends React.AllHTMLAttributes<HTMLElement> {
/**
* Text to display in the breadcrumb item.
*/
text: string;
/**
* Arbitrary unique string associated with the breadcrumb item.
*/
key: string;
/**
* Callback for when the breadcrumb item is selected.
*/
onClick?: (ev?: React.MouseEvent<HTMLElement>, item?: IBreadcrumbItem) => void;
/**
* URL to navigate to when this breadcrumb item is clicked.
* If provided, the breadcrumb will be rendered as a link.
*/
href?: string;
/**
* Whether this is the breadcrumb item the user is currently navigated to.
* If true, `aria-current="page"` will be applied to this breadcrumb item.
*/
isCurrentItem?: boolean;
/**
* A function to render the outer content of the crumb (the link).
*/
onRender?: IRenderFunction<IBreadcrumbItem>;
/**
* A function to render the inner content of the crumb (the text inside the link).
*/
onRenderContent?: IRenderFunction<IBreadcrumbItem>;
/**
* Optional prop to render the item as a heading of your choice.
*
* You can also use this to force items to render as links instead of buttons (by default,
* any item with a `href` renders as a link, and any item without a `href` renders as a button).
* This is not generally recommended because it may prevent activating the link using the keyboard.
*/
as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'a';
/**
* Optional role for the breadcrumb item (which renders as a button by default)
*/
role?: string;
}
/**
* {@docCategory Breadcrumb}
*/
export interface IDividerAsProps extends IIconProps {
/**
* Breadcrumb item to left of the divider to be passed for custom rendering.
* For overflowed items, it will be last item in the list.
*/
item?: IBreadcrumbItem;
}
/**
* {@docCategory Breadcrumb}
*/
export interface IBreadcrumbStyleProps {
className?: string;
theme: ITheme;
}
/**
* {@docCategory Breadcrumb}
*/
export interface IBreadcrumbStyles {
root: IStyle;
list: IStyle;
listItem: IStyle;
chevron: IStyle;
overflow: IStyle;
overflowButton: IStyle;
itemLink: IStyle;
item: IStyle;
}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=Breadcrumb.types.js.map
File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
export * from './Breadcrumb';
export * from './Breadcrumb.base';
export * from './Breadcrumb.types';
+4
View File
@@ -0,0 +1,4 @@
export * from './Breadcrumb';
export * from './Breadcrumb.base';
export * from './Breadcrumb.types';
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["components/Breadcrumb/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC","sourcesContent":["export * from './Breadcrumb';\nexport * from './Breadcrumb.base';\nexport * from './Breadcrumb.types';\n"]}
@@ -0,0 +1,9 @@
import * as React from 'react';
import type { IButtonProps } from '../Button.types';
import type { JSXElement } from '@fluentui/utilities';
/**
* {@docCategory Button}
*/
export declare class ActionButton extends React.Component<IButtonProps, {}> {
render(): JSXElement;
}
@@ -0,0 +1,24 @@
import { __assign, __decorate, __extends } from "tslib";
import * as React from 'react';
import { BaseButton } from '../BaseButton';
import { customizable, nullRender } from '../../../Utilities';
import { getStyles } from './ActionButton.styles';
/**
* {@docCategory Button}
*/
var ActionButton = /** @class */ (function (_super) {
__extends(ActionButton, _super);
function ActionButton() {
return _super !== null && _super.apply(this, arguments) || this;
}
ActionButton.prototype.render = function () {
var _a = this.props, styles = _a.styles, theme = _a.theme;
return (React.createElement(BaseButton, __assign({}, this.props, { variantClassName: "ms-Button--action ms-Button--command", styles: getStyles(theme, styles), onRenderDescription: nullRender })));
};
ActionButton = __decorate([
customizable('ActionButton', ['theme', 'styles'], true)
], ActionButton);
return ActionButton;
}(React.Component));
export { ActionButton };
//# sourceMappingURL=ActionButton.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ActionButton.js","sourceRoot":"../src/","sources":["components/Button/ActionButton/ActionButton.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAKlD;;GAEG;AAEH;IAAkC,gCAAiC;IAAnE;;IAaA,CAAC;IAZQ,6BAAM,GAAb;QACQ,IAAA,KAAoB,IAAI,CAAC,KAAK,EAA5B,MAAM,YAAA,EAAE,KAAK,WAAe,CAAC;QAErC,OAAO,CACL,oBAAC,UAAU,eACL,IAAI,CAAC,KAAK,IACd,gBAAgB,EAAC,sCAAsC,EACvD,MAAM,EAAE,SAAS,CAAC,KAAM,EAAE,MAAM,CAAC,EACjC,mBAAmB,EAAE,UAAU,IAC/B,CACH,CAAC;IACJ,CAAC;IAZU,YAAY;QADxB,YAAY,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC;OAC3C,YAAY,CAaxB;IAAD,mBAAC;CAAA,AAbD,CAAkC,KAAK,CAAC,SAAS,GAahD;SAbY,YAAY","sourcesContent":["import * as React from 'react';\nimport { BaseButton } from '../BaseButton';\nimport { customizable, nullRender } from '../../../Utilities';\nimport { getStyles } from './ActionButton.styles';\nimport type { IButtonProps } from '../Button.types';\n\nimport type { JSXElement } from '@fluentui/utilities';\n\n/**\n * {@docCategory Button}\n */\n@customizable('ActionButton', ['theme', 'styles'], true)\nexport class ActionButton extends React.Component<IButtonProps, {}> {\n public render(): JSXElement {\n const { styles, theme } = this.props;\n\n return (\n <BaseButton\n {...this.props}\n variantClassName=\"ms-Button--action ms-Button--command\"\n styles={getStyles(theme!, styles)}\n onRenderDescription={nullRender}\n />\n );\n }\n}\n"]}
@@ -0,0 +1,3 @@
import type { IButtonStyles } from '../Button.types';
import type { ITheme } from '../../../Styling';
export declare const getStyles: (theme: ITheme, customStyles?: IButtonStyles) => IButtonStyles;
@@ -0,0 +1,73 @@
import { concatStyleSets, HighContrastSelector } from '../../../Styling';
import { memoizeFunction } from '../../../Utilities';
import { getStyles as getBaseButtonStyles } from '../BaseButton.styles';
var DEFAULT_BUTTON_HEIGHT = '40px';
var DEFAULT_PADDING = '0 4px';
export var getStyles = memoizeFunction(function (theme, customStyles) {
var _a, _b, _c;
var baseButtonStyles = getBaseButtonStyles(theme);
var actionButtonStyles = {
root: (_a = {
padding: DEFAULT_PADDING,
height: DEFAULT_BUTTON_HEIGHT,
color: theme.palette.neutralPrimary,
backgroundColor: 'transparent',
border: '1px solid transparent'
},
_a[HighContrastSelector] = {
borderColor: 'Window',
},
_a),
rootHovered: (_b = {
color: theme.palette.themePrimary
},
_b[HighContrastSelector] = {
color: 'Highlight',
},
_b),
iconHovered: {
color: theme.palette.themePrimary,
},
rootPressed: {
color: theme.palette.black,
},
rootExpanded: {
color: theme.palette.themePrimary,
},
iconPressed: {
color: theme.palette.themeDarker,
},
rootDisabled: (_c = {
color: theme.palette.neutralTertiary,
backgroundColor: 'transparent',
borderColor: 'transparent'
},
_c[HighContrastSelector] = {
color: 'GrayText',
},
_c),
rootChecked: {
color: theme.palette.black,
},
iconChecked: {
color: theme.palette.themeDarker,
},
flexContainer: {
justifyContent: 'flex-start',
},
icon: {
color: theme.palette.themeDarkAlt,
},
iconDisabled: {
color: 'inherit',
},
menuIcon: {
color: theme.palette.neutralSecondary,
},
textContainer: {
flexGrow: 0,
},
};
return concatStyleSets(baseButtonStyles, actionButtonStyles, customStyles);
});
//# sourceMappingURL=ActionButton.styles.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ActionButton.styles.js","sourceRoot":"../src/","sources":["components/Button/ActionButton/ActionButton.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,SAAS,IAAI,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAIxE,IAAM,qBAAqB,GAAG,MAAM,CAAC;AACrC,IAAM,eAAe,GAAG,OAAO,CAAC;AAEhC,MAAM,CAAC,IAAM,SAAS,GAAG,eAAe,CAAC,UAAC,KAAa,EAAE,YAA4B;;IACnF,IAAM,gBAAgB,GAAkB,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACnE,IAAM,kBAAkB,GAAkB;QACxC,IAAI;gBACF,OAAO,EAAE,eAAe;gBACxB,MAAM,EAAE,qBAAqB;gBAC7B,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,cAAc;gBACnC,eAAe,EAAE,aAAa;gBAC9B,MAAM,EAAE,uBAAuB;;YAC/B,GAAC,oBAAoB,IAAG;gBACtB,WAAW,EAAE,QAAQ;aACtB;eACF;QAED,WAAW;gBACT,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,YAAY;;YACjC,GAAC,oBAAoB,IAAG;gBACtB,KAAK,EAAE,WAAW;aACnB;eACF;QAED,WAAW,EAAE;YACX,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,YAAY;SAClC;QAED,WAAW,EAAE;YACX,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK;SAC3B;QAED,YAAY,EAAE;YACZ,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,YAAY;SAClC;QAED,WAAW,EAAE;YACX,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW;SACjC;QAED,YAAY;gBACV,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,eAAe;gBACpC,eAAe,EAAE,aAAa;gBAC9B,WAAW,EAAE,aAAa;;YAC1B,GAAC,oBAAoB,IAAG;gBACtB,KAAK,EAAE,UAAU;aAClB;eACF;QAED,WAAW,EAAE;YACX,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK;SAC3B;QAED,WAAW,EAAE;YACX,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW;SACjC;QAED,aAAa,EAAE;YACb,cAAc,EAAE,YAAY;SAC7B;QAED,IAAI,EAAE;YACJ,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,YAAY;SAClC;QAED,YAAY,EAAE;YACZ,KAAK,EAAE,SAAS;SACjB;QAED,QAAQ,EAAE;YACR,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,gBAAgB;SACtC;QAED,aAAa,EAAE;YACb,QAAQ,EAAE,CAAC;SACZ;KACF,CAAC;IAEF,OAAO,eAAe,CAAC,gBAAgB,EAAE,kBAAkB,EAAE,YAAY,CAAE,CAAC;AAC9E,CAAC,CAAC,CAAC","sourcesContent":["import { concatStyleSets, HighContrastSelector } from '../../../Styling';\nimport { memoizeFunction } from '../../../Utilities';\nimport { getStyles as getBaseButtonStyles } from '../BaseButton.styles';\nimport type { IButtonStyles } from '../Button.types';\nimport type { ITheme } from '../../../Styling';\n\nconst DEFAULT_BUTTON_HEIGHT = '40px';\nconst DEFAULT_PADDING = '0 4px';\n\nexport const getStyles = memoizeFunction((theme: ITheme, customStyles?: IButtonStyles): IButtonStyles => {\n const baseButtonStyles: IButtonStyles = getBaseButtonStyles(theme);\n const actionButtonStyles: IButtonStyles = {\n root: {\n padding: DEFAULT_PADDING,\n height: DEFAULT_BUTTON_HEIGHT,\n color: theme.palette.neutralPrimary,\n backgroundColor: 'transparent',\n border: '1px solid transparent',\n [HighContrastSelector]: {\n borderColor: 'Window',\n },\n },\n\n rootHovered: {\n color: theme.palette.themePrimary,\n [HighContrastSelector]: {\n color: 'Highlight',\n },\n },\n\n iconHovered: {\n color: theme.palette.themePrimary,\n },\n\n rootPressed: {\n color: theme.palette.black,\n },\n\n rootExpanded: {\n color: theme.palette.themePrimary,\n },\n\n iconPressed: {\n color: theme.palette.themeDarker,\n },\n\n rootDisabled: {\n color: theme.palette.neutralTertiary,\n backgroundColor: 'transparent',\n borderColor: 'transparent',\n [HighContrastSelector]: {\n color: 'GrayText',\n },\n },\n\n rootChecked: {\n color: theme.palette.black,\n },\n\n iconChecked: {\n color: theme.palette.themeDarker,\n },\n\n flexContainer: {\n justifyContent: 'flex-start',\n },\n\n icon: {\n color: theme.palette.themeDarkAlt,\n },\n\n iconDisabled: {\n color: 'inherit',\n },\n\n menuIcon: {\n color: theme.palette.neutralSecondary,\n },\n\n textContainer: {\n flexGrow: 0,\n },\n };\n\n return concatStyleSets(baseButtonStyles, actionButtonStyles, customStyles)!;\n});\n"]}
@@ -0,0 +1,24 @@
import type { ITheme } from '../../Styling';
import type { IButtonStyles } from './Button.types';
export interface IButtonClassNames {
root?: string;
flexContainer?: string;
textContainer?: string;
icon?: string;
label?: string;
menuIcon?: string;
description?: string;
screenReaderText?: string;
}
export declare const ButtonGlobalClassNames: {
msButton: string;
msButtonHasMenu: string;
msButtonIcon: string;
msButtonMenuIcon: string;
msButtonLabel: string;
msButtonDescription: string;
msButtonScreenReaderText: string;
msButtonFlexContainer: string;
msButtonTextContainer: string;
};
export declare const getBaseButtonClassNames: (theme: ITheme, styles: IButtonStyles, className: string, variantClassName: string, iconClassName: string | undefined, menuIconClassName: string | undefined, disabled: boolean, hasMenu: boolean, checked: boolean, expanded: boolean, isSplit: boolean | undefined) => IButtonClassNames;
@@ -0,0 +1,93 @@
import { memoizeFunction } from '../../Utilities';
import { getGlobalClassNames, mergeStyleSets } from '../../Styling';
export var ButtonGlobalClassNames = {
msButton: 'ms-Button',
msButtonHasMenu: 'ms-Button--hasMenu',
msButtonIcon: 'ms-Button-icon',
msButtonMenuIcon: 'ms-Button-menuIcon',
msButtonLabel: 'ms-Button-label',
msButtonDescription: 'ms-Button-description',
msButtonScreenReaderText: 'ms-Button-screenReaderText',
msButtonFlexContainer: 'ms-Button-flexContainer',
msButtonTextContainer: 'ms-Button-textContainer',
};
export var getBaseButtonClassNames = memoizeFunction(function (theme, styles, className, variantClassName, iconClassName, menuIconClassName, disabled, hasMenu, checked, expanded, isSplit) {
var _a, _b;
var classNames = getGlobalClassNames(ButtonGlobalClassNames, theme || {});
var isExpanded = expanded && !isSplit;
return mergeStyleSets(styles.__shadowConfig__, {
root: [
classNames.msButton,
styles.root,
variantClassName,
checked && ['is-checked', styles.rootChecked],
isExpanded && [
'is-expanded',
styles.rootExpanded,
(_a = {},
_a[":hover .".concat(classNames.msButtonIcon)] = styles.iconExpandedHovered,
// menuIcon falls back to rootExpandedHovered to support original behavior
_a[":hover .".concat(classNames.msButtonMenuIcon)] = styles.menuIconExpandedHovered || styles.rootExpandedHovered,
_a[':hover'] = styles.rootExpandedHovered,
_a),
],
hasMenu && [ButtonGlobalClassNames.msButtonHasMenu, styles.rootHasMenu],
disabled && ['is-disabled', styles.rootDisabled],
!disabled &&
!isExpanded &&
!checked && (_b = {
':hover': styles.rootHovered
},
_b[":hover .".concat(classNames.msButtonLabel)] = styles.labelHovered,
_b[":hover .".concat(classNames.msButtonIcon)] = styles.iconHovered,
_b[":hover .".concat(classNames.msButtonDescription)] = styles.descriptionHovered,
_b[":hover .".concat(classNames.msButtonMenuIcon)] = styles.menuIconHovered,
_b[':focus'] = styles.rootFocused,
_b[':active'] = styles.rootPressed,
_b[":active .".concat(classNames.msButtonIcon)] = styles.iconPressed,
_b[":active .".concat(classNames.msButtonDescription)] = styles.descriptionPressed,
_b[":active .".concat(classNames.msButtonMenuIcon)] = styles.menuIconPressed,
_b),
disabled && checked && [styles.rootCheckedDisabled],
!disabled &&
checked && {
':hover': styles.rootCheckedHovered,
':active': styles.rootCheckedPressed,
},
className,
],
flexContainer: [classNames.msButtonFlexContainer, styles.flexContainer],
textContainer: [classNames.msButtonTextContainer, styles.textContainer],
icon: [
classNames.msButtonIcon,
iconClassName,
styles.icon,
isExpanded && styles.iconExpanded,
checked && styles.iconChecked,
disabled && styles.iconDisabled,
],
label: [classNames.msButtonLabel, styles.label, checked && styles.labelChecked, disabled && styles.labelDisabled],
menuIcon: [
classNames.msButtonMenuIcon,
menuIconClassName,
styles.menuIcon,
checked && styles.menuIconChecked,
disabled && !isSplit && styles.menuIconDisabled,
!disabled &&
!isExpanded &&
!checked && {
':hover': styles.menuIconHovered,
':active': styles.menuIconPressed,
},
isExpanded && ['is-expanded', styles.menuIconExpanded],
],
description: [
classNames.msButtonDescription,
styles.description,
checked && styles.descriptionChecked,
disabled && styles.descriptionDisabled,
],
screenReaderText: [classNames.msButtonScreenReaderText, styles.screenReaderText],
});
});
//# sourceMappingURL=BaseButton.classNames.js.map
File diff suppressed because one or more lines are too long
+93
View File
@@ -0,0 +1,93 @@
import * as React from 'react';
import type { IFocusRectsContext } from '../../Utilities';
import type { IButtonProps, IButton } from './Button.types';
import type { JSXElement } from '@fluentui/utilities';
/**
* {@docCategory Button}
*/
export interface IBaseButtonProps extends IButtonProps {
baseClassName?: string;
variantClassName?: string;
}
/**
* {@docCategory Button}
*/
export interface IBaseButtonState {
menuHidden: boolean;
}
/**
* {@docCategory Button}
*/
export declare class BaseButton extends React.Component<IBaseButtonProps, IBaseButtonState> implements IButton {
private get _isSplitButton();
static defaultProps: Partial<IBaseButtonProps>;
static contextType: React.Context<IFocusRectsContext | undefined>;
context: IFocusRectsContext;
private _async;
private _events;
private _buttonElement;
private _splitButtonContainer;
private _mergedRef;
private _labelId;
private _descriptionId;
private _ariaDescriptionId;
private _classNames;
private _processingTouch;
private _lastTouchTimeoutId;
private _renderedVisibleMenu;
private _menuShouldFocusOnContainer;
private _menuShouldFocusOnMount;
private _getMemoizedMenuButtonKeytipProps;
constructor(props: IBaseButtonProps);
render(): JSXElement;
componentDidMount(): void;
componentDidUpdate(prevProps: IBaseButtonProps, prevState: IBaseButtonState): void;
componentWillUnmount(): void;
focus(): void;
dismissMenu(): void;
openMenu(shouldFocusOnContainer?: boolean, shouldFocusOnMount?: boolean): void;
private _onRenderContent;
/**
* Method to help determine if the menu's component tree should
* be rendered. It takes into account whether the menu is expanded,
* whether it is a persisted menu and whether it has been shown to the user.
*/
private _shouldRenderMenu;
private _onRenderIcon;
private _onRenderTextContents;
private _onRenderText;
private _hasText;
private _onRenderChildren;
private _onRenderDescription;
private _onRenderAriaDescription;
private _onRenderMenuIcon;
private _getMenuProps;
private _onRenderMenu;
private _onDismissMenu;
private _dismissMenu;
private _openMenu;
private _onToggleMenu;
private _onRenderSplitButtonContent;
private _onSplitContainerFocusCapture;
private _onSplitButtonPrimaryClick;
private _onRenderSplitButtonDivider;
private _onRenderSplitButtonMenuButton;
private _onKeyDown;
private _onKeyUp;
private _onKeyPress;
private _onMouseUp;
private _onMouseDown;
private _onClick;
private _onSplitButtonContainerKeyDown;
private _onMenuKeyDown;
private _onTouchStart;
private _onPointerDown;
private _handleTouchAndPointerEvent;
/**
* Returns if the user hits a valid keyboard key to open the menu
* @param ev - the keyboard event
* @returns True if user clicks on custom trigger key if enabled or alt + down arrow if not. False otherwise.
*/
private _isValidMenuOpenKey;
private _onMenuClick;
}
+628
View File
@@ -0,0 +1,628 @@
import { __assign, __extends, __rest } from "tslib";
import * as React from 'react';
import { anchorProperties, assign, buttonProperties, createMergedRef, css, getId, getNativeProps, initializeComponentRef, memoizeFunction, mergeAriaAttributeValues, nullRender, portalContainsElement, setFocusVisibility, warnConditionallyRequiredProps, warnDeprecations, Async, EventGroup, FocusRects, FocusRectsContext, KeyCodes, } from '../../Utilities';
import { Icon, FontIcon, ImageIcon } from '../../Icon';
import { DirectionalHint } from '../../common/DirectionalHint';
import { ContextualMenu } from '../../ContextualMenu';
import { getBaseButtonClassNames } from './BaseButton.classNames';
import { getSplitButtonClassNames as getBaseSplitButtonClassNames } from './SplitButton/SplitButton.classNames';
import { KeytipData } from '../../KeytipData';
import { composeComponentAs } from '../../Utilities';
var TouchIdleDelay = 500; /* ms */
var COMPONENT_NAME = 'BaseButton';
/**
* {@docCategory Button}
*/
var BaseButton = /** @class */ (function (_super) {
__extends(BaseButton, _super);
function BaseButton(props) {
var _this = _super.call(this, props) || this;
_this._buttonElement = React.createRef();
_this._splitButtonContainer = React.createRef();
_this._mergedRef = createMergedRef();
_this._renderedVisibleMenu = false;
_this._getMemoizedMenuButtonKeytipProps = memoizeFunction(function (keytipProps) {
return __assign(__assign({}, keytipProps), { hasMenu: true });
});
_this._onRenderIcon = function (buttonProps, defaultRender) {
var iconProps = _this.props.iconProps;
if (iconProps && (iconProps.iconName !== undefined || iconProps.imageProps)) {
var className = iconProps.className, imageProps = iconProps.imageProps, rest = __rest(iconProps, ["className", "imageProps"]);
// If the styles prop is specified as part of iconProps, fall back to regular Icon as FontIcon and ImageIcon
// do not have this prop.
if (iconProps.styles) {
return React.createElement(Icon, __assign({ className: css(_this._classNames.icon, className), imageProps: imageProps }, rest));
}
if (iconProps.iconName) {
return React.createElement(FontIcon, __assign({ className: css(_this._classNames.icon, className) }, rest));
}
if (imageProps) {
return React.createElement(ImageIcon, __assign({ className: css(_this._classNames.icon, className), imageProps: imageProps }, rest));
}
}
return null;
};
_this._onRenderTextContents = function () {
var _a = _this.props, text = _a.text, children = _a.children,
// eslint-disable-next-line @typescript-eslint/no-deprecated
_b = _a.secondaryText,
// eslint-disable-next-line @typescript-eslint/no-deprecated
secondaryText = _b === void 0 ? _this.props.description : _b, _c = _a.onRenderText, onRenderText = _c === void 0 ? _this._onRenderText : _c, _d = _a.onRenderDescription, onRenderDescription = _d === void 0 ? _this._onRenderDescription : _d;
if (text || typeof children === 'string' || secondaryText) {
return (React.createElement("span", { className: _this._classNames.textContainer },
onRenderText(_this.props, _this._onRenderText),
onRenderDescription(_this.props, _this._onRenderDescription)));
}
return [onRenderText(_this.props, _this._onRenderText), onRenderDescription(_this.props, _this._onRenderDescription)];
};
_this._onRenderText = function () {
var text = _this.props.text;
var children = _this.props.children;
// For backwards compat, we should continue to take in the text content from children.
if (text === undefined && typeof children === 'string') {
text = children;
}
if (_this._hasText()) {
return (React.createElement("span", { key: _this._labelId, className: _this._classNames.label, id: _this._labelId }, text));
}
return null;
};
_this._onRenderChildren = function () {
var children = _this.props.children;
// If children is just a string, either it or the text will be rendered via onRenderLabel
// If children is another component, it will be rendered after text
if (typeof children === 'string') {
return null;
}
return children;
};
_this._onRenderDescription = function (props) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
var _a = props.secondaryText, secondaryText = _a === void 0 ? _this.props.description : _a;
// ms-Button-description is only shown when the button type is compound.
// In other cases it will not be displayed.
return secondaryText ? (React.createElement("span", { key: _this._descriptionId, className: _this._classNames.description, id: _this._descriptionId }, secondaryText)) : null;
};
_this._onRenderAriaDescription = function () {
var ariaDescription = _this.props.ariaDescription;
// If ariaDescription is given, descriptionId will be assigned to ariaDescriptionSpan,
// otherwise it will be assigned to descriptionSpan.
return ariaDescription ? (React.createElement("span", { className: _this._classNames.screenReaderText, id: _this._ariaDescriptionId }, ariaDescription)) : null;
};
_this._onRenderMenuIcon = function (props) {
var menuIconProps = _this.props.menuIconProps;
return React.createElement(FontIcon, __assign({ iconName: "ChevronDown" }, menuIconProps, { className: _this._classNames.menuIcon }));
};
_this._onRenderMenu = function (menuProps) {
var MenuType = _this.props.menuAs ? composeComponentAs(_this.props.menuAs, ContextualMenu) : ContextualMenu;
return React.createElement(MenuType, __assign({}, menuProps));
};
_this._onDismissMenu = function (ev) {
var menuProps = _this.props.menuProps;
if (menuProps && menuProps.onDismiss) {
menuProps.onDismiss(ev);
}
if (!ev || !ev.defaultPrevented) {
_this._dismissMenu();
}
};
_this._dismissMenu = function () {
_this._menuShouldFocusOnMount = undefined;
_this._menuShouldFocusOnContainer = undefined;
_this.setState({ menuHidden: true });
};
_this._openMenu = function (shouldFocusOnContainer, shouldFocusOnMount) {
if (shouldFocusOnMount === void 0) { shouldFocusOnMount = true; }
if (_this.props.menuProps) {
_this._menuShouldFocusOnContainer = shouldFocusOnContainer;
_this._menuShouldFocusOnMount = shouldFocusOnMount;
_this._renderedVisibleMenu = true;
_this.setState({ menuHidden: false });
}
};
_this._onToggleMenu = function (shouldFocusOnContainer) {
var shouldFocusOnMount = true;
if (_this.props.menuProps && _this.props.menuProps.shouldFocusOnMount === false) {
shouldFocusOnMount = false;
}
_this.state.menuHidden ? _this._openMenu(shouldFocusOnContainer, shouldFocusOnMount) : _this._dismissMenu();
};
_this._onSplitContainerFocusCapture = function (ev) {
var container = _this._splitButtonContainer.current;
// If the target is coming from the portal we do not need to set focus on the container.
if (!container || (ev.target && portalContainsElement(ev.target, container))) {
return;
}
// We should never be able to focus the individual buttons in a split button. Focus
// should always remain on the container.
container.focus();
};
_this._onSplitButtonPrimaryClick = function (ev) {
if (!_this.state.menuHidden) {
_this._dismissMenu();
}
// toggle split buttons need two separate targets, even for touch
var singleTouchTarget = _this._processingTouch && !_this.props.toggle;
if (!singleTouchTarget && _this.props.onClick) {
_this.props.onClick(ev);
}
else if (singleTouchTarget) {
_this._onMenuClick(ev);
}
};
_this._onKeyDown = function (ev) {
// explicity cancelling event so click won't fire after this
// eslint-disable-next-line @typescript-eslint/no-deprecated
if (_this.props.disabled && (ev.which === KeyCodes.enter || ev.which === KeyCodes.space)) {
ev.preventDefault();
ev.stopPropagation();
}
else if (!_this.props.disabled) {
if (_this.props.menuProps) {
_this._onMenuKeyDown(ev);
}
else if (_this.props.onKeyDown !== undefined) {
_this.props.onKeyDown(ev); // not cancelling event because it's not disabled
}
}
};
_this._onKeyUp = function (ev) {
if (!_this.props.disabled && _this.props.onKeyUp !== undefined) {
_this.props.onKeyUp(ev); // not cancelling event because it's not disabled
}
};
_this._onKeyPress = function (ev) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
if (!_this.props.disabled && _this.props.onKeyPress !== undefined) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
_this.props.onKeyPress(ev); // not cancelling event because it's not disabled
}
};
_this._onMouseUp = function (ev) {
if (!_this.props.disabled && _this.props.onMouseUp !== undefined) {
_this.props.onMouseUp(ev); // not cancelling event because it's not disabled
}
};
_this._onMouseDown = function (ev) {
if (!_this.props.disabled && _this.props.onMouseDown !== undefined) {
_this.props.onMouseDown(ev); // not cancelling event because it's not disabled
}
};
_this._onClick = function (ev) {
if (!_this.props.disabled) {
if (_this.props.menuProps) {
_this._onMenuClick(ev);
}
else if (_this.props.onClick !== undefined) {
_this.props.onClick(ev); // not cancelling event because it's not disabled
}
}
};
_this._onSplitButtonContainerKeyDown = function (ev) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
if (ev.which === KeyCodes.enter || ev.which === KeyCodes.space) {
if (_this._buttonElement.current) {
_this._buttonElement.current.click();
ev.preventDefault();
ev.stopPropagation();
}
}
else {
_this._onMenuKeyDown(ev);
}
};
_this._onMenuKeyDown = function (ev) {
var _a;
if (_this.props.disabled) {
return;
}
if (_this.props.onKeyDown) {
_this.props.onKeyDown(ev);
}
// eslint-disable-next-line @typescript-eslint/no-deprecated
var isUp = ev.which === KeyCodes.up;
// eslint-disable-next-line @typescript-eslint/no-deprecated
var isDown = ev.which === KeyCodes.down;
if (!ev.defaultPrevented && _this._isValidMenuOpenKey(ev)) {
var onMenuClick = _this.props.onMenuClick;
if (onMenuClick) {
onMenuClick(ev, _this.props);
}
_this._onToggleMenu(false);
ev.preventDefault();
ev.stopPropagation();
}
// eslint-disable-next-line @typescript-eslint/no-deprecated
if (ev.which === KeyCodes.enter || ev.which === KeyCodes.space) {
// We manually set the focus visibility to true if opening via Enter or Space to account for the scenario where
// a user clicks on the button, closes the menu and then opens it via keyboard. In this scenario our default logic
// for setting focus visibility is not triggered since there is no keyboard navigation present beforehand.
setFocusVisibility(true, ev.target, (_a = _this.context) === null || _a === void 0 ? void 0 : _a.registeredProviders);
}
if (!(ev.altKey || ev.metaKey) && (isUp || isDown)) {
// Suppose a menu, with shouldFocusOnMount: false, is open, and user wants to keyboard to the menu items
// We need to re-render the menu with shouldFocusOnMount as true.
if (!_this.state.menuHidden && _this.props.menuProps) {
var currentShouldFocusOnMount = _this._menuShouldFocusOnMount !== undefined
? _this._menuShouldFocusOnMount
: _this.props.menuProps.shouldFocusOnMount;
if (!currentShouldFocusOnMount) {
ev.preventDefault();
ev.stopPropagation();
_this._menuShouldFocusOnMount = true;
_this.forceUpdate();
}
}
}
};
_this._onTouchStart = function () {
if (_this._isSplitButton &&
_this._splitButtonContainer.current &&
!('onpointerdown' in _this._splitButtonContainer.current)) {
_this._handleTouchAndPointerEvent();
}
};
_this._onMenuClick = function (ev) {
var _a = _this.props, onMenuClick = _a.onMenuClick, menuProps = _a.menuProps;
if (onMenuClick) {
onMenuClick(ev, _this.props);
}
// focus on the container by default when the menu is opened with a click event
// this differentiates from a keyboard interaction triggering the click event
var shouldFocusOnContainer = typeof (menuProps === null || menuProps === void 0 ? void 0 : menuProps.shouldFocusOnContainer) === 'boolean'
? menuProps.shouldFocusOnContainer
: ev.nativeEvent.pointerType === 'mouse';
if (!ev.defaultPrevented) {
_this._onToggleMenu(shouldFocusOnContainer);
ev.preventDefault();
ev.stopPropagation();
}
};
initializeComponentRef(_this);
_this._async = new Async(_this);
_this._events = new EventGroup(_this);
warnConditionallyRequiredProps(COMPONENT_NAME, props, ['menuProps', 'onClick'], 'split', _this.props.split);
warnDeprecations(COMPONENT_NAME, props, {
rootProps: undefined,
description: 'secondaryText',
toggled: 'checked',
});
_this._labelId = getId();
_this._descriptionId = getId();
_this._ariaDescriptionId = getId();
_this.state = {
menuHidden: true,
};
return _this;
}
Object.defineProperty(BaseButton.prototype, "_isSplitButton", {
get: function () {
return !!this.props.menuProps && !!this.props.onClick && this.props.split === true;
},
enumerable: false,
configurable: true
});
BaseButton.prototype.render = function () {
var _a;
var _b = this.props, ariaDescription = _b.ariaDescription, ariaLabel = _b.ariaLabel, ariaHidden = _b.ariaHidden, className = _b.className, disabled = _b.disabled, allowDisabledFocus = _b.allowDisabledFocus, primaryDisabled = _b.primaryDisabled,
// eslint-disable-next-line @typescript-eslint/no-deprecated
_c = _b.secondaryText,
// eslint-disable-next-line @typescript-eslint/no-deprecated
secondaryText = _c === void 0 ? this.props.description : _c, href = _b.href, iconProps = _b.iconProps, menuIconProps = _b.menuIconProps, styles = _b.styles, checked = _b.checked, variantClassName = _b.variantClassName, theme = _b.theme, toggle = _b.toggle, getClassNames = _b.getClassNames, role = _b.role;
var menuHidden = this.state.menuHidden;
// Button is disabled if the whole button (in case of splitButton is disabled) or if the primary action is disabled
var isPrimaryButtonDisabled = disabled || primaryDisabled;
this._classNames = getClassNames
? getClassNames(theme, className, variantClassName, iconProps && iconProps.className, menuIconProps && menuIconProps.className, isPrimaryButtonDisabled, checked, !menuHidden, !!this.props.menuProps, this.props.split, !!allowDisabledFocus)
: getBaseButtonClassNames(theme, styles, className, variantClassName, iconProps && iconProps.className, menuIconProps && menuIconProps.className, isPrimaryButtonDisabled, !!this.props.menuProps, checked, !menuHidden, this.props.split);
var _d = this, _ariaDescriptionId = _d._ariaDescriptionId, _labelId = _d._labelId, _descriptionId = _d._descriptionId;
// Anchor tag cannot be disabled hence in disabled state rendering
// anchor button as normal button
var renderAsAnchor = !isPrimaryButtonDisabled && !!href;
var tag = renderAsAnchor ? 'a' : 'button';
var nativeProps = getNativeProps(
// eslint-disable-next-line @typescript-eslint/no-deprecated
assign(renderAsAnchor ? {} : { type: 'button' }, this.props.rootProps, this.props), renderAsAnchor ? anchorProperties : buttonProperties, [
'disabled', // let disabled buttons be focused and styled as disabled.
]);
// Check for ariaLabel passed in via Button props, and fall back to aria-label passed in via native props
var resolvedAriaLabel = ariaLabel || nativeProps['aria-label'];
// Check for ariaDescription, secondaryText or aria-describedby in the native props to determine source of
// aria-describedby. Otherwise default to undefined so property does not appear in output.
var ariaDescribedBy = undefined;
if (ariaDescription) {
ariaDescribedBy = _ariaDescriptionId;
}
else if (secondaryText && this.props.onRenderDescription !== nullRender) {
// for buttons like CompoundButton with a valid onRenderDescription, we need to set an ariaDescribedBy
// for buttons that do not render anything (via nullRender), we should not set an ariaDescribedBy
ariaDescribedBy = _descriptionId;
}
else if (nativeProps['aria-describedby']) {
ariaDescribedBy = nativeProps['aria-describedby'];
}
// If an explicit aria-labelledby is given, use that and we're done.
// If any kind of description is given (which will end up as an aria-describedby attribute)
// and no ariaLabel is specified, set the labelledby element.
// Otherwise, the button is labeled implicitly by the descendent text on the button (if it exists).
var ariaLabelledBy = undefined;
if (nativeProps['aria-labelledby']) {
ariaLabelledBy = nativeProps['aria-labelledby'];
}
else if (ariaDescribedBy && !resolvedAriaLabel) {
ariaLabelledBy = this._hasText() ? _labelId : undefined;
}
var dataIsFocusable = this.props['data-is-focusable'] === false || (disabled && !allowDisabledFocus) || this._isSplitButton
? false
: true;
var isCheckboxTypeRole = role === 'menuitemcheckbox' || role === 'checkbox';
// if isCheckboxTypeRole, always return a checked value.
// Otherwise only return checked value if toggle is set to true.
// This is because role="checkbox" always needs to have an aria-checked value
// but our checked prop only sets aria-pressed if we mark the button as a toggle="true"
var checkedOrPressedValue = isCheckboxTypeRole ? !!checked : toggle === true ? !!checked : undefined;
var buttonProps = assign(nativeProps, (_a = {
className: this._classNames.root,
// eslint-disable-next-line @typescript-eslint/no-deprecated
ref: this._mergedRef(this.props.elementRef, this._buttonElement),
disabled: isPrimaryButtonDisabled && !allowDisabledFocus,
onKeyDown: this._onKeyDown,
onKeyPress: this._onKeyPress,
onKeyUp: this._onKeyUp,
onMouseDown: this._onMouseDown,
onMouseUp: this._onMouseUp,
onClick: this._onClick,
'aria-label': resolvedAriaLabel,
'aria-labelledby': ariaLabelledBy,
'aria-describedby': ariaDescribedBy,
'aria-disabled': isPrimaryButtonDisabled,
'data-is-focusable': dataIsFocusable
},
// aria-pressed attribute should only be present for toggle buttons
// aria-checked attribute should only be present for toggle buttons with checkbox type role
_a[isCheckboxTypeRole ? 'aria-checked' : 'aria-pressed'] = checkedOrPressedValue,
_a));
if (ariaHidden) {
buttonProps['aria-hidden'] = true;
}
if (this._isSplitButton) {
return this._onRenderSplitButtonContent(tag, buttonProps);
}
else if (this.props.menuProps) {
var _e = this.props.menuProps.id, id = _e === void 0 ? "".concat(this._labelId, "-menu") : _e;
assign(buttonProps, {
'aria-expanded': !menuHidden,
'aria-controls': !menuHidden ? id : null,
'aria-haspopup': true,
});
}
return this._onRenderContent(tag, buttonProps);
};
BaseButton.prototype.componentDidMount = function () {
// For split buttons, touching anywhere in the button should drop the dropdown, which should contain the
// primary action. This gives more hit target space for touch environments. We're setting the onpointerdown here,
// because React does not support Pointer events yet.
if (this._isSplitButton && this._splitButtonContainer.current) {
if ('onpointerdown' in this._splitButtonContainer.current) {
this._events.on(this._splitButtonContainer.current, 'pointerdown', this._onPointerDown, true);
}
if ('onpointerup' in this._splitButtonContainer.current && this.props.onPointerUp) {
this._events.on(this._splitButtonContainer.current, 'pointerup', this.props.onPointerUp, true);
}
}
};
BaseButton.prototype.componentDidUpdate = function (prevProps, prevState) {
// If Button's menu was closed, run onAfterMenuDismiss.
if (this.props.onAfterMenuDismiss && !prevState.menuHidden && this.state.menuHidden) {
this.props.onAfterMenuDismiss();
}
};
BaseButton.prototype.componentWillUnmount = function () {
this._async.dispose();
this._events.dispose();
};
BaseButton.prototype.focus = function () {
var _a, _b;
if (this._isSplitButton && this._splitButtonContainer.current) {
setFocusVisibility(true, undefined, (_a = this.context) === null || _a === void 0 ? void 0 : _a.registeredProviders);
this._splitButtonContainer.current.focus();
}
else if (this._buttonElement.current) {
setFocusVisibility(true, undefined, (_b = this.context) === null || _b === void 0 ? void 0 : _b.registeredProviders);
this._buttonElement.current.focus();
}
};
BaseButton.prototype.dismissMenu = function () {
this._dismissMenu();
};
BaseButton.prototype.openMenu = function (shouldFocusOnContainer, shouldFocusOnMount) {
this._openMenu(shouldFocusOnContainer, shouldFocusOnMount);
};
BaseButton.prototype._onRenderContent = function (tag, buttonProps) {
var _this = this;
var props = this.props;
var Tag = tag;
var menuIconProps = props.menuIconProps, menuProps = props.menuProps, _a = props.onRenderIcon, onRenderIcon = _a === void 0 ? this._onRenderIcon : _a, _b = props.onRenderAriaDescription, onRenderAriaDescription = _b === void 0 ? this._onRenderAriaDescription : _b, _c = props.onRenderChildren, onRenderChildren = _c === void 0 ? this._onRenderChildren : _c,
// eslint-disable-next-line @typescript-eslint/no-deprecated
_d = props.onRenderMenu,
// eslint-disable-next-line @typescript-eslint/no-deprecated
onRenderMenu = _d === void 0 ? this._onRenderMenu : _d, _e = props.onRenderMenuIcon, onRenderMenuIcon = _e === void 0 ? this._onRenderMenuIcon : _e, disabled = props.disabled;
var keytipProps = props.keytipProps;
if (keytipProps && menuProps) {
keytipProps = this._getMemoizedMenuButtonKeytipProps(keytipProps);
}
var Button = function (keytipAttributes) { return (React.createElement(Tag, __assign({}, buttonProps, keytipAttributes),
React.createElement("span", { className: _this._classNames.flexContainer, "data-automationid": "splitbuttonprimary" },
onRenderIcon(props, _this._onRenderIcon),
_this._onRenderTextContents(),
onRenderAriaDescription(props, _this._onRenderAriaDescription),
onRenderChildren(props, _this._onRenderChildren),
!_this._isSplitButton &&
(menuProps || menuIconProps || _this.props.onRenderMenuIcon) &&
onRenderMenuIcon(_this.props, _this._onRenderMenuIcon),
menuProps &&
!menuProps.doNotLayer &&
_this._shouldRenderMenu() &&
onRenderMenu(_this._getMenuProps(menuProps), _this._onRenderMenu)))); };
var Content = keytipProps ? (
// If we're making a split button, we won't put the keytip here
React.createElement(KeytipData, { keytipProps: !this._isSplitButton ? keytipProps : undefined, ariaDescribedBy: buttonProps['aria-describedby'], disabled: disabled }, function (keytipAttributes) { return Button(keytipAttributes); })) : (Button());
if (menuProps && menuProps.doNotLayer) {
return (React.createElement(React.Fragment, null,
Content,
this._shouldRenderMenu() && onRenderMenu(this._getMenuProps(menuProps), this._onRenderMenu)));
}
return (React.createElement(React.Fragment, null,
Content,
React.createElement(FocusRects, null)));
};
/**
* Method to help determine if the menu's component tree should
* be rendered. It takes into account whether the menu is expanded,
* whether it is a persisted menu and whether it has been shown to the user.
*/
BaseButton.prototype._shouldRenderMenu = function () {
var menuHidden = this.state.menuHidden;
// eslint-disable-next-line @typescript-eslint/no-deprecated
var _a = this.props, persistMenu = _a.persistMenu, renderPersistedMenuHiddenOnMount = _a.renderPersistedMenuHiddenOnMount;
if (!menuHidden) {
// Always should render a menu when it is expanded
return true;
}
else if (persistMenu && (this._renderedVisibleMenu || renderPersistedMenuHiddenOnMount)) {
// _renderedVisibleMenu ensures that the first rendering of
// the menu happens on-screen, as edge's scrollbar calculations are off if done while hidden.
return true;
}
return false;
};
BaseButton.prototype._hasText = function () {
// _onRenderTextContents and _onRenderText do not perform the same checks. Below is parity with what _onRenderText
// used to have before the refactor that introduced this function. _onRenderTextContents does not require props.
// text to be undefined in order for props.children to be used as a fallback.
// Purely a code maintainability/reuse issue, but logged as Issue #4979.
return this.props.text !== null && (this.props.text !== undefined || typeof this.props.children === 'string');
};
BaseButton.prototype._getMenuProps = function (menuProps) {
var persistMenu = this.props.persistMenu;
var menuHidden = this.state.menuHidden;
// the accessible menu label (accessible name) has a relationship to the button.
// If the menu props do not specify an explicit value for aria-label or aria-labelledBy,
// AND the button has text, we'll set the menu aria-labelledBy to the text element id.
if (!menuProps.ariaLabel && !menuProps.labelElementId && this._hasText()) {
menuProps = __assign(__assign({}, menuProps), { labelElementId: this._labelId });
}
return __assign(__assign({ id: this._labelId + '-menu', directionalHint: DirectionalHint.bottomLeftEdge }, menuProps), { shouldFocusOnContainer: this._menuShouldFocusOnContainer, shouldFocusOnMount: this._menuShouldFocusOnMount, hidden: persistMenu ? menuHidden : undefined, className: css('ms-BaseButton-menuhost', menuProps.className), target: this._isSplitButton ? this._splitButtonContainer.current : this._buttonElement.current, onDismiss: this._onDismissMenu });
};
BaseButton.prototype._onRenderSplitButtonContent = function (tag, buttonProps) {
var _this = this;
var _a = this.props, _b = _a.styles, styles = _b === void 0 ? {} : _b, disabled = _a.disabled, allowDisabledFocus = _a.allowDisabledFocus, checked = _a.checked, getSplitButtonClassNames = _a.getSplitButtonClassNames, primaryDisabled = _a.primaryDisabled, menuProps = _a.menuProps, toggle = _a.toggle, role = _a.role, primaryActionButtonProps = _a.primaryActionButtonProps;
var keytipProps = this.props.keytipProps;
var menuHidden = this.state.menuHidden;
var classNames = getSplitButtonClassNames
? getSplitButtonClassNames(!!disabled, !menuHidden, !!checked, !!allowDisabledFocus)
: styles && getBaseSplitButtonClassNames(styles, !!disabled, !menuHidden, !!checked, !!primaryDisabled);
assign(buttonProps, {
onClick: undefined,
onPointerDown: undefined,
onPointerUp: undefined,
tabIndex: -1,
'data-is-focusable': false,
});
if (keytipProps && menuProps) {
keytipProps = this._getMemoizedMenuButtonKeytipProps(keytipProps);
}
var containerProps = getNativeProps(buttonProps, [], ['disabled']);
// Add additional props to apply on primary action button
if (primaryActionButtonProps) {
assign(buttonProps, primaryActionButtonProps);
}
var SplitButton = function (keytipAttributes) { return (React.createElement("div", __assign({}, containerProps, { "data-ktp-target": keytipAttributes ? keytipAttributes['data-ktp-target'] : undefined, role: role ? role : 'button', "aria-disabled": disabled, "aria-haspopup": true, "aria-expanded": !menuHidden, "aria-pressed": toggle ? !!checked : undefined, "aria-describedby": mergeAriaAttributeValues(buttonProps['aria-describedby'], keytipAttributes ? keytipAttributes['aria-describedby'] : undefined), className: classNames && classNames.splitButtonContainer, onKeyDown: _this._onSplitButtonContainerKeyDown, onTouchStart: _this._onTouchStart, ref: _this._splitButtonContainer, "data-is-focusable": true, onClick: !disabled && !primaryDisabled ? _this._onSplitButtonPrimaryClick : undefined, tabIndex: (!disabled && !primaryDisabled) || allowDisabledFocus ? 0 : undefined, "aria-roledescription": buttonProps['aria-roledescription'], onFocusCapture: _this._onSplitContainerFocusCapture }),
React.createElement("span", { style: { display: 'flex', width: '100%' } },
_this._onRenderContent(tag, buttonProps),
_this._onRenderSplitButtonMenuButton(classNames, keytipAttributes),
_this._onRenderSplitButtonDivider(classNames)))); };
return keytipProps ? (React.createElement(KeytipData, { keytipProps: keytipProps, disabled: disabled }, function (keytipAttributes) { return SplitButton(keytipAttributes); })) : (SplitButton());
};
BaseButton.prototype._onRenderSplitButtonDivider = function (classNames) {
if (classNames && classNames.divider) {
var onClick = function (ev) {
ev.stopPropagation();
};
return React.createElement("span", { className: classNames.divider, "aria-hidden": true, onClick: onClick });
}
return null;
};
BaseButton.prototype._onRenderSplitButtonMenuButton = function (classNames, keytipAttributes) {
var _a = this.props, allowDisabledFocus = _a.allowDisabledFocus, checked = _a.checked, disabled = _a.disabled, splitButtonMenuProps = _a.splitButtonMenuProps, splitButtonAriaLabel = _a.splitButtonAriaLabel, primaryDisabled = _a.primaryDisabled;
var menuHidden = this.state.menuHidden;
var menuIconProps = this.props.menuIconProps;
if (menuIconProps === undefined) {
menuIconProps = {
iconName: 'ChevronDown',
};
}
var splitButtonProps = __assign(__assign({}, splitButtonMenuProps), { styles: classNames, checked: checked, disabled: disabled, allowDisabledFocus: allowDisabledFocus, onClick: this._onMenuClick, menuProps: undefined, iconProps: __assign(__assign({}, menuIconProps), { className: this._classNames.menuIcon }), ariaLabel: splitButtonAriaLabel, 'aria-haspopup': true, 'aria-expanded': !menuHidden, 'data-is-focusable': false });
// Add data-ktp-execute-target to the split button if the keytip is defined
return (React.createElement(BaseButton, __assign({}, splitButtonProps, { "data-ktp-execute-target": keytipAttributes ? keytipAttributes['data-ktp-execute-target'] : keytipAttributes, onMouseDown: this._onMouseDown, tabIndex: primaryDisabled && !allowDisabledFocus ? 0 : -1 })));
};
BaseButton.prototype._onPointerDown = function (ev) {
var onPointerDown = this.props.onPointerDown;
if (onPointerDown) {
onPointerDown(ev);
}
if (ev.pointerType === 'touch') {
this._handleTouchAndPointerEvent();
ev.preventDefault();
ev.stopImmediatePropagation();
}
};
BaseButton.prototype._handleTouchAndPointerEvent = function () {
var _this = this;
// If we already have an existing timeout from a previous touch and pointer event
// cancel that timeout so we can set a new one.
if (this._lastTouchTimeoutId !== undefined) {
this._async.clearTimeout(this._lastTouchTimeoutId);
this._lastTouchTimeoutId = undefined;
}
this._processingTouch = true;
this._lastTouchTimeoutId = this._async.setTimeout(function () {
_this._processingTouch = false;
_this._lastTouchTimeoutId = undefined;
// Touch and pointer events don't focus the button naturally,
// so adding an imperative focus call to guarantee this behavior.
// Only focus the button if a splitbutton menu is not open
if (_this.state.menuHidden) {
_this.focus();
}
}, TouchIdleDelay);
};
/**
* Returns if the user hits a valid keyboard key to open the menu
* @param ev - the keyboard event
* @returns True if user clicks on custom trigger key if enabled or alt + down arrow if not. False otherwise.
*/
BaseButton.prototype._isValidMenuOpenKey = function (ev) {
if (this.props.menuTriggerKeyCode) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
return ev.which === this.props.menuTriggerKeyCode;
}
else if (this.props.menuProps) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
return ev.which === KeyCodes.down && (ev.altKey || ev.metaKey);
}
// Note: When enter is pressed, we will let the event continue to propagate
// to trigger the onClick event on the button
return false;
};
BaseButton.defaultProps = {
baseClassName: 'ms-Button',
styles: {},
split: false,
};
// needed to access registeredProviders when manually setting focus visibility
BaseButton.contextType = FocusRectsContext;
return BaseButton;
}(React.Component));
export { BaseButton };
//# sourceMappingURL=BaseButton.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
import type { IButtonStyles } from './Button.types';
import type { ITheme } from '../../Styling';
/**
* Gets the base button styles. Note: because it is a base class to be used with the `mergeRules`
* helper, it should have values for all class names in the interface. This let `mergeRules` optimize
* mixing class names together.
*/
export declare const getStyles: (theme: ITheme) => IButtonStyles;
+107
View File
@@ -0,0 +1,107 @@
import { memoizeFunction } from '../../Utilities';
import { HighContrastSelector, getFocusStyle, hiddenContentStyle } from '../../Styling';
var noOutline = {
outline: 0,
};
var iconStyle = function (fontSize) {
return {
fontSize: fontSize,
margin: '0 4px',
height: '16px',
lineHeight: '16px',
textAlign: 'center',
flexShrink: 0,
};
};
/**
* Gets the base button styles. Note: because it is a base class to be used with the `mergeRules`
* helper, it should have values for all class names in the interface. This let `mergeRules` optimize
* mixing class names together.
*/
export var getStyles = memoizeFunction(function (theme) {
var _a, _b;
var semanticColors = theme.semanticColors, effects = theme.effects, fonts = theme.fonts;
var border = semanticColors.buttonBorder;
var disabledBackground = semanticColors.disabledBackground;
var disabledText = semanticColors.disabledText;
var buttonHighContrastFocus = {
left: -2,
top: -2,
bottom: -2,
right: -2,
outlineColor: 'ButtonText',
};
return {
root: [
getFocusStyle(theme, { inset: 1, highContrastStyle: buttonHighContrastFocus, borderColor: 'transparent' }),
theme.fonts.medium,
{
border: '1px solid ' + border,
borderRadius: effects.roundedCorner2,
boxSizing: 'border-box',
cursor: 'pointer',
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
padding: '0 16px',
textDecoration: 'none',
textAlign: 'center',
userSelect: 'none',
// IE11 workaround for preventing shift of child elements of a button when active.
':active > span': {
position: 'relative',
left: 0,
top: 0,
},
},
],
rootDisabled: [
getFocusStyle(theme, { inset: 1, highContrastStyle: buttonHighContrastFocus, borderColor: 'transparent' }),
{
backgroundColor: disabledBackground,
borderColor: disabledBackground,
color: disabledText,
cursor: 'default',
':hover': noOutline,
':focus': noOutline,
},
],
iconDisabled: (_a = {
color: disabledText
},
_a[HighContrastSelector] = {
color: 'GrayText',
},
_a),
menuIconDisabled: (_b = {
color: disabledText
},
_b[HighContrastSelector] = {
color: 'GrayText',
},
_b),
flexContainer: {
display: 'flex',
height: '100%',
flexWrap: 'nowrap',
justifyContent: 'center',
alignItems: 'center',
},
description: {
display: 'block',
},
textContainer: {
flexGrow: 1,
display: 'block',
},
icon: iconStyle(fonts.mediumPlus.fontSize),
menuIcon: iconStyle(fonts.small.fontSize),
label: {
margin: '0 4px',
lineHeight: '100%',
display: 'block',
},
screenReaderText: hiddenContentStyle,
};
});
//# sourceMappingURL=BaseButton.styles.js.map
File diff suppressed because one or more lines are too long
+12
View File
@@ -0,0 +1,12 @@
import * as React from 'react';
import type { IButtonProps } from './Button.types';
import type { JSXElement } from '@fluentui/utilities';
/**
* This class is deprecated. Use the individual *Button components instead.
* @deprecated Use the individual *Button components instead.
* {@docCategory Button}
*/
export declare class Button extends React.Component<IButtonProps, {}> {
constructor(props: IButtonProps);
render(): JSXElement;
}
+42
View File
@@ -0,0 +1,42 @@
import { __assign, __extends } from "tslib";
import * as React from 'react';
import { warn } from '../../Utilities';
import { ButtonType } from './Button.types';
import { DefaultButton } from './DefaultButton/DefaultButton';
import { ActionButton } from './ActionButton/ActionButton';
import { CompoundButton } from './CompoundButton/CompoundButton';
import { IconButton } from './IconButton/IconButton';
import { PrimaryButton } from './PrimaryButton/PrimaryButton';
/**
* This class is deprecated. Use the individual *Button components instead.
* @deprecated Use the individual *Button components instead.
* {@docCategory Button}
*/
var Button = /** @class */ (function (_super) {
__extends(Button, _super);
function Button(props) {
var _this = _super.call(this, props) || this;
warn("The Button component has been deprecated. Use specific variants instead. " +
"(PrimaryButton, DefaultButton, IconButton, ActionButton, etc.)");
return _this;
}
Button.prototype.render = function () {
var props = this.props;
// eslint-disable-next-line @typescript-eslint/no-deprecated
switch (props.buttonType) {
case ButtonType.command:
return React.createElement(ActionButton, __assign({}, props));
case ButtonType.compound:
return React.createElement(CompoundButton, __assign({}, props));
case ButtonType.icon:
return React.createElement(IconButton, __assign({}, props));
case ButtonType.primary:
return React.createElement(PrimaryButton, __assign({}, props));
default:
return React.createElement(DefaultButton, __assign({}, props));
}
};
return Button;
}(React.Component));
export { Button };
//# sourceMappingURL=Button.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Button.js","sourceRoot":"../src/","sources":["components/Button/Button.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAK9D;;;;GAIG;AACH;IAA4B,0BAAiC;IAC3D,gBAAY,KAAmB;QAC7B,YAAA,MAAK,YAAC,KAAK,CAAC,SAAC;QAEb,IAAI,CACF,2EAA2E;YACzE,gEAAgE,CACnE,CAAC;;IACJ,CAAC;IAEM,uBAAM,GAAb;QACE,IAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAEzB,4DAA4D;QAC5D,QAAQ,KAAK,CAAC,UAAU,EAAE,CAAC;YACzB,KAAK,UAAU,CAAC,OAAO;gBACrB,OAAO,oBAAC,YAAY,eAAK,KAAK,EAAI,CAAC;YAErC,KAAK,UAAU,CAAC,QAAQ;gBACtB,OAAO,oBAAC,cAAc,eAAK,KAAK,EAAI,CAAC;YAEvC,KAAK,UAAU,CAAC,IAAI;gBAClB,OAAO,oBAAC,UAAU,eAAK,KAAK,EAAI,CAAC;YAEnC,KAAK,UAAU,CAAC,OAAO;gBACrB,OAAO,oBAAC,aAAa,eAAK,KAAK,EAAI,CAAC;YAEtC;gBACE,OAAO,oBAAC,aAAa,eAAK,KAAK,EAAI,CAAC;QACxC,CAAC;IACH,CAAC;IACH,aAAC;AAAD,CAAC,AA/BD,CAA4B,KAAK,CAAC,SAAS,GA+B1C","sourcesContent":["import * as React from 'react';\n\nimport { warn } from '../../Utilities';\nimport { ButtonType } from './Button.types';\nimport { DefaultButton } from './DefaultButton/DefaultButton';\nimport { ActionButton } from './ActionButton/ActionButton';\nimport { CompoundButton } from './CompoundButton/CompoundButton';\nimport { IconButton } from './IconButton/IconButton';\nimport { PrimaryButton } from './PrimaryButton/PrimaryButton';\nimport type { IButtonProps } from './Button.types';\n\nimport type { JSXElement } from '@fluentui/utilities';\n\n/**\n * This class is deprecated. Use the individual *Button components instead.\n * @deprecated Use the individual *Button components instead.\n * {@docCategory Button}\n */\nexport class Button extends React.Component<IButtonProps, {}> {\n constructor(props: IButtonProps) {\n super(props);\n\n warn(\n `The Button component has been deprecated. Use specific variants instead. ` +\n `(PrimaryButton, DefaultButton, IconButton, ActionButton, etc.)`,\n );\n }\n\n public render(): JSXElement {\n const props = this.props;\n\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n switch (props.buttonType) {\n case ButtonType.command:\n return <ActionButton {...props} />;\n\n case ButtonType.compound:\n return <CompoundButton {...props} />;\n\n case ButtonType.icon:\n return <IconButton {...props} />;\n\n case ButtonType.primary:\n return <PrimaryButton {...props} />;\n\n default:\n return <DefaultButton {...props} />;\n }\n }\n}\n"]}
+522
View File
@@ -0,0 +1,522 @@
import * as React from 'react';
import { BaseButton } from './BaseButton';
import { Button } from './Button';
import { KeyCodes } from '../../Utilities';
import type { IButtonClassNames } from './BaseButton.classNames';
import type { ISplitButtonClassNames } from './SplitButton/SplitButton.classNames';
import type { IRefObject, IRenderFunction, IComponentAs } from '../../Utilities';
import type { IContextualMenuProps } from '../../ContextualMenu';
import type { IIconProps } from '../../Icon';
import type { IShadowDomStyle, IStyle, ITheme } from '../../Styling';
import type { IKeytipProps } from '../../Keytip';
/**
* {@docCategory Button}
*/
export interface IButton {
/**
* Sets focus to the button.
*/
focus: () => void;
/**
* If there is a menu associated with this button and it is visible, this will dismiss the menu
*/
dismissMenu: () => void;
/**
* If there is a menu associated with this button and it is visible, this will open the menu.
* Params are optional overrides to the ones defined in `menuProps` to apply to just this instance of
* opening the menu.
*
* @param shouldFocusOnContainer - override to the ContextualMenu `shouldFocusOnContainer` prop.
* BaseButton implementation defaults to `undefined`.
* Avoid using `shouldFocusOnContainer` as it breaks the default focus behaviour when using
* assistive technologies.
* @param shouldFocusOnMount - override to the ContextualMenu `shouldFocusOnMount` prop.
* BaseButton implementation defaults to `true`.
*/
openMenu: (shouldFocusOnContainer?: boolean, shouldFocusOnMount?: boolean) => void;
}
/**
* {@docCategory Button}
*/
export interface IButtonProps extends React.AllHTMLAttributes<HTMLAnchorElement | HTMLButtonElement | HTMLDivElement | BaseButton | Button | HTMLSpanElement> {
/**
* Optional callback to access the `IButton` interface. Use this instead of `ref` for accessing
* the public methods and properties of the component.
*/
componentRef?: IRefObject<IButton>;
/**
* Optional callback to access the root DOM element.
* @deprecated Temporary solution which will be replaced with ref in the V8 release.
*/
elementRef?: React.Ref<HTMLElement>;
/**
* If provided, this component will be rendered as an anchor.
* @defaultvalue ElementType.anchor
*/
href?: string;
/**
* Changes the visual presentation of the button to be emphasized.
* @defaultvalue false
*/
primary?: boolean;
/**
* Unique ID to identify the item. Typically a duplicate of key value.
*/
uniqueId?: string | number;
/**
* Whether the button is disabled
*/
disabled?: boolean;
/**
* Whether the button can have focus in disabled mode
*/
allowDisabledFocus?: boolean;
/**
* If set to true and this is a split button (`split` is true), the split button's primary action is disabled.
*/
primaryDisabled?: boolean;
/**
* Custom styling for individual elements within the button DOM.
*/
styles?: IButtonStyles;
/**
* Theme provided by HOC.
*/
theme?: ITheme;
/**
* Whether the button is checked. Should be used with the `toggle` attribute when creating a standalone on/off button.
*/
checked?: boolean;
/**
* Whether button is a toggle button with distinct on and off states. This should be true for buttons that permanently
* change state when a press event finishes, such as a volume mute button.
*/
toggle?: boolean;
/**
* If provided, additional class name to provide on the root element.
*/
className?: string;
/**
* The aria label of the button for the benefit of screen readers.
*/
ariaLabel?: string;
/**
* Detailed description of the button for the benefit of screen readers.
*
* Besides the compound button, other button types will need more information provided to screen reader.
*/
ariaDescription?: string;
/**
* If true, add an `aria-hidden` attribute instructing screen readers to ignore the element.
*/
ariaHidden?: boolean;
/**
* Text to render button label. If text is supplied, it will override any string in button children.
* Other children components will be passed through after the text.
*/
text?: string;
/**
* The props for the icon shown in the button.
*/
iconProps?: IIconProps;
/**
* Props for button menu. Providing this will default to showing the menu icon. See `menuIconProps` for overriding
* how the default icon looks. Providing this in addition to `onClick` and setting the `split` property to `true`
* will render a SplitButton.
*/
menuProps?: IContextualMenuProps;
/**
* Callback that runs after Button's contextual menu was closed (removed from the DOM)
*/
onAfterMenuDismiss?: () => void;
/**
* If set to true, and if `menuProps` and `onClick` are provided, the button will render as a SplitButton.
* @default false
*/
split?: boolean;
/**
* The props for the icon shown when providing a menu dropdown.
*/
menuIconProps?: IIconProps;
/**
* Accessible label for the dropdown chevron button if this button is split.
*/
splitButtonAriaLabel?: string;
/**
* Optional callback when menu is clicked.
*/
onMenuClick?: (ev?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>, button?: IButtonProps) => void;
/**
* Custom render function for the icon
*/
onRenderIcon?: IRenderFunction<IButtonProps>;
/**
* Custom render function for the label text.
*/
onRenderText?: IRenderFunction<IButtonProps>;
/**
* Custom render function for the description text.
*/
onRenderDescription?: IRenderFunction<IButtonProps>;
/**
* Custom render function for the aria description element.
*/
onRenderAriaDescription?: IRenderFunction<IButtonProps>;
/**
* Custom render function for rendering the button children.
*/
onRenderChildren?: IRenderFunction<IButtonProps>;
/**
* Custom render function for button menu icon
*/
onRenderMenuIcon?: IRenderFunction<IButtonProps>;
/**
* @deprecated Deprecated at v6.3.2, to be removed at \>= v7.0.0.
* Use `menuAs` instead.
*/
onRenderMenu?: IRenderFunction<IContextualMenuProps>;
/**
* Render a custom menu in place of the normal one.
*/
menuAs?: IComponentAs<IContextualMenuProps>;
/**
* Description of the action this button takes.
* Only used for compound buttons.
*/
secondaryText?: string;
/**
* @defaultvalue ButtonType.default
* @deprecated Deprecated at v1.2.3, to be removed at \>= v2.0.0.
* Use specific button component instead.
*/
buttonType?: ButtonType;
/**
* @deprecated Deprecated at v0.56.2, to be removed at \>= v1.0.0.
* Use native props on the Button itself instead.
* They will be mixed into the button/anchor element rendered by the component.
*/
rootProps?: React.ButtonHTMLAttributes<HTMLButtonElement> | React.AnchorHTMLAttributes<HTMLAnchorElement>;
/**
* @deprecated No longer used. Use `checked` if setting state.
*/
toggled?: boolean;
/**
* Any custom data the developer wishes to associate with the button.
*/
data?: any;
/**
* Method to provide the classnames to style a button.
* The default value for this prop is the `getClassnames` func defined in `BaseButton.classnames.ts`.
* @defaultvalue getBaseButtonClassNames
*/
getClassNames?: (theme: ITheme, className: string, variantClassName: string, iconClassName: string | undefined, menuIconClassName: string | undefined, disabled: boolean, checked: boolean, expanded: boolean, hasMenu: boolean, isSplit: boolean | undefined, allowDisabledFocus: boolean) => IButtonClassNames;
/**
* Method to provide the classnames to style a button.
* The default value for this prop is the `getClassnames` func defined in `BaseButton.classnames.ts`.
* @defaultvalue getBaseSplitButtonClassNames
*/
getSplitButtonClassNames?: (disabled: boolean, expanded: boolean, checked: boolean, allowDisabledFocus: boolean) => ISplitButtonClassNames;
/**
* Provides a custom KeyCode that can be used to open the button menu.
* A value of `null` can be provided to disable opening the button menu with a key press.
* @default KeyCodes.down
*/
menuTriggerKeyCode?: KeyCodes | null;
/**
* Optional keytip for this button
*/
keytipProps?: IKeytipProps;
/**
* Menu will not be created or destroyed when opened or closed, instead it
* will be hidden. This will improve perf of the menu opening but could potentially
* impact overall perf by having more elements in the dom. Should only be used
* when menu perf is important.
*
* Note: This may increase the amount of time it takes for the button itself to mount.
*/
persistMenu?: boolean;
/**
* If true, the persisted menu is rendered hidden when the button initially mounts.
* Non-persisted menus will not be in the component tree unless they are being shown.
*
* Note: This increases the time the button will take to mount, but
* can improve perceived menu open perf. when the user opens the menu.
*
* @defaultvalue `undefined`, equivalent to false
*
* @deprecated There is known bug in Edge when this prop is true where scrollbars
* overlap with the content when a menu is first rendered hidden.
* Please do not start using this. If you are already using this,
* please make sure that you are doing so only in non-Edge browsers.
* See: https://github.com/microsoft/fluentui/issues/9034
*/
renderPersistedMenuHiddenOnMount?: boolean;
/**
* Experimental prop that get passed into the menuButton that's rendered as part of
* split button. Anything passed in will likely need to have accompanying
* style changes.
*/
splitButtonMenuProps?: IButtonProps;
/**
* Style for the description text if applicable (for compound buttons).
* @deprecated Use `secondaryText` instead.
*/
description?: string;
/**
* yet unknown docs
*/
defaultRender?: any;
/**
* Optional props to be applied only to the primary action button of SplitButton and not to the
* overall SplitButton container
*/
primaryActionButtonProps?: IButtonProps;
}
/**
* {@docCategory Button}
*/
export declare enum ElementType {
/** `button` element. */
button = 0,
/** `a` element. */
anchor = 1
}
/**
* {@docCategory Button}
*/
export declare enum ButtonType {
normal = 0,
primary = 1,
hero = 2,
compound = 3,
command = 4,
icon = 5,
default = 6
}
/**
* {@docCategory Button}
*/
export interface IButtonStyles extends IShadowDomStyle {
/**
* Style for the root element in the default enabled, non-toggled state.
*/
root?: IStyle;
/**
* Style override for the root element in a checked state, layered on top of the root style.
*/
rootChecked?: IStyle;
/**
* Style override for the root element in a disabled state, layered on top of the root style.
*/
rootDisabled?: IStyle;
/**
* Style override applied to the root on hover in the default, enabled, non-toggled state.
*/
rootHovered?: IStyle;
/**
* Style override applied to the root on focus in the default, enabled, non-toggled state.
*/
rootFocused?: IStyle;
/**
* Style override applied to the root on pressed in the default, enabled, non-toggled state.
*/
rootPressed?: IStyle;
/**
* Style override applied to the root on when menu is expanded in the default, enabled, non-toggled state.
*/
rootExpanded?: IStyle;
/**
* Style override applied to the root on hover in a checked, enabled state
*/
rootCheckedHovered?: IStyle;
/**
* Style override applied to the root on pressed in a checked, enabled state
*/
rootCheckedPressed?: IStyle;
/**
* Style override applied to the root on hover in a checked, disabled state
*/
rootCheckedDisabled?: IStyle;
/**
* Style override applied to the root on hover in a expanded state on hover
*/
rootExpandedHovered?: IStyle;
/**
* Style override for the root element when it has a menu button, layered on top of the root style.
*/
rootHasMenu?: IStyle;
/**
* Style for the flexbox container within the root element.
*/
flexContainer?: IStyle;
/**
* Style for the text container within the flexbox container element (and contains the text and description).
*/
textContainer?: IStyle;
/**
* Style for the icon on the near side of the label.
*/
icon?: IStyle;
/**
* Style for the icon on the near side of the label on hover.
*/
iconHovered?: IStyle;
/**
* Style for the icon on the near side of the label when pressed.
*/
iconPressed?: IStyle;
/**
* Style for the icon on the near side of the label when expanded.
*/
iconExpanded?: IStyle;
/**
* Style for the icon on the near side of the label when expanded and hovered.
*/
iconExpandedHovered?: IStyle;
/**
* Style override for the icon when the button is disabled.
*/
iconDisabled?: IStyle;
/**
* Style override for the icon when the button is checked.
*/
iconChecked?: IStyle;
/**
* Style for the text content of the button.
*/
label?: IStyle;
/**
* Style override for the text content when the button is hovered.
*/
labelHovered?: IStyle;
/**
* Style override for the text content when the button is disabled.
*/
labelDisabled?: IStyle;
/**
* Style override for the text content when the button is checked.
*/
labelChecked?: IStyle;
/**
* Style for the menu chevron.
*/
menuIcon?: IStyle;
/**
* Style for the menu chevron on hover.
*/
menuIconHovered?: IStyle;
/**
* Style for the menu chevron when pressed.
*/
menuIconPressed?: IStyle;
/**
* Style for the menu chevron when expanded.
*/
menuIconExpanded?: IStyle;
/**
* Style for the menu chevron when expanded and hovered.
*/
menuIconExpandedHovered?: IStyle;
/**
* Style override for the menu chevron when the button is disabled.
*/
menuIconDisabled?: IStyle;
/**
* Style override for the menu chevron when the button is checked.
*/
menuIconChecked?: IStyle;
/**
* Style for the description text if applicable (for compound buttons).
*/
description?: IStyle;
/**
* Style for the description text if applicable (for compound buttons).
*/
secondaryText?: IStyle;
/**
* Style override for the description text when the button is hovered.
*/
descriptionHovered?: IStyle;
/**
* Style for the description text when the button is pressed.
*/
descriptionPressed?: IStyle;
/**
* Style override for the description text when the button is disabled.
*/
descriptionDisabled?: IStyle;
/**
* Style override for the description text when the button is checked.
*/
descriptionChecked?: IStyle;
/**
* Style override for the screen reader text.
*/
screenReaderText?: IStyle;
/**
* Style override for the container div around a SplitButton element
*/
splitButtonContainer?: IStyle;
/**
* Style for container div around a SplitButton element when the button is hovered.
*/
splitButtonContainerHovered?: IStyle;
/**
* Style for container div around a SplitButton element when the button is focused.
*/
splitButtonContainerFocused?: IStyle;
/**
* Style for container div around a SplitButton element when the button is checked.
*/
splitButtonContainerChecked?: IStyle;
/**
* Style for container div around a SplitButton element when the button is checked and hovered.
*/
splitButtonContainerCheckedHovered?: IStyle;
/**
* Style override for the container div around a SplitButton element in a disabled state
*/
splitButtonContainerDisabled?: IStyle;
/**
* Style override for the divider element that appears between the button and menu button
* for a split button.
*/
splitButtonDivider?: IStyle;
/**
* Style override for the divider element that appears between the button and menu button
* for a split button in a disabled state.
*/
splitButtonDividerDisabled?: IStyle;
/**
* Style override for the SplitButton menu button
*/
splitButtonMenuButton?: IStyle;
/**
* Style override for the SplitButton menu button element in a disabled state.
*/
splitButtonMenuButtonDisabled?: IStyle;
/**
* Style override for the SplitButton menu button element in a checked state
*/
splitButtonMenuButtonChecked?: IStyle;
/**
* Style override for the SplitButton menu button element in an expanded state
*/
splitButtonMenuButtonExpanded?: IStyle;
/**
* Style override for the SplitButton menu icon element
*/
splitButtonMenuIcon?: IStyle;
/**
* Style override for the SplitButton menu icon element in a disabled state
*/
splitButtonMenuIconDisabled?: IStyle;
/**
* Style override for the SplitButton FlexContainer.
*/
splitButtonFlexContainer?: IStyle;
/**
* Style override for the SplitButton when only primaryButton is in a disabled state
*/
splitButtonMenuFocused?: IStyle;
}
+24
View File
@@ -0,0 +1,24 @@
/**
* {@docCategory Button}
*/
export var ElementType;
(function (ElementType) {
/** `button` element. */
ElementType[ElementType["button"] = 0] = "button";
/** `a` element. */
ElementType[ElementType["anchor"] = 1] = "anchor";
})(ElementType || (ElementType = {}));
/**
* {@docCategory Button}
*/
export var ButtonType;
(function (ButtonType) {
ButtonType[ButtonType["normal"] = 0] = "normal";
ButtonType[ButtonType["primary"] = 1] = "primary";
ButtonType[ButtonType["hero"] = 2] = "hero";
ButtonType[ButtonType["compound"] = 3] = "compound";
ButtonType[ButtonType["command"] = 4] = "command";
ButtonType[ButtonType["icon"] = 5] = "icon";
ButtonType[ButtonType["default"] = 6] = "default";
})(ButtonType || (ButtonType = {}));
//# sourceMappingURL=Button.types.js.map
File diff suppressed because one or more lines are too long
+4
View File
@@ -0,0 +1,4 @@
import type { IButtonStyles } from './Button.types';
import type { ITheme } from '../../Styling';
export declare function standardStyles(theme: ITheme): IButtonStyles;
export declare function primaryStyles(theme: ITheme): IButtonStyles;
+225
View File
@@ -0,0 +1,225 @@
import { __assign } from "tslib";
import { HighContrastSelector, getHighContrastNoAdjustStyle } from '../../Styling';
import { IsFocusVisibleClassName } from '../../Utilities';
var splitButtonDividerBaseStyles = function () {
return {
position: 'absolute',
width: 1,
right: 31,
top: 8,
bottom: 8,
};
};
export function standardStyles(theme) {
var _a, _b, _c, _d, _e;
var s = theme.semanticColors, p = theme.palette;
var buttonBackground = s.buttonBackground;
var buttonBackgroundPressed = s.buttonBackgroundPressed;
var buttonBackgroundHovered = s.buttonBackgroundHovered;
var buttonBackgroundDisabled = s.buttonBackgroundDisabled;
var buttonText = s.buttonText;
var buttonTextHovered = s.buttonTextHovered;
var buttonTextDisabled = s.buttonTextDisabled;
var buttonTextChecked = s.buttonTextChecked;
var buttonTextCheckedHovered = s.buttonTextCheckedHovered;
return {
root: {
backgroundColor: buttonBackground,
color: buttonText,
},
rootHovered: (_a = {
backgroundColor: buttonBackgroundHovered,
color: buttonTextHovered
},
_a[HighContrastSelector] = {
borderColor: 'Highlight',
color: 'Highlight',
},
_a),
rootPressed: {
backgroundColor: buttonBackgroundPressed,
color: buttonTextChecked,
},
rootExpanded: {
backgroundColor: buttonBackgroundPressed,
color: buttonTextChecked,
},
rootChecked: {
backgroundColor: buttonBackgroundPressed,
color: buttonTextChecked,
},
rootCheckedHovered: {
backgroundColor: buttonBackgroundPressed,
color: buttonTextCheckedHovered,
},
rootDisabled: (_b = {
color: buttonTextDisabled,
backgroundColor: buttonBackgroundDisabled
},
_b[HighContrastSelector] = {
color: 'GrayText',
borderColor: 'GrayText',
backgroundColor: 'Window',
},
_b),
// Split button styles
splitButtonContainer: (_c = {},
_c[HighContrastSelector] = {
border: 'none',
},
_c),
splitButtonMenuButton: {
color: p.white,
backgroundColor: 'transparent',
':hover': (_d = {
backgroundColor: p.neutralLight
},
_d[HighContrastSelector] = {
color: 'Highlight',
},
_d),
},
splitButtonMenuButtonDisabled: {
backgroundColor: s.buttonBackgroundDisabled,
':hover': {
backgroundColor: s.buttonBackgroundDisabled,
},
},
splitButtonDivider: __assign(__assign({}, splitButtonDividerBaseStyles()), (_e = { backgroundColor: p.neutralTertiaryAlt }, _e[HighContrastSelector] = {
backgroundColor: 'WindowText',
}, _e)),
splitButtonDividerDisabled: {
backgroundColor: theme.palette.neutralTertiaryAlt,
},
splitButtonMenuButtonChecked: {
backgroundColor: p.neutralQuaternaryAlt,
':hover': {
backgroundColor: p.neutralQuaternaryAlt,
},
},
splitButtonMenuButtonExpanded: {
backgroundColor: p.neutralQuaternaryAlt,
':hover': {
backgroundColor: p.neutralQuaternaryAlt,
},
},
splitButtonMenuIcon: {
color: s.buttonText,
},
splitButtonMenuIconDisabled: {
color: s.buttonTextDisabled,
},
};
}
export function primaryStyles(theme) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
var p = theme.palette, s = theme.semanticColors;
return {
root: (_a = {
backgroundColor: s.primaryButtonBackground,
border: "1px solid ".concat(s.primaryButtonBackground),
color: s.primaryButtonText
},
_a[HighContrastSelector] = __assign({ color: 'Window', backgroundColor: 'WindowText', borderColor: 'WindowText' }, getHighContrastNoAdjustStyle()),
_a[".".concat(IsFocusVisibleClassName, " &:focus, :host(.").concat(IsFocusVisibleClassName, ") &:focus")] = {
':after': {
border: "none",
outlineColor: p.white,
},
},
_a),
rootHovered: (_b = {
backgroundColor: s.primaryButtonBackgroundHovered,
border: "1px solid ".concat(s.primaryButtonBackgroundHovered),
color: s.primaryButtonTextHovered
},
_b[HighContrastSelector] = {
color: 'Window',
backgroundColor: 'Highlight',
borderColor: 'Highlight',
},
_b),
rootPressed: (_c = {
backgroundColor: s.primaryButtonBackgroundPressed,
border: "1px solid ".concat(s.primaryButtonBackgroundPressed),
color: s.primaryButtonTextPressed
},
_c[HighContrastSelector] = __assign({ color: 'Window', backgroundColor: 'WindowText', borderColor: 'WindowText' }, getHighContrastNoAdjustStyle()),
_c),
rootExpanded: {
backgroundColor: s.primaryButtonBackgroundPressed,
color: s.primaryButtonTextPressed,
},
rootChecked: {
backgroundColor: s.primaryButtonBackgroundPressed,
color: s.primaryButtonTextPressed,
},
rootCheckedHovered: {
backgroundColor: s.primaryButtonBackgroundPressed,
color: s.primaryButtonTextPressed,
},
rootDisabled: (_d = {
color: s.primaryButtonTextDisabled,
backgroundColor: s.primaryButtonBackgroundDisabled
},
_d[HighContrastSelector] = {
color: 'GrayText',
borderColor: 'GrayText',
backgroundColor: 'Window',
},
_d),
// Split button styles
splitButtonContainer: (_e = {},
_e[HighContrastSelector] = {
border: 'none',
},
_e),
splitButtonDivider: __assign(__assign({}, splitButtonDividerBaseStyles()), (_f = { backgroundColor: p.white }, _f[HighContrastSelector] = {
backgroundColor: 'Window',
}, _f)),
splitButtonMenuButton: (_g = {
backgroundColor: s.primaryButtonBackground,
color: s.primaryButtonText
},
_g[HighContrastSelector] = {
backgroundColor: 'Canvas',
},
_g[':hover'] = (_h = {
backgroundColor: s.primaryButtonBackgroundHovered
},
_h[HighContrastSelector] = {
color: 'Highlight',
},
_h),
_g),
splitButtonMenuButtonDisabled: {
backgroundColor: s.primaryButtonBackgroundDisabled,
':hover': {
backgroundColor: s.primaryButtonBackgroundDisabled,
},
},
splitButtonMenuButtonChecked: {
backgroundColor: s.primaryButtonBackgroundPressed,
':hover': {
backgroundColor: s.primaryButtonBackgroundPressed,
},
},
splitButtonMenuButtonExpanded: {
backgroundColor: s.primaryButtonBackgroundPressed,
':hover': {
backgroundColor: s.primaryButtonBackgroundPressed,
},
},
splitButtonMenuIcon: {
color: s.primaryButtonText,
},
splitButtonMenuIconDisabled: (_j = {
color: p.neutralTertiary
},
_j[HighContrastSelector] = {
color: 'GrayText',
},
_j),
};
}
//# sourceMappingURL=ButtonThemes.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,9 @@
import * as React from 'react';
import type { IButtonProps } from '../Button.types';
import type { JSXElement } from '@fluentui/utilities';
/**
* {@docCategory Button}
*/
export declare class CommandBarButton extends React.Component<IButtonProps, {}> {
render(): JSXElement;
}
@@ -0,0 +1,24 @@
import { __assign, __decorate, __extends } from "tslib";
import * as React from 'react';
import { BaseButton } from '../BaseButton';
import { customizable, nullRender } from '../../../Utilities';
import { getStyles } from './CommandBarButton.styles';
/**
* {@docCategory Button}
*/
var CommandBarButton = /** @class */ (function (_super) {
__extends(CommandBarButton, _super);
function CommandBarButton() {
return _super !== null && _super.apply(this, arguments) || this;
}
CommandBarButton.prototype.render = function () {
var _a = this.props, styles = _a.styles, theme = _a.theme;
return (React.createElement(BaseButton, __assign({}, this.props, { variantClassName: "ms-Button--commandBar", styles: getStyles(theme, styles), onRenderDescription: nullRender })));
};
CommandBarButton = __decorate([
customizable('CommandBarButton', ['theme', 'styles'], true)
], CommandBarButton);
return CommandBarButton;
}(React.Component));
export { CommandBarButton };
//# sourceMappingURL=CommandBarButton.js.map
@@ -0,0 +1 @@
{"version":3,"file":"CommandBarButton.js","sourceRoot":"../src/","sources":["components/Button/CommandBarButton/CommandBarButton.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAKtD;;GAEG;AAEH;IAAsC,oCAAiC;IAAvE;;IAaA,CAAC;IAZQ,iCAAM,GAAb;QACQ,IAAA,KAAoB,IAAI,CAAC,KAAK,EAA5B,MAAM,YAAA,EAAE,KAAK,WAAe,CAAC;QAErC,OAAO,CACL,oBAAC,UAAU,eACL,IAAI,CAAC,KAAK,IACd,gBAAgB,EAAC,uBAAuB,EACxC,MAAM,EAAE,SAAS,CAAC,KAAM,EAAE,MAAM,CAAC,EACjC,mBAAmB,EAAE,UAAU,IAC/B,CACH,CAAC;IACJ,CAAC;IAZU,gBAAgB;QAD5B,YAAY,CAAC,kBAAkB,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC;OAC/C,gBAAgB,CAa5B;IAAD,uBAAC;CAAA,AAbD,CAAsC,KAAK,CAAC,SAAS,GAapD;SAbY,gBAAgB","sourcesContent":["import * as React from 'react';\nimport { BaseButton } from '../BaseButton';\nimport { customizable, nullRender } from '../../../Utilities';\nimport { getStyles } from './CommandBarButton.styles';\nimport type { IButtonProps } from '../Button.types';\n\nimport type { JSXElement } from '@fluentui/utilities';\n\n/**\n * {@docCategory Button}\n */\n@customizable('CommandBarButton', ['theme', 'styles'], true)\nexport class CommandBarButton extends React.Component<IButtonProps, {}> {\n public render(): JSXElement {\n const { styles, theme } = this.props;\n\n return (\n <BaseButton\n {...this.props}\n variantClassName=\"ms-Button--commandBar\"\n styles={getStyles(theme!, styles)}\n onRenderDescription={nullRender}\n />\n );\n }\n}\n"]}
@@ -0,0 +1,3 @@
import type { IButtonStyles } from '../Button.types';
import type { ITheme } from '../../../Styling';
export declare const getStyles: (theme: ITheme, customStyles?: IButtonStyles, focusInset?: string, focusColor?: string) => IButtonStyles;
@@ -0,0 +1,188 @@
import { __assign } from "tslib";
import { concatStyleSets, getFocusStyle, HighContrastSelector, getHighContrastNoAdjustStyle } from '../../../Styling';
import { memoizeFunction } from '../../../Utilities';
import { getStyles as getBaseButtonStyles } from '../BaseButton.styles';
import { getStyles as getSplitButtonStyles } from '../SplitButton/SplitButton.styles';
import { ButtonGlobalClassNames } from '../BaseButton.classNames';
export var getStyles = memoizeFunction(function (theme, customStyles, focusInset, focusColor) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
var baseButtonStyles = getBaseButtonStyles(theme);
var baseSplitButtonStyles = getSplitButtonStyles(theme);
var p = theme.palette, semanticColors = theme.semanticColors;
var commandButtonHighContrastFocus = {
left: 4,
top: 4,
bottom: 4,
right: 4,
border: 'none',
};
var commandButtonStyles = {
root: [
getFocusStyle(theme, {
inset: 2,
highContrastStyle: commandButtonHighContrastFocus,
borderColor: 'transparent',
}),
theme.fonts.medium,
(_a = {
minWidth: '40px',
backgroundColor: p.white,
color: p.neutralPrimary,
padding: '0 4px',
border: 'none',
borderRadius: 0
},
_a[HighContrastSelector] = {
border: 'none',
},
_a),
],
rootHovered: (_b = {
backgroundColor: p.neutralLighter,
color: p.neutralDark
},
_b[HighContrastSelector] = {
color: 'Highlight',
},
_b[".".concat(ButtonGlobalClassNames.msButtonIcon)] = {
color: p.themeDarkAlt,
},
_b[".".concat(ButtonGlobalClassNames.msButtonMenuIcon)] = {
color: p.neutralPrimary,
},
_b),
rootPressed: (_c = {
backgroundColor: p.neutralLight,
color: p.neutralDark
},
_c[".".concat(ButtonGlobalClassNames.msButtonIcon)] = {
color: p.themeDark,
},
_c[".".concat(ButtonGlobalClassNames.msButtonMenuIcon)] = {
color: p.neutralPrimary,
},
_c),
rootChecked: (_d = {
backgroundColor: p.neutralLight,
color: p.neutralDark
},
_d[".".concat(ButtonGlobalClassNames.msButtonIcon)] = {
color: p.themeDark,
},
_d[".".concat(ButtonGlobalClassNames.msButtonMenuIcon)] = {
color: p.neutralPrimary,
},
_d),
rootCheckedHovered: (_e = {
backgroundColor: p.neutralQuaternaryAlt
},
_e[".".concat(ButtonGlobalClassNames.msButtonIcon)] = {
color: p.themeDark,
},
_e[".".concat(ButtonGlobalClassNames.msButtonMenuIcon)] = {
color: p.neutralPrimary,
},
_e),
rootExpanded: (_f = {
backgroundColor: p.neutralLight,
color: p.neutralDark
},
_f[".".concat(ButtonGlobalClassNames.msButtonIcon)] = {
color: p.themeDark,
},
_f[".".concat(ButtonGlobalClassNames.msButtonMenuIcon)] = {
color: p.neutralPrimary,
},
_f),
rootExpandedHovered: {
backgroundColor: p.neutralQuaternaryAlt,
},
rootDisabled: (_g = {
backgroundColor: p.white
},
_g[".".concat(ButtonGlobalClassNames.msButtonIcon)] = (_h = {
color: semanticColors.disabledBodySubtext
},
_h[HighContrastSelector] = __assign({ color: 'GrayText' }, getHighContrastNoAdjustStyle()),
_h),
_g[HighContrastSelector] = __assign({ color: 'GrayText', backgroundColor: 'Window' }, getHighContrastNoAdjustStyle()),
_g),
// Split button styles
splitButtonContainer: (_j = {
height: '100%'
},
_j[HighContrastSelector] = {
border: 'none',
},
_j),
splitButtonDividerDisabled: (_k = {},
_k[HighContrastSelector] = {
backgroundColor: 'Window',
},
_k),
splitButtonDivider: {
backgroundColor: p.neutralTertiaryAlt,
},
splitButtonMenuButton: {
backgroundColor: p.white,
border: 'none',
borderTopRightRadius: '0',
borderBottomRightRadius: '0',
color: p.neutralSecondary,
':hover': (_l = {
backgroundColor: p.neutralLighter,
color: p.neutralDark
},
_l[HighContrastSelector] = {
color: 'Highlight',
},
_l[".".concat(ButtonGlobalClassNames.msButtonIcon)] = {
color: p.neutralPrimary,
},
_l),
':active': (_m = {
backgroundColor: p.neutralLight
},
_m[".".concat(ButtonGlobalClassNames.msButtonIcon)] = {
color: p.neutralPrimary,
},
_m),
},
splitButtonMenuButtonDisabled: (_o = {
backgroundColor: p.white
},
_o[HighContrastSelector] = __assign({ color: 'GrayText', border: 'none', backgroundColor: 'Window' }, getHighContrastNoAdjustStyle()),
_o),
splitButtonMenuButtonChecked: {
backgroundColor: p.neutralLight,
color: p.neutralDark,
':hover': {
backgroundColor: p.neutralQuaternaryAlt,
},
},
splitButtonMenuButtonExpanded: {
backgroundColor: p.neutralLight,
color: p.black,
':hover': {
backgroundColor: p.neutralQuaternaryAlt,
},
},
splitButtonMenuIcon: {
color: p.neutralPrimary,
},
splitButtonMenuIconDisabled: {
color: p.neutralTertiary,
},
label: {
fontWeight: 'normal', // theme.fontWeights.semibold,
},
icon: {
color: p.themePrimary,
},
menuIcon: {
color: p.neutralSecondary,
},
};
return concatStyleSets(baseButtonStyles, baseSplitButtonStyles, commandButtonStyles, customStyles);
});
//# sourceMappingURL=CommandBarButton.styles.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,5 @@
import { ActionButton } from '../ActionButton/ActionButton';
/**
* {@docCategory Button}
*/
export declare const CommandButton: typeof ActionButton;
@@ -0,0 +1,6 @@
import { ActionButton } from '../ActionButton/ActionButton';
/**
* {@docCategory Button}
*/
export var CommandButton = ActionButton;
//# sourceMappingURL=CommandButton.js.map
@@ -0,0 +1 @@
{"version":3,"file":"CommandButton.js","sourceRoot":"../src/","sources":["components/Button/CommandButton/CommandButton.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE5D;;GAEG;AACH,MAAM,CAAC,IAAM,aAAa,GAAG,YAAY,CAAC","sourcesContent":["import { ActionButton } from '../ActionButton/ActionButton';\n\n/**\n * {@docCategory Button}\n */\nexport const CommandButton = ActionButton;\n"]}
@@ -0,0 +1,9 @@
import * as React from 'react';
import type { IButtonProps } from '../Button.types';
import type { JSXElement } from '@fluentui/utilities';
/**
* {@docCategory Button}
*/
export declare class CompoundButton extends React.Component<IButtonProps, {}> {
render(): JSXElement;
}
@@ -0,0 +1,24 @@
import { __assign, __decorate, __extends } from "tslib";
import * as React from 'react';
import { BaseButton } from '../BaseButton';
import { customizable } from '../../../Utilities';
import { getStyles } from './CompoundButton.styles';
/**
* {@docCategory Button}
*/
var CompoundButton = /** @class */ (function (_super) {
__extends(CompoundButton, _super);
function CompoundButton() {
return _super !== null && _super.apply(this, arguments) || this;
}
CompoundButton.prototype.render = function () {
var _a = this.props, _b = _a.primary, primary = _b === void 0 ? false : _b, styles = _a.styles, theme = _a.theme;
return (React.createElement(BaseButton, __assign({}, this.props, { variantClassName: primary ? 'ms-Button--compoundPrimary' : 'ms-Button--compound', styles: getStyles(theme, styles, primary) })));
};
CompoundButton = __decorate([
customizable('CompoundButton', ['theme', 'styles'], true)
], CompoundButton);
return CompoundButton;
}(React.Component));
export { CompoundButton };
//# sourceMappingURL=CompoundButton.js.map
@@ -0,0 +1 @@
{"version":3,"file":"CompoundButton.js","sourceRoot":"../src/","sources":["components/Button/CompoundButton/CompoundButton.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAKpD;;GAEG;AAEH;IAAoC,kCAAiC;IAArE;;IAWA,CAAC;IAVQ,+BAAM,GAAb;QACQ,IAAA,KAAqC,IAAI,CAAC,KAAK,EAA7C,eAAe,EAAf,OAAO,mBAAG,KAAK,KAAA,EAAE,MAAM,YAAA,EAAE,KAAK,WAAe,CAAC;QACtD,OAAO,CACL,oBAAC,UAAU,eACL,IAAI,CAAC,KAAK,IACd,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,qBAAqB,EAChF,MAAM,EAAE,SAAS,CAAC,KAAM,EAAE,MAAM,EAAE,OAAO,CAAC,IAC1C,CACH,CAAC;IACJ,CAAC;IAVU,cAAc;QAD1B,YAAY,CAAC,gBAAgB,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC;OAC7C,cAAc,CAW1B;IAAD,qBAAC;CAAA,AAXD,CAAoC,KAAK,CAAC,SAAS,GAWlD;SAXY,cAAc","sourcesContent":["import * as React from 'react';\nimport { BaseButton } from '../BaseButton';\nimport { customizable } from '../../../Utilities';\nimport { getStyles } from './CompoundButton.styles';\nimport type { IButtonProps } from '../Button.types';\n\nimport type { JSXElement } from '@fluentui/utilities';\n\n/**\n * {@docCategory Button}\n */\n@customizable('CompoundButton', ['theme', 'styles'], true)\nexport class CompoundButton extends React.Component<IButtonProps, {}> {\n public render(): JSXElement {\n const { primary = false, styles, theme } = this.props;\n return (\n <BaseButton\n {...this.props}\n variantClassName={primary ? 'ms-Button--compoundPrimary' : 'ms-Button--compound'}\n styles={getStyles(theme!, styles, primary)}\n />\n );\n }\n}\n"]}
@@ -0,0 +1,3 @@
import type { IButtonStyles } from '../Button.types';
import type { ITheme } from '../../../Styling';
export declare const getStyles: (theme: ITheme, customStyles?: IButtonStyles, primary?: boolean) => IButtonStyles;
@@ -0,0 +1,99 @@
import { __assign } from "tslib";
import { concatStyleSets, FontWeights, HighContrastSelector, getHighContrastNoAdjustStyle } from '../../../Styling';
import { memoizeFunction } from '../../../Utilities';
import { getStyles as getBaseButtonStyles } from '../BaseButton.styles';
import { getStyles as getSplitButtonStyles } from '../SplitButton/SplitButton.styles';
import { primaryStyles, standardStyles } from '../ButtonThemes';
export var getStyles = memoizeFunction(function (theme, customStyles, primary) {
var _a, _b, _c, _d, _e;
var fonts = theme.fonts, palette = theme.palette;
var baseButtonStyles = getBaseButtonStyles(theme);
var splitButtonStyles = getSplitButtonStyles(theme);
var compoundButtonStyles = {
root: {
maxWidth: '280px',
minHeight: '72px',
height: 'auto',
padding: '16px 12px',
},
flexContainer: {
flexDirection: 'row',
alignItems: 'flex-start',
minWidth: '100%',
margin: '',
},
textContainer: {
textAlign: 'left',
},
icon: {
fontSize: '2em',
lineHeight: '1em',
height: '1em',
margin: '0px 8px 0px 0px',
flexBasis: '1em',
flexShrink: '0',
},
label: {
margin: '0 0 5px',
lineHeight: '100%',
fontWeight: FontWeights.semibold,
},
description: [
fonts.small,
{
lineHeight: '100%',
},
],
};
var standardCompoundTheme = {
description: {
color: palette.neutralSecondary,
},
descriptionHovered: {
color: palette.neutralDark,
},
descriptionPressed: {
color: 'inherit',
},
descriptionChecked: {
color: 'inherit',
},
descriptionDisabled: {
color: 'inherit',
},
};
var primaryCompoundTheme = {
description: (_a = {
color: palette.white
},
_a[HighContrastSelector] = __assign({ backgroundColor: 'WindowText', color: 'Window' }, getHighContrastNoAdjustStyle()),
_a),
descriptionHovered: (_b = {
color: palette.white
},
_b[HighContrastSelector] = {
backgroundColor: 'Highlight',
color: 'Window',
},
_b),
descriptionPressed: (_c = {
color: 'inherit'
},
_c[HighContrastSelector] = __assign({ color: 'Window', backgroundColor: 'WindowText' }, getHighContrastNoAdjustStyle()),
_c),
descriptionChecked: (_d = {
color: 'inherit'
},
_d[HighContrastSelector] = __assign({ color: 'Window', backgroundColor: 'WindowText' }, getHighContrastNoAdjustStyle()),
_d),
descriptionDisabled: (_e = {
color: 'inherit'
},
_e[HighContrastSelector] = {
color: 'inherit',
},
_e),
};
return concatStyleSets(baseButtonStyles, compoundButtonStyles, primary ? primaryStyles(theme) : standardStyles(theme), primary ? primaryCompoundTheme : standardCompoundTheme, splitButtonStyles, customStyles);
});
//# sourceMappingURL=CompoundButton.styles.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,9 @@
import * as React from 'react';
import type { IButtonProps } from '../Button.types';
import type { JSXElement } from '@fluentui/utilities';
/**
* {@docCategory Button}
*/
export declare class DefaultButton extends React.Component<IButtonProps, {}> {
render(): JSXElement;
}
@@ -0,0 +1,24 @@
import { __assign, __decorate, __extends } from "tslib";
import * as React from 'react';
import { BaseButton } from '../BaseButton';
import { customizable, nullRender } from '../../../Utilities';
import { getStyles } from './DefaultButton.styles';
/**
* {@docCategory Button}
*/
var DefaultButton = /** @class */ (function (_super) {
__extends(DefaultButton, _super);
function DefaultButton() {
return _super !== null && _super.apply(this, arguments) || this;
}
DefaultButton.prototype.render = function () {
var _a = this.props, _b = _a.primary, primary = _b === void 0 ? false : _b, styles = _a.styles, theme = _a.theme;
return (React.createElement(BaseButton, __assign({}, this.props, { variantClassName: primary ? 'ms-Button--primary' : 'ms-Button--default', styles: getStyles(theme, styles, primary), onRenderDescription: nullRender })));
};
DefaultButton = __decorate([
customizable('DefaultButton', ['theme', 'styles'], true)
], DefaultButton);
return DefaultButton;
}(React.Component));
export { DefaultButton };
//# sourceMappingURL=DefaultButton.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DefaultButton.js","sourceRoot":"../src/","sources":["components/Button/DefaultButton/DefaultButton.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAKnD;;GAEG;AAEH;IAAmC,iCAAiC;IAApE;;IAaA,CAAC;IAZQ,8BAAM,GAAb;QACQ,IAAA,KAAqC,IAAI,CAAC,KAAK,EAA7C,eAAe,EAAf,OAAO,mBAAG,KAAK,KAAA,EAAE,MAAM,YAAA,EAAE,KAAK,WAAe,CAAC;QAEtD,OAAO,CACL,oBAAC,UAAU,eACL,IAAI,CAAC,KAAK,IACd,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,EACvE,MAAM,EAAE,SAAS,CAAC,KAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAC1C,mBAAmB,EAAE,UAAU,IAC/B,CACH,CAAC;IACJ,CAAC;IAZU,aAAa;QADzB,YAAY,CAAC,eAAe,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC;OAC5C,aAAa,CAazB;IAAD,oBAAC;CAAA,AAbD,CAAmC,KAAK,CAAC,SAAS,GAajD;SAbY,aAAa","sourcesContent":["import * as React from 'react';\nimport { BaseButton } from '../BaseButton';\nimport { customizable, nullRender } from '../../../Utilities';\nimport { getStyles } from './DefaultButton.styles';\nimport type { IButtonProps } from '../Button.types';\n\nimport type { JSXElement } from '@fluentui/utilities';\n\n/**\n * {@docCategory Button}\n */\n@customizable('DefaultButton', ['theme', 'styles'], true)\nexport class DefaultButton extends React.Component<IButtonProps, {}> {\n public render(): JSXElement {\n const { primary = false, styles, theme } = this.props;\n\n return (\n <BaseButton\n {...this.props}\n variantClassName={primary ? 'ms-Button--primary' : 'ms-Button--default'}\n styles={getStyles(theme!, styles, primary)}\n onRenderDescription={nullRender}\n />\n );\n }\n}\n"]}
@@ -0,0 +1,3 @@
import type { IButtonStyles } from '../Button.types';
import type { ITheme } from '../../../Styling';
export declare const getStyles: (theme: ITheme, customStyles?: IButtonStyles, primary?: boolean) => IButtonStyles;
@@ -0,0 +1,22 @@
import { concatStyleSets, FontWeights } from '../../../Styling';
import { memoizeFunction } from '../../../Utilities';
import { getStyles as getBaseButtonStyles } from '../BaseButton.styles';
import { getStyles as getSplitButtonStyles } from '../SplitButton/SplitButton.styles';
import { primaryStyles, standardStyles } from '../ButtonThemes';
var DEFAULT_BUTTON_MIN_HEIGHT = '32px';
var DEFAULT_BUTTON_MIN_WIDTH = '80px';
export var getStyles = memoizeFunction(function (theme, customStyles, primary) {
var baseButtonStyles = getBaseButtonStyles(theme);
var splitButtonStyles = getSplitButtonStyles(theme);
var defaultButtonStyles = {
root: {
minWidth: DEFAULT_BUTTON_MIN_WIDTH,
minHeight: DEFAULT_BUTTON_MIN_HEIGHT,
},
label: {
fontWeight: FontWeights.semibold,
},
};
return concatStyleSets(baseButtonStyles, defaultButtonStyles, primary ? primaryStyles(theme) : standardStyles(theme), splitButtonStyles, customStyles);
});
//# sourceMappingURL=DefaultButton.styles.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DefaultButton.styles.js","sourceRoot":"../src/","sources":["components/Button/DefaultButton/DefaultButton.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,SAAS,IAAI,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,SAAS,IAAI,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEtF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIhE,IAAM,yBAAyB,GAAG,MAAM,CAAC;AACzC,IAAM,wBAAwB,GAAG,MAAM,CAAC;AAExC,MAAM,CAAC,IAAM,SAAS,GAAG,eAAe,CACtC,UAAC,KAAa,EAAE,YAA4B,EAAE,OAAiB;IAC7D,IAAM,gBAAgB,GAAkB,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACnE,IAAM,iBAAiB,GAAkB,oBAAoB,CAAC,KAAK,CAAC,CAAC;IACrE,IAAM,mBAAmB,GAAkB;QACzC,IAAI,EAAE;YACJ,QAAQ,EAAE,wBAAwB;YAClC,SAAS,EAAE,yBAAyB;SACrC;QACD,KAAK,EAAE;YACL,UAAU,EAAE,WAAW,CAAC,QAAQ;SACjC;KACF,CAAC;IAEF,OAAO,eAAe,CACpB,gBAAgB,EAChB,mBAAmB,EACnB,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,EACtD,iBAAiB,EACjB,YAAY,CACZ,CAAC;AACL,CAAC,CACF,CAAC","sourcesContent":["import { concatStyleSets, FontWeights } from '../../../Styling';\nimport { memoizeFunction } from '../../../Utilities';\nimport { getStyles as getBaseButtonStyles } from '../BaseButton.styles';\nimport { getStyles as getSplitButtonStyles } from '../SplitButton/SplitButton.styles';\n\nimport { primaryStyles, standardStyles } from '../ButtonThemes';\nimport type { IButtonStyles } from '../Button.types';\nimport type { ITheme } from '../../../Styling';\n\nconst DEFAULT_BUTTON_MIN_HEIGHT = '32px';\nconst DEFAULT_BUTTON_MIN_WIDTH = '80px';\n\nexport const getStyles = memoizeFunction(\n (theme: ITheme, customStyles?: IButtonStyles, primary?: boolean): IButtonStyles => {\n const baseButtonStyles: IButtonStyles = getBaseButtonStyles(theme);\n const splitButtonStyles: IButtonStyles = getSplitButtonStyles(theme);\n const defaultButtonStyles: IButtonStyles = {\n root: {\n minWidth: DEFAULT_BUTTON_MIN_WIDTH,\n minHeight: DEFAULT_BUTTON_MIN_HEIGHT,\n },\n label: {\n fontWeight: FontWeights.semibold,\n },\n };\n\n return concatStyleSets(\n baseButtonStyles,\n defaultButtonStyles,\n primary ? primaryStyles(theme) : standardStyles(theme),\n splitButtonStyles,\n customStyles,\n )!;\n },\n);\n"]}
@@ -0,0 +1,9 @@
import * as React from 'react';
import type { IButtonProps } from '../Button.types';
import type { JSXElement } from '@fluentui/utilities';
/**
* {@docCategory Button}
*/
export declare class IconButton extends React.Component<IButtonProps, {}> {
render(): JSXElement;
}

Some files were not shown because too many files have changed in this diff Show More