UNPKG

@carbon/ibm-products

Version:
278 lines (276 loc) 11.1 kB
/** * Copyright IBM Corp. 2020, 2026 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import { __toESM } from "../../_virtual/_rolldown/runtime.js"; import { require_classnames } from "../../node_modules/classnames/index.js"; import { pkg } from "../../settings.js"; import { TearsheetNarrow } from "../Tearsheet/TearsheetNarrow.js"; import { NotFoundEmptyState } from "../EmptyStates/NotFoundEmptyState/NotFoundEmptyState.js"; import { Tearsheet } from "../Tearsheet/Tearsheet.js"; import { AddSelectSidebar } from "./AddSelectSidebar.js"; import { AddSelectBreadcrumbs } from "./AddSelectBreadcrumbs.js"; import { AddSelectList } from "./AddSelectList.js"; import { AddSelectSort } from "./AddSelectSort.js"; import { getFilteredItems, sortItems } from "./add-select-utils.js"; import { useItemSort } from "./hooks/useItemSort.js"; import useParentSelect from "./hooks/useParentSelect.js"; import { AddSelectColumn } from "./AddSelectColumn.js"; import { AddSelectFilter } from "./AddSelectFilter.js"; import usePath from "./hooks/usePath.js"; import React, { forwardRef, useState } from "react"; import PropTypes from "prop-types"; import { Tag } from "@carbon/react"; //#region src/components/AddSelect/AddSelectBody.tsx var import_classnames = /* @__PURE__ */ __toESM(require_classnames()); const blockClass = `${pkg.prefix}--add-select`; const componentName = "AddSelectBody"; const AddSelectBody = forwardRef(({ className, clearFiltersText, closeIconDescription, columnInputPlaceholder, defaultModifiers, description, filterByLabel, globalFilterOpts, globalFiltersLabel, globalFiltersIconDescription, globalFiltersPlaceholderText, globalFiltersPrimaryButtonText, globalFiltersSecondaryButtonText, globalSearchLabel, globalSearchPlaceholder, globalSortBy, illustrationTheme, influencerTitle, items, itemsLabel, metaIconDescription, metaPanelTitle, multi, navIconDescription, noResultsDescription, noResultsTitle, noSelectionDescription, noSelectionTitle, noTearsheet = false, normalizedItems, onClose, onCloseButtonText, onSubmit, onSubmitButtonText, open, portalTarget, searchResultsTitle, sortByLabel, title, useNormalizedItems, ...rest }, ref) => { const [singleSelection, setSingleSelection] = useState(""); const [multiSelection, setMultiSelection] = useState([]); const [searchTerm, setSearchTerm] = useState(""); const [appliedGlobalFilters, setAppliedGlobalFilters] = useState({}); const [displayMetalPanel, setDisplayMetaPanel] = useState({}); const [appliedModifiers, setAppliedModifiers] = useState(defaultModifiers); const { sortDirection, setSortDirection, sortAttribute, setSortAttribute } = useItemSort(); const { parentSelected, setParentSelected } = useParentSelect(); const { path, setPath, pathOnclick, resetPath } = usePath(itemsLabel); const resetState = () => { setSingleSelection(""); setMultiSelection([]); setSearchTerm(""); setAppliedGlobalFilters({}); setDisplayMetaPanel({}); setAppliedModifiers(defaultModifiers); setSortAttribute(""); setSortDirection(""); setParentSelected(null); resetPath(); }; const onCloseHandler = () => { resetState(); onClose?.(); }; const tearsheetClassnames = (0, import_classnames.default)(className, blockClass, { [`${blockClass}__single`]: !multi, [`${blockClass}__multi`]: multi }); const globalFilterKeys = Object.keys(appliedGlobalFilters); const globalFiltersApplied = globalFilterKeys.length > 0; const handleSearch = (term) => { setSearchTerm(term); }; const handleFilter = (filters) => { setAppliedGlobalFilters(filters); }; const submitHandler = () => { if (multi && appliedModifiers && appliedModifiers?.length > 0) { const selections = multiSelection.map((item) => { return appliedModifiers.find((mod) => mod.id === item); }); onSubmit?.(selections); } else if (multi && appliedModifiers?.length === 0) onSubmit?.(multiSelection); else onSubmit?.(singleSelection); onCloseHandler(); }; const setShowBreadsCrumbs = () => { if (useNormalizedItems === false || searchTerm || globalFiltersApplied) return false; return true; }; const setShowTags = () => { if (searchTerm) return true; if (useNormalizedItems && multi) return false; return true; }; const parentSelectionHandler = (id, title, parentId) => { setParentSelected(id); setPath(id, title, parentId); }; const itemsToDisplay = getFilteredItems(useNormalizedItems, normalizedItems, searchTerm, globalFiltersApplied, globalFilterKeys, appliedGlobalFilters, sortItems(sortAttribute, sortDirection), multi, items, path); const hasResults = itemsToDisplay.length > 0; const showBreadsCrumbs = setShowBreadsCrumbs(); const showSort = (searchTerm || globalFiltersApplied) && hasResults; const showTags = setShowTags(); const commonListProps = { displayMetalPanel, metaIconDescription, multi, multiSelection, navIconDescription, path, setMultiSelection, setPath, setSingleSelection, singleSelection, setDisplayMetaPanel, parentId: path[0].id }; const commonTearsheetProps = { ...rest, className: tearsheetClassnames, open, title, description, actions: [{ label: onCloseButtonText, kind: "secondary", onClick: onCloseHandler }, { label: onSubmitButtonText, kind: "primary", onClick: submitHandler, disabled: multi ? multiSelection.length === 0 : !singleSelection }], portalTarget, ref }; const sidebarProps = { appliedModifiers, closeIconDescription, displayMetalPanel, illustrationTheme, influencerTitle, items: useNormalizedItems ? normalizedItems : items?.entries, metaPanelTitle, modifiers: items?.modifiers, multiSelection, noSelectionDescription, noSelectionTitle, setDisplayMetaPanel }; const displayColumnView = multi && useNormalizedItems && !searchTerm && !globalFiltersApplied; const body = /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { id: "add-select", className: `${blockClass}__header` }, /* @__PURE__ */ React.createElement(AddSelectFilter, { inputLabel: globalSearchLabel, inputPlaceholder: globalSearchPlaceholder, searchTerm, handleSearch, multi, filterOpts: globalFilterOpts, filtersLabel: globalFiltersLabel, handleFilter, primaryButtonText: globalFiltersPrimaryButtonText, secondaryButtonText: globalFiltersSecondaryButtonText, placeholder: globalFiltersPlaceholderText, iconDescription: globalFiltersIconDescription, appliedFilters: appliedGlobalFilters, hasFiltersApplied: globalFiltersApplied, clearFiltersText }), /* @__PURE__ */ React.createElement("div", { className: (0, import_classnames.default)(`${blockClass}__sub-header`, { [`${blockClass}__sub-header-multi`]: multi }) }, /* @__PURE__ */ React.createElement("div", { className: `${blockClass}__tags` }, showBreadsCrumbs ? /* @__PURE__ */ React.createElement(AddSelectBreadcrumbs, { path, onClick: pathOnclick, multi }) : /* @__PURE__ */ React.createElement("p", { className: `${blockClass}__tags-label` }, searchTerm ? searchResultsTitle : itemsLabel), showTags && /* @__PURE__ */ React.createElement(Tag, { type: "gray", size: "sm" }, itemsToDisplay.length)), showSort && /* @__PURE__ */ React.createElement(AddSelectSort, { setSortAttribute, setSortDirection, sortBy: globalSortBy }))), displayColumnView ? /* @__PURE__ */ React.createElement("div", { className: `${blockClass}__columns` }, /* @__PURE__ */ React.createElement(AddSelectColumn, { ...commonListProps, items: itemsToDisplay, columnInputPlaceholder, header: path[0]?.title, filterByLabel, sortByLabel })) : /* @__PURE__ */ React.createElement("div", null, hasResults ? /* @__PURE__ */ React.createElement(AddSelectList, { ...commonListProps, filteredItems: itemsToDisplay, modifiers: items?.modifiers, appliedModifiers, setAppliedModifiers, setParentSelected: parentSelectionHandler, parentSelected, parentId: parentSelected || path[0].id }) : /* @__PURE__ */ React.createElement("div", { className: `${blockClass}__body` }, /* @__PURE__ */ React.createElement(NotFoundEmptyState, { subtitle: noResultsDescription, title: noResultsTitle, illustrationTheme })))); if (noTearsheet) return body; if (multi) return /* @__PURE__ */ React.createElement(Tearsheet, { ...commonTearsheetProps, influencer: multi && /* @__PURE__ */ React.createElement(AddSelectSidebar, sidebarProps), influencerPosition: "right" }, body); return /* @__PURE__ */ React.createElement(TearsheetNarrow, commonTearsheetProps, body); }); AddSelectBody.propTypes = { className: PropTypes.string, clearFiltersText: PropTypes.string, closeIconDescription: PropTypes.string, columnInputPlaceholder: PropTypes.string, defaultModifiers: PropTypes.array, description: PropTypes.string, filterByLabel: PropTypes.string, globalFilterOpts: PropTypes.array, globalFiltersIconDescription: PropTypes.string, globalFiltersLabel: PropTypes.string, globalFiltersPlaceholderText: PropTypes.string, globalFiltersPrimaryButtonText: PropTypes.string, globalFiltersSecondaryButtonText: PropTypes.string, globalSearchLabel: PropTypes.string.isRequired, globalSearchPlaceholder: PropTypes.string, globalSortBy: PropTypes.array, illustrationTheme: PropTypes.oneOf(["light", "dark"]), influencerTitle: PropTypes.string, /**@ts-ignore */ items: PropTypes.shape({ modifiers: PropTypes.shape({ id: PropTypes.string, label: PropTypes.string, options: PropTypes.array, multiSelect: PropTypes.bool }), sortBy: PropTypes.array, filterBy: PropTypes.array, entries: PropTypes.arrayOf(PropTypes.shape({ avatar: PropTypes.shape({ alt: PropTypes.string, icon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), src: PropTypes.string, theme: PropTypes.oneOf(["light", "dark"]) }), children: PropTypes.object, icon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), id: PropTypes.string.isRequired, meta: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.string, title: PropTypes.string, value: PropTypes.string })), PropTypes.node]), subtitle: PropTypes.string, title: PropTypes.string.isRequired, value: PropTypes.string.isRequired })) }), itemsLabel: PropTypes.string, metaIconDescription: PropTypes.string, metaPanelTitle: PropTypes.string, multi: PropTypes.bool, navIconDescription: PropTypes.string, noResultsDescription: PropTypes.string, noResultsTitle: PropTypes.string, noSelectionDescription: PropTypes.string, noSelectionTitle: PropTypes.string, normalizedItems: PropTypes.object, onClose: PropTypes.func, onCloseButtonText: PropTypes.string, onSubmit: PropTypes.func, onSubmitButtonText: PropTypes.string, open: PropTypes.bool, /**@ts-ignore */ portalTarget: PropTypes.node, searchResultsTitle: PropTypes.string, sortByLabel: PropTypes.string, title: PropTypes.string, useNormalizedItems: PropTypes.bool }; AddSelectBody.displayName = componentName; //#endregion export { AddSelectBody };