@itwin/itwinui-react
Version:
A react component library for iTwinUI
232 lines (231 loc) • 6.62 kB
JavaScript
import * as React from 'react';
import cx from 'classnames';
import {
InputFlexContainer,
SvgSearch,
SvgCloseSmall,
useSafeContext,
useId,
useMergedRefs,
mergeEventHandlers,
Box,
InputFlexContainerIcon,
InputFlexContainerButton,
} from '../../utils/index.js';
let SearchBoxContext = React.createContext(void 0);
let SearchBoxComponent = React.forwardRef((props, ref) => {
let {
size,
expandable = false,
isDisabled = false,
onCollapse: onCollapseProp,
onExpand: onExpandProp,
isExpanded: isExpandedProp,
children,
inputProps,
className,
...rest
} = props;
let uid = useId();
let [inputId, setInputId] = React.useState(uid);
let inputRef = React.useRef(null);
let openButtonRef = React.useRef(null);
let [localExpanded, setLocalExpanded] = React.useState(isExpandedProp);
let isExpanded = isExpandedProp ?? localExpanded;
let onCollapse = () => {
setLocalExpanded(false);
onCollapseProp?.();
queueMicrotask(() =>
openButtonRef.current?.focus({
preventScroll: true,
}),
);
};
let onExpand = () => {
setLocalExpanded(true);
onExpandProp?.();
queueMicrotask(() =>
inputRef.current?.focus({
preventScroll: true,
}),
);
};
return React.createElement(
SearchBoxContext.Provider,
{
value: {
size,
isDisabled,
onCollapse,
onExpand,
inputRef,
inputId,
setInputId,
openButtonRef,
isExpanded,
expandable,
},
},
React.createElement(
InputFlexContainer,
{
ref: ref,
className: cx(
'iui-searchbox',
{
'iui-expandable-searchbox': expandable,
},
className,
),
size: size,
isDisabled: isDisabled,
'data-iui-expanded': isExpanded,
...rest,
},
children ??
React.createElement(
React.Fragment,
null,
React.createElement(
SearchBoxCollapsedState,
null,
React.createElement(SearchBoxExpandButton, null),
),
React.createElement(
SearchBoxExpandedState,
null,
React.createElement(SearchBoxIcon, null),
React.createElement(SearchBoxInput, inputProps),
expandable
? React.createElement(SearchBoxCollapseButton, null)
: null,
),
),
),
);
});
let SearchBoxCollapsedState = ({ children }) => {
let { isExpanded, expandable } = useSafeContext(SearchBoxContext);
if (!expandable || isExpanded) return null;
return React.createElement(
React.Fragment,
null,
children ?? React.createElement(SearchBoxExpandButton, null),
);
};
if ('development' === process.env.NODE_ENV)
SearchBoxCollapsedState.displayName = 'SearchBox.CollapsedState';
let SearchBoxExpandedState = ({ children }) => {
let { isExpanded, expandable } = useSafeContext(SearchBoxContext);
if (expandable && !isExpanded) return null;
return React.createElement(React.Fragment, null, children);
};
if ('development' === process.env.NODE_ENV)
SearchBoxExpandedState.displayName = 'SearchBox.ExpandedState';
let SearchBoxIcon = React.forwardRef((props, ref) => {
let { className, children, ...rest } = props;
return React.createElement(
InputFlexContainerIcon,
{
'aria-hidden': true,
className: cx('iui-search-icon', className),
ref: ref,
...rest,
},
children ?? React.createElement(SvgSearch, null),
);
});
if ('development' === process.env.NODE_ENV)
SearchBoxIcon.displayName = 'SearchBox.Icon';
let SearchBoxInput = React.forwardRef((props, ref) => {
let { className, id: idProp, ...rest } = props;
let { inputId, setInputId, isDisabled, inputRef } =
useSafeContext(SearchBoxContext);
React.useEffect(() => {
if (idProp && idProp !== inputId) setInputId(idProp);
}, [idProp, inputId, setInputId]);
return React.createElement(Box, {
as: 'input',
id: idProp ?? inputId,
ref: useMergedRefs(ref, inputRef),
role: 'searchbox',
type: 'text',
className: cx('iui-search-input', className),
disabled: isDisabled,
...rest,
});
});
if ('development' === process.env.NODE_ENV)
SearchBoxInput.displayName = 'SearchBox.Input';
let SearchBoxButton = React.forwardRef((props, ref) => {
let { children, ...rest } = props;
let { size: sizeContext, isDisabled } = useSafeContext(SearchBoxContext);
return React.createElement(
InputFlexContainerButton,
{
size: sizeContext,
ref: ref,
disabled: isDisabled,
...rest,
},
children ?? React.createElement(SvgSearch, null),
);
});
if ('development' === process.env.NODE_ENV)
SearchBoxButton.displayName = 'SearchBox.Button';
let SearchBoxCollapseButton = React.forwardRef((props, ref) => {
let { children, onClick: onClickProp, ...rest } = props;
let {
onCollapse,
size: sizeContext,
isDisabled,
} = useSafeContext(SearchBoxContext);
return React.createElement(
SearchBoxButton,
{
ref: ref,
'aria-label': 'Close searchbox',
size: sizeContext,
disabled: isDisabled,
onClick: mergeEventHandlers(onClickProp, onCollapse),
...rest,
},
children ?? React.createElement(SvgCloseSmall, null),
);
});
if ('development' === process.env.NODE_ENV)
SearchBoxCollapseButton.displayName = 'SearchBox.CollapseButton';
let SearchBoxExpandButton = React.forwardRef((props, ref) => {
let { children, onClick: onClickProp, ...rest } = props;
let {
onExpand,
size: sizeContext,
isDisabled,
openButtonRef,
} = useSafeContext(SearchBoxContext);
return React.createElement(
SearchBoxButton,
{
ref: useMergedRefs(ref, openButtonRef),
'aria-label': 'Expand searchbox',
size: sizeContext,
disabled: isDisabled,
onClick: mergeEventHandlers(onClickProp, onExpand),
styleType: 'default',
...rest,
},
children ?? React.createElement(SvgSearch, null),
);
});
if ('development' === process.env.NODE_ENV)
SearchBoxExpandButton.displayName = 'SearchBox.ExpandButton';
export const SearchBox = Object.assign(SearchBoxComponent, {
Icon: SearchBoxIcon,
Input: SearchBoxInput,
Button: SearchBoxButton,
CollapseButton: SearchBoxCollapseButton,
ExpandButton: SearchBoxExpandButton,
ExpandedState: SearchBoxExpandedState,
CollapsedState: SearchBoxCollapsedState,
});
if ('development' === process.env.NODE_ENV) SearchBox.displayName = 'SearchBox';