137 lines
8.3 KiB
JavaScript
137 lines
8.3 KiB
JavaScript
define(["require", "exports", "tslib", "react", "../../Utilities", "@fluentui/react-hooks", "../../Button", "../../Icon"], function (require, exports, tslib_1, React, Utilities_1, react_hooks_1, Button_1, Icon_1) {
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.SearchBoxBase = void 0;
|
|
var COMPONENT_NAME = 'SearchBox';
|
|
var iconButtonStyles = { root: { height: 'auto' }, icon: { fontSize: '12px' } };
|
|
var iconButtonProps = { iconName: 'Clear' };
|
|
var defaultClearButtonProps = { ariaLabel: 'Clear text' };
|
|
var getClassNames = (0, Utilities_1.classNamesFunction)();
|
|
var useComponentRef = function (componentRef, inputElementRef, hasFocus) {
|
|
React.useImperativeHandle(componentRef, function () { return ({
|
|
focus: function () { var _a; return (_a = inputElementRef.current) === null || _a === void 0 ? void 0 : _a.focus(); },
|
|
blur: function () { var _a; return (_a = inputElementRef.current) === null || _a === void 0 ? void 0 : _a.blur(); },
|
|
hasFocus: function () { return hasFocus; },
|
|
}); }, [inputElementRef, hasFocus]);
|
|
};
|
|
exports.SearchBoxBase = React.forwardRef(function (props, forwardedRef) {
|
|
var ariaLabel = props.ariaLabel, className = props.className, _a = props.defaultValue, defaultValue = _a === void 0 ? '' : _a, disabled = props.disabled, underlined = props.underlined, styles = props.styles,
|
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
labelText = props.labelText, _b = props.placeholder, placeholder = _b === void 0 ? labelText : _b, theme = props.theme, _c = props.clearButtonProps, clearButtonProps = _c === void 0 ? defaultClearButtonProps : _c, _d = props.disableAnimation, disableAnimation = _d === void 0 ? false : _d, _e = props.showIcon, showIcon = _e === void 0 ? false : _e, customOnClear = props.onClear, customOnBlur = props.onBlur, customOnEscape = props.onEscape, customOnSearch = props.onSearch, customOnKeyDown = props.onKeyDown, iconProps = props.iconProps, role = props.role, onChange = props.onChange,
|
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
onChanged = props.onChanged;
|
|
var _f = React.useState(false), hasFocus = _f[0], setHasFocus = _f[1];
|
|
var prevChangeTimestamp = React.useRef(undefined);
|
|
var _g = (0, react_hooks_1.useControllableValue)(props.value, defaultValue, function (ev, newValue) {
|
|
if (ev && ev.timeStamp === prevChangeTimestamp.current) {
|
|
// For historical reasons, SearchBox handles both onInput and onChange (we can't modify this
|
|
// outside a major version due to potential to break partners' tests and possibly apps).
|
|
// Only call props.onChange for one of the events.
|
|
return;
|
|
}
|
|
prevChangeTimestamp.current = ev === null || ev === void 0 ? void 0 : ev.timeStamp;
|
|
onChange === null || onChange === void 0 ? void 0 : onChange(ev, newValue);
|
|
onChanged === null || onChanged === void 0 ? void 0 : onChanged(newValue);
|
|
}), uncastValue = _g[0], setValue = _g[1];
|
|
var value = String(uncastValue);
|
|
var rootElementRef = React.useRef(null);
|
|
var inputElementRef = React.useRef(null);
|
|
var mergedRootRef = (0, react_hooks_1.useMergedRefs)(rootElementRef, forwardedRef);
|
|
var id = (0, react_hooks_1.useId)(COMPONENT_NAME, props.id);
|
|
var customOnClearClick = clearButtonProps.onClick;
|
|
var classNames = getClassNames(styles, {
|
|
theme: theme,
|
|
className: className,
|
|
underlined: underlined,
|
|
hasFocus: hasFocus,
|
|
disabled: disabled,
|
|
hasInput: value.length > 0,
|
|
disableAnimation: disableAnimation,
|
|
showIcon: showIcon,
|
|
});
|
|
var nativeProps = (0, Utilities_1.getNativeProps)(props, Utilities_1.inputProperties, [
|
|
'className',
|
|
'placeholder',
|
|
'onFocus',
|
|
'onBlur',
|
|
'value',
|
|
'role',
|
|
]);
|
|
var onClear = React.useCallback(function (ev) {
|
|
var _a;
|
|
customOnClear === null || customOnClear === void 0 ? void 0 : customOnClear(ev);
|
|
if (!ev.defaultPrevented) {
|
|
setValue('');
|
|
(_a = inputElementRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
ev.stopPropagation();
|
|
ev.preventDefault();
|
|
}
|
|
}, [customOnClear, setValue]);
|
|
var onClearClick = React.useCallback(function (ev) {
|
|
customOnClearClick === null || customOnClearClick === void 0 ? void 0 : customOnClearClick(ev);
|
|
if (!ev.defaultPrevented) {
|
|
onClear(ev);
|
|
}
|
|
}, [customOnClearClick, onClear]);
|
|
var onFocusCapture = function (ev) {
|
|
var _a;
|
|
setHasFocus(true);
|
|
(_a = props.onFocus) === null || _a === void 0 ? void 0 : _a.call(props, ev);
|
|
};
|
|
var onClickFocus = function () {
|
|
if (inputElementRef.current) {
|
|
inputElementRef.current.focus();
|
|
inputElementRef.current.selectionStart = inputElementRef.current.selectionEnd = 0;
|
|
}
|
|
};
|
|
var onBlur = React.useCallback(function (ev) {
|
|
setHasFocus(false);
|
|
customOnBlur === null || customOnBlur === void 0 ? void 0 : customOnBlur(ev);
|
|
}, [customOnBlur]);
|
|
var onInputChange = function (ev) {
|
|
setValue(ev.target.value, ev);
|
|
};
|
|
var onKeyDown = function (ev) {
|
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
switch (ev.which) {
|
|
case Utilities_1.KeyCodes.escape:
|
|
customOnEscape === null || customOnEscape === void 0 ? void 0 : customOnEscape(ev);
|
|
// Only call onClear if the search box has a value to clear. Otherwise, allow the Esc key
|
|
// to propagate from the empty search box to a parent element such as a dialog, etc.
|
|
if (value && !ev.defaultPrevented) {
|
|
onClear(ev);
|
|
}
|
|
break;
|
|
case Utilities_1.KeyCodes.enter:
|
|
if (customOnSearch) {
|
|
customOnSearch(value);
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
}
|
|
break;
|
|
default:
|
|
// REVIEW: Why aren't we calling customOnKeyDown for Escape or Enter?
|
|
customOnKeyDown === null || customOnKeyDown === void 0 ? void 0 : customOnKeyDown(ev);
|
|
// REVIEW: Why are we calling stopPropagation if customOnKeyDown called preventDefault?
|
|
// customOnKeyDown should call stopPropagation if it needs it.
|
|
if (ev.defaultPrevented) {
|
|
ev.stopPropagation();
|
|
}
|
|
break;
|
|
}
|
|
};
|
|
useDebugWarning(props);
|
|
useComponentRef(props.componentRef, inputElementRef, hasFocus);
|
|
return (React.createElement("div", { role: role, ref: mergedRootRef, className: classNames.root, onFocusCapture: onFocusCapture },
|
|
React.createElement("div", { className: classNames.iconContainer, onClick: onClickFocus, "aria-hidden": true },
|
|
React.createElement(Icon_1.Icon, tslib_1.__assign({ iconName: "Search" }, iconProps, { className: classNames.icon }))),
|
|
React.createElement("input", tslib_1.__assign({}, nativeProps, { id: id, className: classNames.field, placeholder: placeholder, onChange: onInputChange, onInput: onInputChange, onBlur: onBlur, onKeyDown: onKeyDown, value: value, disabled: disabled, role: "searchbox", "aria-label": ariaLabel, ref: inputElementRef })),
|
|
value.length > 0 && (React.createElement("div", { className: classNames.clearButton },
|
|
React.createElement(Button_1.IconButton, tslib_1.__assign({ onBlur: onBlur, styles: iconButtonStyles, iconProps: iconButtonProps }, clearButtonProps, { onClick: onClearClick }))))));
|
|
});
|
|
exports.SearchBoxBase.displayName = COMPONENT_NAME;
|
|
function useDebugWarning(props) {
|
|
|
|
}
|
|
});
|
|
//# sourceMappingURL=SearchBox.base.js.map
|