UNPKG

@pnp/spfx-controls-react

Version:

Reusable React controls for SharePoint Framework solutions

179 lines • 9.73 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import * as React from "react"; import get from "lodash/get"; import { Box, Button, Divider, Popup, Text, Tooltip, Tree, tooltipAsLabelBehavior, } from "@fluentui/react-northstar"; import { AudienceIcon, TriangleDownIcon, TriangleEndIcon, } from "@fluentui/react-icons-northstar"; import styles from "./Toolbar.module.scss"; var treeItemIconStyles = { position: "relative", left: "-1rem", height: "1rem", width: "0", display: "block", pointerEvents: "none", }; var treeItemTitleRenderer = function (Component, _a) { var content = _a.content, expanded = _a.expanded, hasSubtree = _a.hasSubtree, restProps = __rest(_a, ["content", "expanded", "hasSubtree"]); return (React.createElement(Component, __assign({ expanded: expanded, hasSubtree: hasSubtree, styles: { display: "flex", justifyContent: "flex-start", alignItems: "center", padding: "0.325rem 0.875rem 0.325rem 1.125rem", }, selectionIndicator: { styles: { flex: "0 0 auto", marginLeft: "1rem" }, } }, restProps), hasSubtree ? (expanded ? (React.createElement(TriangleDownIcon, { styles: treeItemIconStyles })) : (React.createElement(TriangleEndIcon, { styles: treeItemIconStyles }))) : null, React.createElement(Text, { styles: { flex: "1 1 auto", overflow: "hidden", whiteSpace: "nowrap", textOverflow: "ellipsis", pointerEvents: "none", marginRight: ".5rem", }, content: content, className: "extended-toolbar__filters-menu__item__content" }))); }; var addSelectableParent = function (items) { return items.map(function (item) { if (item && item.hasOwnProperty("items")) // eslint-disable-line no-prototype-builtins return Object.assign(item, { selectableParent: true, items: addSelectableParent(get(item, ["items"], [])), }); else return item; }); }; var findSingleTitle = function (selectedId, filters) { var result = undefined; for (var i = 0; i < filters.length; i += 1) { if (get(filters, [i, "id"]) === selectedId) { result = get(filters, [i, "title"]); break; } else if (Array.isArray(get(filters, [i, "items"]))) { var deepResult = findSingleTitle(selectedId, get(filters, [i, "items"])); if (deepResult) { result = deepResult; break; } } } return result; }; var getSingleTitle = function (layout, selectedId, filters) { switch (layout) { case "verbose": return (selectedId && findSingleTitle(selectedId, filters)) || "Filter"; default: case "compact": return selectedId ? "(1)" : ""; } }; export var ToolbarFilter = function (props) { var layout = props.layout, filters = props.filters, externalSelectedFilters = props.selectedFilterIds, singleSelect = props.singleSelect, open = props.open, onOpenChange = props.onOpenChange, toolbarMenuProps = props.toolbarMenuProps; var _a = React.useState([]), selectedFilters = _a[0], setSelectedFilters = _a[1]; var propagateSetSelectedFilters = function (eventSelectedFilters) { if (props.onSelectedFiltersChange) { var selectedFiltersAfterNotifyingChange = props.onSelectedFiltersChange(eventSelectedFilters); // If Toolbar is used as a controlled component - i.e. selectedFilterIds is defined - then we ignore the value // returned by the onSelectedFiltersChange callback and assume that selectedFilterIds will be updated // to reflect the new set of selected filters. // If Toolbar is uncontrolled then a defined returned value from the onSelectedFilterChange callback will be // used as the new set of selected filters. if (externalSelectedFilters === undefined) { console.log("externalSelectedFilters is undefined"); if (selectedFiltersAfterNotifyingChange !== undefined && Array.isArray(selectedFiltersAfterNotifyingChange)) { setSelectedFilters(selectedFiltersAfterNotifyingChange); } else { setSelectedFilters(eventSelectedFilters); } } } else { setSelectedFilters(eventSelectedFilters); } }; React.useEffect(function () { if (externalSelectedFilters !== undefined) { setSelectedFilters(externalSelectedFilters); } }, [externalSelectedFilters]); var invokerTitle = singleSelect ? getSingleTitle(layout, selectedFilters[0], filters) : "".concat(layout === "verbose" ? "Filter" : "").concat(selectedFilters.length > 0 ? " (".concat(selectedFilters.length, ")") : ""); var filtersForTree = singleSelect ? filters : addSelectableParent(filters); var filterInvoker = (React.createElement(Button, { text: true, title: "Filter", content: invokerTitle, className: "extended-toolbar__filters-invoker " + styles.toolbarButtonStyles, icon: React.createElement(AudienceIcon, { outline: true }), styles: { marginRight: ".5rem", flex: "0 0 auto", }, onClick: function (e) { return onOpenChange(e, { open: !open }); } })); return filters.length ? (React.createElement(Popup, __assign({}, toolbarMenuProps, { open: open, onOpenChange: onOpenChange, trigger: layout === "compact" ? (React.createElement(Tooltip, { trigger: filterInvoker, content: "Filter", accessibility: tooltipAsLabelBehavior })) : (filterInvoker), content: { styles: { width: "13.75rem" }, content: (React.createElement(Box, { className: "extended-toolbar__filters-menu" }, React.createElement(Box, { className: "extended-toolbar__filters-menu__header", styles: { display: "flex", flexFlow: "row wrap", alignItems: "center", padding: "0 .5rem", } }, React.createElement(Text, { content: "Filter", className: "extended-toolbar__filters-menu__title", styles: { flex: "1 0 auto", padding: ".5rem 0", } }), React.createElement(Button, { text: true, primary: true, content: "Clear", "aria-label": "Clear filter", className: "extended-toolbar__filters-menu__clear-action", onClick: function () { return propagateSetSelectedFilters([]); }, styles: { marginRight: "calc(1px - .5rem)", padding: ".5rem", height: "2rem", minWidth: 0, }, variables: function (_a) { var colorScheme = _a.colorScheme, theme = _a.theme; var color = colorScheme.brand.foreground; switch (theme) { case "teamsHighContrastTheme": color = colorScheme.grey.foregroundHover; break; } return { color: color }; } })), React.createElement(Divider, { styles: { padding: 0, margin: "0 .5rem" } }), React.createElement(Tree, { selectable: true, items: filtersForTree, onSelectedItemIdsChange: function (event, selectProps) { if (selectProps && selectProps.selectedItemIds) { var selectedItemIds = selectProps.selectedItemIds; var nextSelectedFilters = typeof selectedItemIds === "function" ? selectedItemIds(selectedFilters) : Array.isArray(selectedItemIds) ? selectedItemIds : []; propagateSetSelectedFilters(singleSelect ? nextSelectedFilters.slice(nextSelectedFilters.length - 1, nextSelectedFilters.length) : nextSelectedFilters); } }, selectedItemIds: selectedFilters, renderItemTitle: treeItemTitleRenderer, className: "extended-toolbar__filters-menu__tree", "aria-labelledby": "extended-toolbar__filters-menu__title", styles: { padding: "0.3125rem 0" } }))), }, trapFocus: { firstFocusableSelector: ".extended-toolbar__filters-menu__tree [data-is-focusable=true]", } }))) : null; }; //# sourceMappingURL=ToolbarFilter.js.map