UNPKG

@carbon/ibm-products

Version:
170 lines (168 loc) 7.91 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. */ const require_runtime = require("../../_virtual/_rolldown/runtime.js"); const require_settings = require("../../settings.js"); const require_useId = require("../../global/js/utils/useId.js"); const require_AddSelectList = require("./AddSelectList.js"); const require_AddSelectSort = require("./AddSelectSort.js"); const require_add_select_utils = require("./add-select-utils.js"); const require_useItemSort = require("./hooks/useItemSort.js"); const require_useParentSelect = require("./hooks/useParentSelect.js"); let react = require("react"); react = require_runtime.__toESM(react); let prop_types = require("prop-types"); prop_types = require_runtime.__toESM(prop_types); let _carbon_react = require("@carbon/react"); let _carbon_react_icons = require("@carbon/react/icons"); //#region src/components/AddSelect/AddSelectColumn.jsx const blockClass = `${require_settings.pkg.prefix}--add-select`; const colClass = `${blockClass}__column`; const componentName = "AddSelectColumn"; let AddSelectColumn = ({ columnInputPlaceholder, filterByLabel, header, items, multiSelection, parentId, path, setMultiSelection, setPath, sortByLabel, ...props }) => { const { parentSelected, setParentSelected } = require_useParentSelect.default(); const selectAllId = require_useId.useId(); const filterId = require_useId.useId(); const searchId = require_useId.useId(); const [searchTerm, setSearchTerm] = (0, react.useState)(""); const { sortDirection, setSortDirection, sortAttribute, setSortAttribute } = require_useItemSort.useItemSort(); const [filterOpen, setFilterOpen] = (0, react.useState)(false); const [filters, setFilters] = (0, react.useState)([]); const { entries, filterBy, sortBy } = items; const getSelectedItem = () => { const parentInPath = path.find((entry) => entry.parentId === parentId); /** * this check helps ensure that when the state of the open columns is cleared by global search * that the columns are rebuilt from the data in the path array */ if (parentInPath && !parentSelected) return entries.find((item) => item.id === parentInPath.id); return entries.find((item) => item.id === parentSelected) ?? null; }; const selectedItem = getSelectedItem(); /** * this check helps prevent children from already being open when you switch from parents * on the same level. for example- using the storybook example, if you click on folder 1, * file 1, folder 2, and then folder 1 again file 1 children shouldn't be expanded. this * check ensures that when a user navigates to parents on the same level that the open state * of their children is cleared by referencing the path array. */ const itemInPath = selectedItem && path.find((entry) => entry.id === selectedItem.id); const allSelected = entries.every((item) => multiSelection.includes(item.id)); const filterByOpts = filterBy ? entries.map((item) => item[filterBy]) : []; const selectAllHandler = (event, { checked }) => { const itemIds = entries.map((item) => item.id); if (checked) setMultiSelection([...new Set([...multiSelection, ...itemIds])]); else setMultiSelection(multiSelection.filter((i) => !itemIds.includes(i))); }; const filterHandler = (checked, opt) => { if (checked) setFilters([...filters, opt]); else setFilters(filters.filter((o) => o !== opt)); }; const filterBySearch = (item) => item.title.toLowerCase().includes(searchTerm); const filterByAttribute = (item) => { if (filters.length === 0) return true; const { filterBy } = item; const filterByValue = item[filterBy]; return filters.some((filter) => filter === filterByValue); }; const filterBtnId = `filter-${filterId}`; const sortFn = require_add_select_utils.sortItems(sortAttribute, sortDirection); const colItems = entries.filter(filterBySearch).filter(filterByAttribute).sort(sortFn); const parentSelectionHandler = (id, title) => { setParentSelected(id); setPath(id, title, parentId); }; return /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement("div", { className: colClass }, /* @__PURE__ */ react.default.createElement("div", { className: `${colClass}-search-bar` }, /* @__PURE__ */ react.default.createElement(_carbon_react.Search, { value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), placeholder: columnInputPlaceholder, className: `${colClass}-input`, id: searchId, labelText: columnInputPlaceholder, size: "md" }), /* @__PURE__ */ react.default.createElement("div", { className: `${colClass}-sort-filter` }, /* @__PURE__ */ react.default.createElement(require_AddSelectSort.AddSelectSort, { items: entries, setSortAttribute, setSortDirection, sortAttribute, sortDirection, sortBy, sortByLabel }), filterByOpts.length > 0 && /* @__PURE__ */ react.default.createElement(_carbon_react.unstable_FeatureFlags, { enableV12DynamicFloatingStyles: true }, /* @__PURE__ */ react.default.createElement(_carbon_react.Popover, { align: "bottom-right", isTabTip: true, onKeyDown: (e) => { if (e.key === "Escape") { setFilterOpen(false); e.preventDefault(); e.stopPropagation(); document.querySelector(`#${filterBtnId}`)?.focus(); } }, onRequestClose: () => setFilterOpen(false), open: filterOpen }, /* @__PURE__ */ react.default.createElement(_carbon_react.IconButton, { size: "md", id: filterBtnId, hasIconOnly: true, "aria-expanded": filterOpen, badgeCount: filters.length > 0 ? 0 : void 0, kind: "ghost", label: filterByLabel || "Filter", onClick: () => { setFilterOpen((prev) => !prev); } }, /* @__PURE__ */ react.default.createElement(_carbon_react_icons.Filter, null)), /* @__PURE__ */ react.default.createElement(_carbon_react.PopoverContent, { className: `${colClass}-filter-popover` }, filterByOpts.map((opt) => /* @__PURE__ */ react.default.createElement(_carbon_react.Checkbox, { key: opt, id: opt, labelText: opt, onChange: (event, { checked }) => filterHandler(checked, opt), checked: filters.find((o) => o === opt) ? true : false }))))))), /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__tags` }, /* @__PURE__ */ react.default.createElement(_carbon_react.Checkbox, { id: `${selectAllId}-select-all`, className: `${colClass}__select-all`, checked: allSelected, onChange: selectAllHandler, labelText: /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement("span", { className: `${blockClass}__tag-label` }, header), /* @__PURE__ */ react.default.createElement(_carbon_react.Tag, { type: "gray", size: "sm" }, colItems.length)) })), /* @__PURE__ */ react.default.createElement(require_AddSelectList.AddSelectList, { ...props, filteredItems: colItems, setMultiSelection, multiSelection, setParentSelected: parentSelectionHandler, parentSelected })), selectedItem && itemInPath && /* @__PURE__ */ react.default.createElement(AddSelectColumn, { columnInputPlaceholder, header: selectedItem.title, items: selectedItem.children, multiSelection, setMultiSelection, parentId: selectedItem.id, setPath, path, sortByLabel, filterByLabel, ...props })); }; AddSelectColumn.propTypes = { columnInputPlaceholder: prop_types.default.string, filterByLabel: prop_types.default.string, header: prop_types.default.string, items: prop_types.default.object, multiSelection: prop_types.default.array, parentId: prop_types.default.string, path: prop_types.default.array, setMultiSelection: prop_types.default.func, setPath: prop_types.default.func, sortByLabel: prop_types.default.string }; AddSelectColumn.displayName = componentName; //#endregion exports.AddSelectColumn = AddSelectColumn;