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,21 @@
import type { IComboBoxStyles, IComboBoxOptionStyles } from './ComboBox.types';
export interface IComboBoxClassNames {
container: string;
label: string;
root: string;
input: string;
errorMessage: string;
callout: string;
optionsContainer: string;
header: string;
divider: string;
optionsContainerWrapper: string;
screenReaderText: string;
}
export interface IComboBoxOptionClassNames {
optionText: string;
root: string;
optionTextWrapper: string;
}
export declare const getClassNames: (styles: Partial<IComboBoxStyles>, className: string, isOpen: boolean, disabled: boolean, required: boolean, focused: boolean, allowFreeForm: boolean, hasErrorMessage: boolean) => IComboBoxClassNames;
export declare const getComboBoxOptionClassNames: (styles: Partial<IComboBoxOptionStyles>) => IComboBoxOptionClassNames;
@@ -0,0 +1,41 @@
define(["require", "exports", "../../Utilities", "../../Styling"], function (require, exports, Utilities_1, Styling_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getComboBoxOptionClassNames = exports.getClassNames = void 0;
exports.getClassNames = (0, Utilities_1.memoizeFunction)(function (styles, className, isOpen, disabled, required, focused, allowFreeForm, hasErrorMessage) {
// const mergeStyles = mergeStylesShadow(styles.__shadowConfig__);
return {
container: (0, Styling_1.mergeStyles)(styles.__shadowConfig__, 'ms-ComboBox-container', className, styles.container),
label: (0, Styling_1.mergeStyles)(styles.__shadowConfig__, styles.label, disabled && styles.labelDisabled),
root: (0, Styling_1.mergeStyles)(styles.__shadowConfig__, 'ms-ComboBox', hasErrorMessage ? styles.rootError : isOpen && 'is-open', required && 'is-required', styles.root, !allowFreeForm && styles.rootDisallowFreeForm, hasErrorMessage && !focused ? styles.rootError : !disabled && focused && styles.rootFocused, !disabled && {
selectors: {
':hover': hasErrorMessage ? styles.rootError : !isOpen && !focused && styles.rootHovered,
':active': hasErrorMessage ? styles.rootError : styles.rootPressed,
':focus': hasErrorMessage ? styles.rootError : styles.rootFocused,
},
}, disabled && ['is-disabled', styles.rootDisabled]),
input: (0, Styling_1.mergeStyles)(styles.__shadowConfig__, 'ms-ComboBox-Input', styles.input, disabled && styles.inputDisabled),
errorMessage: (0, Styling_1.mergeStyles)(styles.__shadowConfig__, styles.errorMessage),
callout: (0, Styling_1.mergeStyles)(styles.__shadowConfig__, 'ms-ComboBox-callout', styles.callout),
optionsContainerWrapper: (0, Styling_1.mergeStyles)(styles.__shadowConfig__, 'ms-ComboBox-optionsContainerWrapper', styles.optionsContainerWrapper),
optionsContainer: (0, Styling_1.mergeStyles)(styles.__shadowConfig__, 'ms-ComboBox-optionsContainer', styles.optionsContainer),
header: (0, Styling_1.mergeStyles)(styles.__shadowConfig__, 'ms-ComboBox-header', styles.header),
divider: (0, Styling_1.mergeStyles)(styles.__shadowConfig__, 'ms-ComboBox-divider', styles.divider),
screenReaderText: (0, Styling_1.mergeStyles)(styles.__shadowConfig__, styles.screenReaderText),
};
});
exports.getComboBoxOptionClassNames = (0, Utilities_1.memoizeFunction)(function (styles) {
return {
optionText: (0, Styling_1.mergeStyles)(styles.__shadowConfig__, 'ms-ComboBox-optionText', styles.optionText),
root: (0, Styling_1.mergeStyles)(styles.__shadowConfig__, 'ms-ComboBox-option', styles.root, {
selectors: {
':hover': styles.rootHovered,
':focus': styles.rootFocused,
':active': styles.rootPressed,
},
}),
optionTextWrapper: (0, Styling_1.mergeStyles)(styles.__shadowConfig__, styles.optionTextWrapper),
};
});
});
//# sourceMappingURL=ComboBox.classNames.js.map
File diff suppressed because one or more lines are too long
+26
View File
@@ -0,0 +1,26 @@
import * as React from 'react';
import type { IComboBoxProps } from './ComboBox.types';
export interface IComboBoxState {
/** The open state */
isOpen?: boolean;
/** The focused state of the combo box */
focusState?: 'none' | 'focused' | 'focusing';
/**
* When taking input, this will store the index that the options input matches
* (-1 if no input or match)
*/
currentPendingValueValidIndex: number;
/**
* Stores the hovered over value in the dropdown
* (used for styling the options without updating the input)
*/
currentPendingValueValidIndexOnHover: number;
/** When taking input, this will store the actual text that is being entered */
currentPendingValue?: string;
/**
* The id of the current focused combo item, otherwise the id of the currently selected element,
* null otherwise
*/
ariaActiveDescendantValue?: string;
}
export declare const ComboBox: React.FunctionComponent<IComboBoxProps>;
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
import type { ITheme } from '../../Styling';
import type { IComboBoxOptionStyles, IComboBoxStyles } from './ComboBox.types';
import type { IButtonStyles } from '../../Button';
export declare const getOptionStyles: (theme: ITheme, customStylesForAllOptions?: Partial<IComboBoxOptionStyles>, customOptionStylesForCurrentOption?: Partial<IComboBoxOptionStyles>, isPending?: boolean, isHidden?: boolean, isSelected?: boolean) => Partial<IComboBoxOptionStyles>;
export declare const getCaretDownButtonStyles: (theme: ITheme, customStyles?: Partial<IButtonStyles>) => IButtonStyles;
export declare const getStyles: (theme: ITheme, customStyles?: Partial<IComboBoxStyles>, comboBoxOptionWidth?: string) => Partial<IComboBoxStyles>;
@@ -0,0 +1,425 @@
define(["require", "exports", "tslib", "../../Styling", "../../Utilities"], function (require, exports, tslib_1, Styling_1, Utilities_1) {
"use strict";
var _a, _b;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getStyles = exports.getCaretDownButtonStyles = exports.getOptionStyles = void 0;
var ComboBoxHeight = 32;
var ComboBoxLineHeight = 30;
var ComboBoxCaretDownWidth = 32;
var ComboBoxOptionHeight = 36;
var getDisabledStyles = (0, Utilities_1.memoizeFunction)(function (theme) {
var _a;
var semanticColors = theme.semanticColors;
return {
backgroundColor: semanticColors.disabledBackground,
color: semanticColors.disabledText,
cursor: 'default',
selectors: (_a = {
':after': {
borderColor: semanticColors.disabledBackground,
}
},
_a[Styling_1.HighContrastSelector] = {
color: 'GrayText',
selectors: {
':after': {
borderColor: 'GrayText',
},
},
},
_a),
};
});
var listOptionHighContrastStyles = {
selectors: (_a = {},
_a[Styling_1.HighContrastSelector] = tslib_1.__assign({ backgroundColor: 'Highlight', borderColor: 'Highlight', color: 'HighlightText' }, (0, Styling_1.getHighContrastNoAdjustStyle)()),
_a),
};
var inputHighContrastStyles = {
selectors: (_b = {},
_b[Styling_1.HighContrastSelector] = tslib_1.__assign({ color: 'WindowText', backgroundColor: 'Window' }, (0, Styling_1.getHighContrastNoAdjustStyle)()),
_b),
};
exports.getOptionStyles = (0, Utilities_1.memoizeFunction)(function (theme, customStylesForAllOptions, customOptionStylesForCurrentOption, isPending, isHidden, isSelected) {
var _a;
var palette = theme.palette, semanticColors = theme.semanticColors;
var option = {
textHoveredColor: semanticColors.menuItemTextHovered,
textSelectedColor: palette.neutralDark,
textDisabledColor: semanticColors.disabledText,
backgroundHoveredColor: semanticColors.menuItemBackgroundHovered,
backgroundPressedColor: semanticColors.menuItemBackgroundPressed,
};
var optionStyles = {
root: [
theme.fonts.medium,
{
backgroundColor: isPending ? option.backgroundHoveredColor : 'transparent',
boxSizing: 'border-box',
cursor: 'pointer',
display: isHidden ? 'none' : 'block',
width: '100%',
height: 'auto',
minHeight: ComboBoxOptionHeight,
lineHeight: '20px',
padding: '0 8px',
position: 'relative',
borderWidth: '1px',
borderStyle: 'solid',
borderColor: 'transparent',
borderRadius: 0,
wordWrap: 'break-word',
overflowWrap: 'break-word',
textAlign: 'left',
selectors: tslib_1.__assign(tslib_1.__assign((_a = {}, _a[Styling_1.HighContrastSelector] = {
border: 'none',
borderColor: 'Background',
}, _a), (!isHidden && {
'&.ms-Checkbox': {
display: 'flex',
alignItems: 'center',
},
})), { '&.ms-Button--command:hover:active': {
backgroundColor: option.backgroundPressedColor,
}, '.ms-Checkbox-label': {
width: '100%',
} }),
},
isSelected
? [
{
backgroundColor: 'transparent',
color: option.textSelectedColor,
selectors: {
':hover': [
{
backgroundColor: option.backgroundHoveredColor,
},
listOptionHighContrastStyles,
],
},
},
(0, Styling_1.getFocusStyle)(theme, { inset: -1, isFocusedOnly: false }),
listOptionHighContrastStyles,
]
: [],
],
rootHovered: {
backgroundColor: option.backgroundHoveredColor,
color: option.textHoveredColor,
},
rootFocused: {
backgroundColor: option.backgroundHoveredColor,
},
rootDisabled: {
color: option.textDisabledColor,
cursor: 'default',
},
optionText: {
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
minWidth: '0px',
maxWidth: '100%',
wordWrap: 'break-word',
overflowWrap: 'break-word',
display: 'inline-block',
},
optionTextWrapper: {
maxWidth: '100%',
display: 'flex',
alignItems: 'center',
},
};
return (0, Styling_1.concatStyleSets)(optionStyles, customStylesForAllOptions, customOptionStylesForCurrentOption);
});
exports.getCaretDownButtonStyles = (0, Utilities_1.memoizeFunction)(function (theme, customStyles) {
var _a, _b;
var semanticColors = theme.semanticColors, fonts = theme.fonts;
var caret = {
buttonTextColor: semanticColors.bodySubtext,
buttonTextHoveredCheckedColor: semanticColors.buttonTextChecked,
buttonBackgroundHoveredColor: semanticColors.listItemBackgroundHovered,
buttonBackgroundCheckedColor: semanticColors.listItemBackgroundChecked,
buttonBackgroundCheckedHoveredColor: semanticColors.listItemBackgroundCheckedHovered,
};
var buttonHighContrastStyles = {
selectors: (_a = {},
_a[Styling_1.HighContrastSelector] = tslib_1.__assign({ backgroundColor: 'Highlight', borderColor: 'Highlight', color: 'HighlightText' }, (0, Styling_1.getHighContrastNoAdjustStyle)()),
_a),
};
var styles = {
root: {
color: caret.buttonTextColor,
fontSize: fonts.small.fontSize,
position: 'absolute',
top: 0,
height: '100%',
lineHeight: ComboBoxLineHeight,
width: ComboBoxCaretDownWidth,
textAlign: 'center',
cursor: 'default',
selectors: (_b = {},
_b[Styling_1.HighContrastSelector] = tslib_1.__assign({ backgroundColor: 'ButtonFace', borderColor: 'ButtonText', color: 'ButtonText' }, (0, Styling_1.getHighContrastNoAdjustStyle)()),
_b),
},
icon: {
fontSize: fonts.small.fontSize,
},
rootHovered: [
{
backgroundColor: caret.buttonBackgroundHoveredColor,
color: caret.buttonTextHoveredCheckedColor,
cursor: 'pointer',
},
buttonHighContrastStyles,
],
rootPressed: [
{
backgroundColor: caret.buttonBackgroundCheckedColor,
color: caret.buttonTextHoveredCheckedColor,
},
buttonHighContrastStyles,
],
rootChecked: [
{
backgroundColor: caret.buttonBackgroundCheckedColor,
color: caret.buttonTextHoveredCheckedColor,
},
buttonHighContrastStyles,
],
rootCheckedHovered: [
{
backgroundColor: caret.buttonBackgroundCheckedHoveredColor,
color: caret.buttonTextHoveredCheckedColor,
},
buttonHighContrastStyles,
],
rootDisabled: [
getDisabledStyles(theme),
{
position: 'absolute',
},
],
};
return (0, Styling_1.concatStyleSets)(styles, customStyles);
});
exports.getStyles = (0, Utilities_1.memoizeFunction)(function (theme, customStyles, comboBoxOptionWidth) {
var _a, _b, _c, _d, _e, _f;
var semanticColors = theme.semanticColors, fonts = theme.fonts, effects = theme.effects;
var root = {
textColor: semanticColors.inputText,
borderColor: semanticColors.inputBorder,
borderHoveredColor: semanticColors.inputBorderHovered,
borderPressedColor: semanticColors.inputFocusBorderAlt,
borderFocusedColor: semanticColors.inputFocusBorderAlt,
backgroundColor: semanticColors.inputBackground,
erroredColor: semanticColors.errorText,
};
var option = {
headerTextColor: semanticColors.menuHeader,
dividerBorderColor: semanticColors.bodyDivider,
};
// placeholder style variables
var placeholderHighContrastStyles = {
selectors: (_a = {},
_a[Styling_1.HighContrastSelector] = {
color: 'GrayText',
},
_a),
};
var placeholderStyles = [
{
color: semanticColors.inputPlaceholderText,
},
placeholderHighContrastStyles,
];
var placeholderStylesHovered = [
{
color: semanticColors.inputTextHovered,
},
placeholderHighContrastStyles,
];
var disabledPlaceholderStyles = [
{
color: semanticColors.disabledText,
},
placeholderHighContrastStyles,
];
var ComboBoxRootHighContrastFocused = tslib_1.__assign(tslib_1.__assign({ color: 'HighlightText', backgroundColor: 'Window' }, (0, Styling_1.getHighContrastNoAdjustStyle)()), { selectors: {
':after': {
borderColor: 'Highlight',
},
} });
var focusBorderStyles = (0, Styling_1.getInputFocusStyle)(root.borderPressedColor, effects.roundedCorner2, 'border', 0);
var styles = {
container: {},
label: {},
labelDisabled: {},
root: [
theme.fonts.medium,
{
boxShadow: 'none',
marginLeft: '0',
paddingRight: ComboBoxCaretDownWidth,
paddingLeft: 9,
color: root.textColor,
position: 'relative',
outline: '0',
userSelect: 'none',
backgroundColor: root.backgroundColor,
cursor: 'text',
display: 'block',
height: ComboBoxHeight,
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
boxSizing: 'border-box', // Border-box matches Dropdown and TextField
selectors: {
'.ms-Label': {
display: 'inline-block',
marginBottom: '8px',
},
'&.is-open': {
selectors: (_b = {},
_b[Styling_1.HighContrastSelector] = ComboBoxRootHighContrastFocused,
_b),
},
// setting border using pseudo-element here in order to
// prevent chevron button to overlap ComboBox border under certain resolutions
':after': {
pointerEvents: 'none',
content: "''",
position: 'absolute',
left: 0,
top: 0,
bottom: 0,
right: 0,
borderWidth: '1px',
borderStyle: 'solid',
borderColor: root.borderColor,
borderRadius: effects.roundedCorner2,
},
},
},
],
rootHovered: {
selectors: (_c = {
':after': {
borderColor: root.borderHoveredColor,
},
'.ms-ComboBox-Input': [
{
color: semanticColors.inputTextHovered,
},
(0, Styling_1.getPlaceholderStyles)(placeholderStylesHovered),
inputHighContrastStyles,
]
},
_c[Styling_1.HighContrastSelector] = tslib_1.__assign(tslib_1.__assign({ color: 'HighlightText', backgroundColor: 'Window' }, (0, Styling_1.getHighContrastNoAdjustStyle)()), { selectors: {
':after': {
borderColor: 'Highlight',
},
} }),
_c),
},
rootPressed: [
{
position: 'relative',
selectors: (_d = {},
_d[Styling_1.HighContrastSelector] = ComboBoxRootHighContrastFocused,
_d),
},
],
rootFocused: [
{
selectors: (_e = {
'.ms-ComboBox-Input': [
{
color: semanticColors.inputTextHovered,
},
inputHighContrastStyles,
]
},
_e[Styling_1.HighContrastSelector] = ComboBoxRootHighContrastFocused,
_e),
},
focusBorderStyles,
],
rootDisabled: getDisabledStyles(theme),
rootError: {
selectors: {
':after': {
borderColor: root.erroredColor,
},
':hover:after': {
borderColor: semanticColors.inputBorderHovered,
},
},
},
rootDisallowFreeForm: {},
input: [
(0, Styling_1.getPlaceholderStyles)(placeholderStyles),
{
backgroundColor: root.backgroundColor,
color: root.textColor,
boxSizing: 'border-box',
width: '100%',
height: '100%',
borderStyle: 'none',
outline: 'none',
font: 'inherit',
textOverflow: 'ellipsis',
padding: '0',
selectors: {
'::-ms-clear': {
display: 'none',
},
},
},
inputHighContrastStyles,
],
inputDisabled: [getDisabledStyles(theme), (0, Styling_1.getPlaceholderStyles)(disabledPlaceholderStyles)],
errorMessage: [
theme.fonts.small,
{
color: root.erroredColor,
marginTop: '5px',
},
],
callout: {
boxShadow: effects.elevation8,
},
optionsContainerWrapper: {
width: comboBoxOptionWidth,
},
optionsContainer: {
display: 'block',
},
screenReaderText: Styling_1.hiddenContentStyle,
header: [
fonts.medium,
{
fontWeight: Styling_1.FontWeights.semibold,
color: option.headerTextColor,
backgroundColor: 'none',
borderStyle: 'none',
height: ComboBoxOptionHeight,
lineHeight: ComboBoxOptionHeight,
cursor: 'default',
padding: '0 8px',
userSelect: 'none',
textAlign: 'left',
selectors: (_f = {},
_f[Styling_1.HighContrastSelector] = tslib_1.__assign({ color: 'GrayText' }, (0, Styling_1.getHighContrastNoAdjustStyle)()),
_f),
},
],
divider: {
height: 1,
backgroundColor: option.dividerBorderColor,
},
};
return (0, Styling_1.concatStyleSets)(styles, customStyles);
});
});
//# sourceMappingURL=ComboBox.styles.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,369 @@
import * as React from 'react';
import type { IIconProps } from '../../Icon';
import type { ISelectableOption, ISelectableDroppableTextProps } from '../../SelectableOption';
import type { IShadowDomStyle, IStyle, ITheme } from '../../Styling';
import type { IButtonStyles, IButtonProps } from '../../Button';
import type { IRefObject, IRenderFunction } from '../../Utilities';
import type { IComboBoxClassNames } from './ComboBox.classNames';
import type { IAutofillProps } from '../../Autofill';
/**
* {@docCategory ComboBox}
*/
export interface IComboBox {
/**
* All selected options.
*/
readonly selectedOptions: IComboBoxOption[];
/**
* If there is a menu open, this will dismiss it.
*/
dismissMenu: () => void;
/**
* Sets focus to the input in the ComboBox.
* @param shouldOpenOnFocus - Whether to open the menu when the input gets focus
* @param useFocusAsync - Whether to focus the input asynchronously
*/
focus(shouldOpenOnFocus?: boolean, useFocusAsync?: boolean): void;
}
/**
* {@docCategory ComboBox}
*/
export interface IComboBoxOption extends ISelectableOption {
/**
* Specific styles for each ComboBox option. To give common styles to all options, use
* `IComboBoxProps.comboBoxOptionStyles` instead.
*/
styles?: Partial<IComboBoxOptionStyles>;
/**
* Whether to use the `ariaLabel` prop instead of the `text` prop to set the preview text as well
* as the `aria-label`. This is for scenarios where the `text` prop is used for embedded data.
*/
useAriaLabelAsText?: boolean;
}
/**
* {@docCategory ComboBox}
*/
export interface IComboBoxProps extends ISelectableDroppableTextProps<IComboBox, IComboBox>, React.RefAttributes<HTMLDivElement> {
/**
* Optional ref to access the `IComboBox` interface. Use this instead of `ref` for accessing
* the public methods and properties of the component.
*/
componentRef?: IRefObject<IComboBox>;
/**
* Collection of options for this ComboBox.
*/
options: IComboBoxOption[];
/**
* Called when a ComboBox item is clicked.
*/
onItemClick?: (event: React.FormEvent<IComboBox>, option?: IComboBoxOption, index?: number) => void;
/**
* Called when either:
* 1) The selected option changes.
* 2) A manually edited value is submitted. In this case there may not be a matched option if `allowFreeform`
* is also true (and hence only `value` would be provided; the other parameters would be unspecified).
*
* The value passed to the callback (4th paramenter) reflects the changed option's text, or the user-typed input when
* freeform is allowed.
*/
onChange?: (event: React.FormEvent<IComboBox>, option?: IComboBoxOption, index?: number, value?: string) => void;
/**
* Called when the user changes the pending value in ComboBox, either by typing in the
* input or hovering over options. When typing, the behavior varies depending on `autoComplete`
* and `allowFreeform` settings.
*
* In all cases, when the pending value is reset, all parameters will be undefined.
*
* When hovering options: `option` and `index` will be provided, and `value` will be undefined.
*
* Typing with `allowFreeform` on: If there's an option matching the input (an exact match if
* `autoComplete` is off, or a prefix match otherwise), `option` and `index` are provided and
* `value` is undefined. Otherwise only `value` is provided.
*
* Typing with `allowFreeform` off (or unspecified): If `autoComplete` is on (or unspecified),
* and the user types text matching the start of an option within a timeout, `option` and `index`
* are provided and `value` is undefined. If `autoComplete` is off, typing does nothing.
*
* If you simply want to be notified of raw text input, use the prop `onInputValueChange`.
*/
onPendingValueChanged?: (option?: IComboBoxOption, index?: number, value?: string) => void;
/**
* Called when the user types in to the input of the combo box
*
* Ideal if you want to be notified of raw text input
*/
onInputValueChange?: (text: string) => void;
/**
* Called when the ComboBox menu is launched.
*/
onMenuOpen?: () => void;
/**
* Called when the ComboBox menu is dismissed.
*/
onMenuDismissed?: () => void;
/**
* Called before the menu gets dismissed.
*/
onMenuDismiss?: () => void;
/**
* Called when the options should be resolved, if they have been updated or
* if they need to be passed in the first time.
*/
onResolveOptions?: (options: IComboBoxOption[]) => IComboBoxOption[] | PromiseLike<IComboBoxOption[]>;
/**
* Called when the ComboBox requests the list to scroll to a specific element.
*/
onScrollToItem?: (itemIndex: number) => void;
/**
* Whether the ComboBox allows freeform user input, rather than restricting to the provided options.
*/
allowFreeform?: boolean;
/**
* When true, the Combobox will allow the user to type freely while the Combobox is focused.
* On Blur, the value will be set to the matching option, or the previous selection if there is no match.
* @defaultvalue false
*/
allowFreeInput?: boolean;
/**
* When true this allows the parent element to navigate using left and right arrow keys.
*
* @defaultvalue false
*/
allowParentArrowNavigation?: boolean;
/**
* Whether the ComboBox auto completes. As the user is entering text, potential matches will be
* suggested from the list of options. If the ComboBox is expanded, this will also scroll to the
* suggested option and give it a selected style.
*
* @defaultvalue "on"
*/
autoComplete?: 'on' | 'off';
/**
* Value to show in the input. Does not have to map to an option.
*/
text?: string;
/**
* When multiple items are selected, this will be used to separate values in the ComboBox input.
*
* @defaultvalue ", "
*/
multiSelectDelimiter?: string;
/**
* The IconProps to use for the caret down (expand) button of the ComboBox.
*/
buttonIconProps?: IIconProps;
/**
* Props to pass through to the Autofill component (the input field) inside the ComboBox.
* WARNING: These props (except the callbacks) may override ComboBox's defaults and cause issues.
*/
autofill?: IAutofillProps;
/**
* Theme provided by HOC.
*/
theme?: ITheme;
/**
* Custom styles for this component.
*/
styles?: Partial<IComboBoxStyles>;
/**
* Custom function for providing the classNames for the ComboBox. Can be used to provide
* all styles for the component instead of applying them on top of the default styles.
*/
getClassNames?: (theme: ITheme, isOpen: boolean, disabled: boolean, required: boolean, focused: boolean, allowFreeForm: boolean, hasErrorMessage: boolean, className?: string) => IComboBoxClassNames;
/**
* Styles for the caret down (expand) button.
*/
caretDownButtonStyles?: Partial<IButtonStyles>;
/**
* Default styles that should be applied to ComboBox options.
*/
comboBoxOptionStyles?: Partial<IComboBoxOptionStyles>;
/**
* If the options list is scrollable, whether to position the selected option at the top of the
* callout when it is opened (unless it has reached the end of the scrollbar).
* @defaultvalue false;
*/
scrollSelectedToTop?: boolean;
/**
* Add additional content above the option list in the callout. Content should not include interactive items.
*/
onRenderUpperContent?: IRenderFunction<IComboBoxProps>;
/**
* Add additional content below the option list in the callout. Content should not include interactive items.
*/
onRenderLowerContent?: IRenderFunction<IComboBoxProps>;
/**
* Custom width for options list dropdown. Mutually exclusive with `useComboBoxAsMenuWidth`.
*/
dropdownWidth?: number;
/**
* Whether to use the ComboBox field width as the menu's width.
* Mutually exclusive with `dropdownWidth`.
*/
useComboBoxAsMenuWidth?: boolean;
/**
* Custom max width for the options list dropdown.
*/
dropdownMaxWidth?: number;
/**
* Whether to hide the ComboBox's caret (expand) button element from screen readers. This is false
* (exposed to AT) by default because Android Talkback cannot otherwise expand the combobox.
* @defaultvalue false
*/
isButtonAriaHidden?: boolean;
/**
* Optional ID of an element providing a description of the ComboBox for screen reader users.
*/
ariaDescribedBy?: string;
/**
* Whether to show/hide the menu when it's opened/closed (rather than creating/destroying it).
* This will improve perf of the menu opening but could potentially have a negative impact on
* overall perf by increasing initial render time (since the ComboBox will render the menu hidden
* on mount) and keeping more elements in the DOM. Should only be used when perf to open/close
* the menu is important.
*
* Note: This may increase the amount of time it takes for the ComboBox itself to mount.
*/
persistMenu?: boolean;
/**
* Whether the options list callout should restore focus after being dismissed. Set to false to
* prevent the menu from trying to re-focus the element that had focus before the menu was opened.
* @defaultvalue true;
*/
shouldRestoreFocus?: boolean;
/**
* Additional props for the caret down (expand) button.
*/
iconButtonProps?: IButtonProps;
/**
* Custom render function for the label text.
*/
onRenderLabel?: IRenderFunction<IOnRenderComboBoxLabelProps>;
/**
* Whether matching the ComboBox options when writing in the ComboBox input should be case-sensitive or not.
* @defaultvalue false
*/
caseSensitive?: boolean;
}
/**
* {@docCategory ComboBox}
*/
export interface IOnRenderComboBoxLabelProps {
/**
* Props to render the ComboBox.
*/
props: IComboBoxProps;
/**
* Accessible text for label when ComboBox is multiselected.
*/
multiselectAccessibleText?: string;
}
/**
* {@docCategory ComboBox}
*/
export interface IComboBoxStyles extends IShadowDomStyle {
/**
* Style for the container which has the ComboBox and the label.
* (In most other components this would be called `root`.)
*/
container: IStyle;
/**
* Style for the label element of the ComboBox.
*/
label: IStyle;
/**
* Style for the label element of the ComboBox in the disabled state.
*/
labelDisabled: IStyle;
/**
* Base styles for the wrapper element containing the input field and caret button, applied to
* all state variants.
*
* Unlike in most components, this is NOT the actual root element which also contains the label
* as well as the field; for that, use `container`.
*/
root: IStyle;
/**
* Styles for the wrapper element containing the input field and caret button, applied when
* the ComboBox has an error message.
*/
rootError: IStyle;
/**
* Styles for the wrapper element containing the input field and caret button, applied when
* `IComboBoxProps.allowFreeform` is false.
*/
rootDisallowFreeForm: IStyle;
/**
* Styles for the wrapper element containing the input field and caret button, applied any time
* the ComboBox is hovered (unless it's disabled).
*/
rootHovered: IStyle;
/**
* Styles for the wrapper element containing the input field and caret button, applied any time
* the ComboBox is active (unless it's disabled).
*/
rootPressed: IStyle;
/**
* Styles for the wrapper element containing the input field and caret button, applied any time
* the ComboBox is focused (unless it's disabled).
*/
rootFocused: IStyle;
/**
* Styles for the wrapper element containing the input field and caret button, applied when the
* ComboBox is disabled. These override all the other styles.
*
* NOTE: Hover/focused/active styles are not applied for disabled ComboBoxes.
*/
rootDisabled: IStyle;
/**
* Base styles for the input element which contains the currently selected option.
*/
input: IStyle;
/**
* Style override for the input element when ComboBox is disabled.
*/
inputDisabled: IStyle;
/**
* Styles for the error message text of the ComboBox.
*/
errorMessage: IStyle;
/**
* Styles for the callout.
*/
callout: IStyle;
/**
* Styles for the options list container element.
*/
optionsContainerWrapper: IStyle;
/**
* Styles for the container of all the ComboBox options.
* Includes the headers and dividers.
*/
optionsContainer: IStyle;
/**
* Styles for a header in the options.
*/
header: IStyle;
/**
* Styles for a divider in the options.
*/
divider: IStyle;
/**
* Styles for hidden screen reader text.
*/
screenReaderText: IStyle;
}
/**
* {@docCategory ComboBox}
*/
export interface IComboBoxOptionStyles extends IButtonStyles {
/**
* Styles for the text inside the ComboBox option. This should be used instead of the description
* in IButtonStyles because we custom render the text in the ComboBox options.
*/
optionText: IStyle;
/**
* Styles for the ComboBox option text's wrapper.
*/
optionTextWrapper: IStyle;
}
@@ -0,0 +1,5 @@
define(["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
});
//# sourceMappingURL=ComboBox.types.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,19 @@
import * as React from 'react';
import type { IComboBoxProps, IComboBox, IComboBoxOption } from './ComboBox.types';
import type { JSXElement } from '@fluentui/utilities';
export declare class VirtualizedComboBox extends React.Component<IComboBoxProps, {}> implements IComboBox {
/** The combo box element */
private _comboBox;
/** The virtualized list element */
private _list;
constructor(props: IComboBoxProps);
/**
* All selected options
*/
get selectedOptions(): IComboBoxOption[];
dismissMenu(): void;
focus(shouldOpenOnFocus?: boolean, useFocusAsync?: boolean): boolean;
render(): JSXElement;
protected _onRenderList: (props: IComboBoxProps) => JSXElement;
protected _onScrollToItem: (itemIndex: number) => void;
}
@@ -0,0 +1,59 @@
define(["require", "exports", "tslib", "react", "./ComboBox", "../../List", "../../Utilities"], function (require, exports, tslib_1, React, ComboBox_1, List_1, Utilities_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VirtualizedComboBox = void 0;
var VirtualizedComboBox = /** @class */ (function (_super) {
tslib_1.__extends(VirtualizedComboBox, _super);
function VirtualizedComboBox(props) {
var _this = _super.call(this, props) || this;
/** The combo box element */
_this._comboBox = React.createRef();
/** The virtualized list element */
_this._list = React.createRef();
_this._onRenderList = function (props) {
var id = props.id, onRenderItem = props.onRenderItem;
// Render virtualized list
return (React.createElement(List_1.List, { componentRef: _this._list, role: "listbox", id: "".concat(id, "-list"), "aria-labelledby": "".concat(id, "-label"), items: props.options,
// eslint-disable-next-line react/jsx-no-bind
onRenderCell: onRenderItem ? function (item) { return onRenderItem(item); } : function () { return null; } }));
};
_this._onScrollToItem = function (itemIndex) {
// We are using the List component, call scrollToIndex
_this._list.current && _this._list.current.scrollToIndex(itemIndex);
};
(0, Utilities_1.initializeComponentRef)(_this);
return _this;
}
Object.defineProperty(VirtualizedComboBox.prototype, "selectedOptions", {
/**
* All selected options
*/
get: function () {
if (this._comboBox.current) {
return this._comboBox.current.selectedOptions;
}
return [];
},
enumerable: false,
configurable: true
});
VirtualizedComboBox.prototype.dismissMenu = function () {
if (this._comboBox.current) {
return this._comboBox.current.dismissMenu();
}
};
VirtualizedComboBox.prototype.focus = function (shouldOpenOnFocus, useFocusAsync) {
if (this._comboBox.current) {
this._comboBox.current.focus(shouldOpenOnFocus, useFocusAsync);
return true;
}
return false;
};
VirtualizedComboBox.prototype.render = function () {
return (React.createElement(ComboBox_1.ComboBox, tslib_1.__assign({}, this.props, { componentRef: this._comboBox, onRenderList: this._onRenderList, onScrollToItem: this._onScrollToItem })));
};
return VirtualizedComboBox;
}(React.Component));
exports.VirtualizedComboBox = VirtualizedComboBox;
});
//# sourceMappingURL=VirtualizedComboBox.js.map
@@ -0,0 +1 @@
{"version":3,"file":"VirtualizedComboBox.js","sourceRoot":"../src/","sources":["components/ComboBox/VirtualizedComboBox.tsx"],"names":[],"mappings":";;;;IAUA;QAAyC,+CAAmC;QAM1E,6BAAY,KAAqB;YAC/B,YAAA,MAAK,YAAC,KAAK,CAAC,SAAC;YANf,4BAA4B;YACpB,eAAS,GAAG,KAAK,CAAC,SAAS,EAAa,CAAC;YACjD,mCAAmC;YAC3B,WAAK,GAAG,KAAK,CAAC,SAAS,EAAS,CAAC;YA4C/B,mBAAa,GAAG,UAAC,KAAqB;gBACtC,IAAA,EAAE,GAAmB,KAAK,GAAxB,EAAE,YAAY,GAAK,KAAK,aAAV,CAAW;gBAEnC,0BAA0B;gBAC1B,OAAO,CACL,oBAAC,WAAI,IACH,YAAY,EAAE,KAAI,CAAC,KAAK,EACxB,IAAI,EAAC,SAAS,EACd,EAAE,EAAE,UAAG,EAAE,UAAO,qBACC,UAAG,EAAE,WAAQ,EAC9B,KAAK,EAAE,KAAK,CAAC,OAAO;oBACpB,6CAA6C;oBAC7C,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,UAAC,IAAuB,IAAK,OAAA,YAAY,CAAC,IAAI,CAAC,EAAlB,CAAkB,CAAC,CAAC,CAAC,cAAM,OAAA,IAAI,EAAJ,CAAI,GACzF,CACH,CAAC;YACJ,CAAC,CAAC;YAEQ,qBAAe,GAAG,UAAC,SAAiB;gBAC5C,sDAAsD;gBACtD,KAAI,CAAC,KAAK,CAAC,OAAO,IAAI,KAAI,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;YACpE,CAAC,CAAC;YA3DA,IAAA,kCAAsB,EAAC,KAAI,CAAC,CAAC;;QAC/B,CAAC;QAKD,sBAAW,gDAAe;YAH1B;;eAEG;iBACH;gBACE,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;oBAC3B,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,eAAe,CAAC;gBAChD,CAAC;gBACD,OAAO,EAAE,CAAC;YACZ,CAAC;;;WAAA;QAEM,yCAAW,GAAlB;YACE,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;gBAC3B,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC9C,CAAC;QACH,CAAC;QAEM,mCAAK,GAAZ,UAAa,iBAA2B,EAAE,aAAuB;YAC/D,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;gBAC3B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;gBAC/D,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;QAEM,oCAAM,GAAb;YACE,OAAO,CACL,oBAAC,mBAAQ,uBACH,IAAI,CAAC,KAAK,IACd,YAAY,EAAE,IAAI,CAAC,SAAS,EAC5B,YAAY,EAAE,IAAI,CAAC,aAAa,EAChC,cAAc,EAAE,IAAI,CAAC,eAAe,IACpC,CACH,CAAC;QACJ,CAAC;QAuBH,0BAAC;IAAD,CAAC,AArED,CAAyC,KAAK,CAAC,SAAS,GAqEvD;IArEY,kDAAmB","sourcesContent":["import * as React from 'react';\nimport { ComboBox } from './ComboBox';\nimport { List } from '../../List';\nimport { initializeComponentRef } from '../../Utilities';\nimport type { IComboBoxProps, IComboBox, IComboBoxOption } from './ComboBox.types';\nimport type { IList } from '../../List';\nimport type { ISelectableOption } from '../../SelectableOption';\n\nimport type { JSXElement } from '@fluentui/utilities';\n\nexport class VirtualizedComboBox extends React.Component<IComboBoxProps, {}> implements IComboBox {\n /** The combo box element */\n private _comboBox = React.createRef<IComboBox>();\n /** The virtualized list element */\n private _list = React.createRef<IList>();\n\n constructor(props: IComboBoxProps) {\n super(props);\n\n initializeComponentRef(this);\n }\n\n /**\n * All selected options\n */\n public get selectedOptions(): IComboBoxOption[] {\n if (this._comboBox.current) {\n return this._comboBox.current.selectedOptions;\n }\n return [];\n }\n\n public dismissMenu(): void {\n if (this._comboBox.current) {\n return this._comboBox.current.dismissMenu();\n }\n }\n\n public focus(shouldOpenOnFocus?: boolean, useFocusAsync?: boolean): boolean {\n if (this._comboBox.current) {\n this._comboBox.current.focus(shouldOpenOnFocus, useFocusAsync);\n return true;\n }\n\n return false;\n }\n\n public render(): JSXElement {\n return (\n <ComboBox\n {...this.props}\n componentRef={this._comboBox}\n onRenderList={this._onRenderList}\n onScrollToItem={this._onScrollToItem}\n />\n );\n }\n\n protected _onRenderList = (props: IComboBoxProps): JSXElement => {\n const { id, onRenderItem } = props;\n\n // Render virtualized list\n return (\n <List\n componentRef={this._list}\n role=\"listbox\"\n id={`${id}-list`}\n aria-labelledby={`${id}-label`}\n items={props.options}\n // eslint-disable-next-line react/jsx-no-bind\n onRenderCell={onRenderItem ? (item: ISelectableOption) => onRenderItem(item) : () => null}\n />\n );\n };\n\n protected _onScrollToItem = (itemIndex: number): void => {\n // We are using the List component, call scrollToIndex\n this._list.current && this._list.current.scrollToIndex(itemIndex);\n };\n}\n"]}
+4
View File
@@ -0,0 +1,4 @@
export * from './ComboBox';
export * from './ComboBox.types';
export * from './VirtualizedComboBox';
export type { IComboBoxClassNames, IComboBoxOptionClassNames } from './ComboBox.classNames';
+8
View File
@@ -0,0 +1,8 @@
define(["require", "exports", "tslib", "./ComboBox", "./ComboBox.types", "./VirtualizedComboBox"], function (require, exports, tslib_1, ComboBox_1, ComboBox_types_1, VirtualizedComboBox_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
tslib_1.__exportStar(ComboBox_1, exports);
tslib_1.__exportStar(ComboBox_types_1, exports);
tslib_1.__exportStar(VirtualizedComboBox_1, exports);
});
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["components/ComboBox/index.ts"],"names":[],"mappings":";;;IAAA,0CAA2B;IAC3B,gDAAiC;IACjC,qDAAsC","sourcesContent":["export * from './ComboBox';\nexport * from './ComboBox.types';\nexport * from './VirtualizedComboBox';\nexport type { IComboBoxClassNames, IComboBoxOptionClassNames } from './ComboBox.classNames';\n"]}