UNPKG

@itwin/itwinui-react

Version:

A react component library for iTwinUI

232 lines (231 loc) 6.62 kB
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';