UNPKG

@ui5/webcomponents-react

Version:

React Wrapper for UI5 Web Components and additional components

243 lines (242 loc) 8.12 kB
'use client'; import ButtonDesign from '@ui5/webcomponents/dist/types/ButtonDesign.js'; import IconMode from '@ui5/webcomponents/dist/types/IconMode.js'; import ListSelectionMode from '@ui5/webcomponents/dist/types/ListSelectionMode.js'; import iconDecline from '@ui5/webcomponents-icons/dist/decline.js'; import iconSearch from '@ui5/webcomponents-icons/dist/search.js'; import { enrichEventWithDetails, useI18nBundle, useStylesheet, useSyncRef } from '@ui5/webcomponents-react-base'; import { clsx } from 'clsx'; import { forwardRef, useEffect, useState } from 'react'; import { CANCEL, CLEAR, RESET, SEARCH, SELECT, SELECTED } from '../../i18n/i18n-defaults.js'; import { Button, Dialog, FlexBox, FlexBoxAlignItems, Icon, Input, List, Text, Title } from '../../index.js'; import { classNames, styleData } from './SelectDialog.module.css.js'; import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; /** * The SelectDialog enables users to filter a comprehensive list via a search field and to select one or more items. */ const SelectDialog = /*#__PURE__*/forwardRef((props, ref) => { const { open, children, className, confirmButtonText, confirmButtonProps, growing, headerText, headerTextAlignCenter, listProps = {}, selectionMode = ListSelectionMode.Single, numberOfSelectedItems, rememberSelections, showClearButton, onClose, onClear, onConfirm, onLoadMore, onSearch, onSearchInput, onSearchReset, onBeforeOpen, onBeforeClose, onOpen, onCancel, ...rest } = props; useStylesheet(styleData, SelectDialog.displayName); const i18nBundle = useI18nBundle('@ui5/webcomponents-react'); const [searchValue, setSearchValue] = useState(''); const [selectedItems, setSelectedItems] = useState([]); const [listComponentRef, listRef] = useSyncRef(listProps.ref); const [internalOpen, setInternalOpen] = useState(open); useEffect(() => { setInternalOpen(open); }, [open]); const handleBeforeOpen = e => { const localSelectedItems = listRef.current?.getSelectedItems() ?? []; if (typeof onBeforeOpen === 'function') { onBeforeOpen(e); } if (selectionMode === ListSelectionMode.Multiple && listRef.current?.hasData) { setSelectedItems(localSelectedItems); } }; const handleAfterOpen = e => { if (typeof onOpen === 'function') { onOpen(e); } listRef.current?.focusFirstItem(); }; const handleSearchInput = e => { if (typeof onSearchInput === 'function') { onSearchInput(enrichEventWithDetails(e, { value: e.target.value })); } setSearchValue(e.target.value); }; const handleSearchSubmit = e => { if (typeof onSearch === 'function') { if (e.type === 'keyup' && e.code === 'Enter') { onSearch(enrichEventWithDetails(e, { value: e.target.value })); } if (e.type === 'click') { onSearch(enrichEventWithDetails(e, { value: searchValue })); } } }; const handleResetSearch = e => { if (typeof onSearchReset === 'function') { onSearchReset(enrichEventWithDetails(e, { prevValue: searchValue })); } setSearchValue(''); }; const handleSelectionChange = e => { if (typeof listProps?.onSelectionChange === 'function') { listProps.onSelectionChange(e); } if (selectionMode === ListSelectionMode.Multiple) { setSelectedItems(e.detail.selectedItems); } else { if (typeof onConfirm === 'function') { onConfirm(e); } setInternalOpen(false); } }; const handleClose = e => { setInternalOpen(false); if (typeof onCancel === 'function') { onCancel(e); } }; const handleClear = e => { if (typeof onClear === 'function') { onClear(enrichEventWithDetails(e, { prevSelectedItems: selectedItems })); } setSelectedItems([]); listRef.current?.deselectSelectedItems(); }; const handleConfirm = e => { if (typeof onConfirm === 'function') { onConfirm(enrichEventWithDetails(e, { selectedItems })); } setInternalOpen(false); }; const handleAfterClose = e => { setInternalOpen(false); if (typeof onClose === 'function') { onClose(e); } if (typeof onSearchReset === 'function') { onSearchReset(enrichEventWithDetails(e, { prevValue: searchValue })); } setSearchValue(''); if (!rememberSelections) { listRef.current?.deselectSelectedItems(); } }; const handleBeforeClose = e => { if (typeof onBeforeClose === 'function') { onBeforeClose(e); } if (typeof onCancel === 'function' && e.detail.escPressed) { onCancel(e); } }; return /*#__PURE__*/_jsxs(Dialog, { ...rest, open: internalOpen, "data-component-name": "SelectDialog", ref: ref, className: clsx(classNames.dialog, className), onClose: handleAfterClose, onBeforeOpen: handleBeforeOpen, onOpen: handleAfterOpen, onBeforeClose: handleBeforeClose, children: [/*#__PURE__*/_jsxs("div", { className: classNames.headerContent, slot: "header", children: [showClearButton && headerTextAlignCenter && /*#__PURE__*/_jsx(Button, { onClick: handleClear, design: ButtonDesign.Transparent, className: classNames.hiddenClearBtn, tabIndex: -1, "aria-hidden": "true", children: i18nBundle.getText(CLEAR) }), /*#__PURE__*/_jsx(Title, { className: clsx(classNames.title, headerTextAlignCenter && classNames.titleCenterAlign), children: headerText }), showClearButton && /*#__PURE__*/_jsx(Button, { onClick: handleClear, design: ButtonDesign.Transparent, className: classNames.clearBtn, children: i18nBundle.getText(CLEAR) }), /*#__PURE__*/_jsx(Input, { className: classNames.input, accessibleName: i18nBundle.getText(SEARCH), value: searchValue, placeholder: i18nBundle.getText(SEARCH), onInput: handleSearchInput, onKeyUp: handleSearchSubmit, icon: /*#__PURE__*/_jsxs(_Fragment, { children: [searchValue && /*#__PURE__*/_jsx(Icon, { accessibleName: i18nBundle.getText(RESET), title: i18nBundle.getText(RESET), name: iconDecline, mode: IconMode.Interactive, onClick: handleResetSearch, className: classNames.inputIcon }), /*#__PURE__*/_jsx(Icon, { mode: IconMode.Interactive, name: iconSearch, className: classNames.inputIcon, onClick: handleSearchSubmit, accessibleName: i18nBundle.getText(SEARCH), title: i18nBundle.getText(SEARCH) })] }) })] }), selectionMode === ListSelectionMode.Multiple && (!!selectedItems.length || numberOfSelectedItems > 0) && /*#__PURE__*/_jsx(FlexBox, { alignItems: FlexBoxAlignItems.Center, className: classNames.infoBar, children: /*#__PURE__*/_jsx(Text, { children: `${i18nBundle.getText(SELECTED)}: ${numberOfSelectedItems ?? selectedItems.length}` }) }), /*#__PURE__*/_jsx(List, { ...listProps, ref: listComponentRef, growing: growing, onLoadMore: onLoadMore, selectionMode: selectionMode, onSelectionChange: handleSelectionChange, children: children }), /*#__PURE__*/_jsxs("div", { slot: "footer", className: classNames.footer, children: [selectionMode === ListSelectionMode.Multiple && /*#__PURE__*/_jsx(Button, { ...confirmButtonProps, onClick: handleConfirm, design: ButtonDesign.Emphasized, children: confirmButtonText ?? i18nBundle.getText(SELECT) }), /*#__PURE__*/_jsx(Button, { onClick: handleClose, design: ButtonDesign.Transparent, children: i18nBundle.getText(CANCEL) })] })] }); }); SelectDialog.displayName = 'SelectDialog'; export { SelectDialog };