From 20b514c00007ee58533205cb2ded2bd81491dbaf Mon Sep 17 00:00:00 2001 From: Dalton <daltojohnso@users.noreply.github.com> Date: Mon, 13 Dec 2021 10:11:40 -0800 Subject: [PATCH] add renderItemWrapper fn to AccordionList (#19279) --- .../{ => AccordionList}/AccordionList.info.js | 22 +++++++++++++++++ .../{ => AccordionList}/AccordionList.jsx | 6 +++++ .../AccordionList}/AccordionList.unit.spec.js | 24 +++++++++++++++++++ .../components/AccordionList/index.js | 1 + 4 files changed, 53 insertions(+) rename frontend/src/metabase/components/{ => AccordionList}/AccordionList.info.js (67%) rename frontend/src/metabase/components/{ => AccordionList}/AccordionList.jsx (99%) rename frontend/{test/metabase/components => src/metabase/components/AccordionList}/AccordionList.unit.spec.js (78%) create mode 100644 frontend/src/metabase/components/AccordionList/index.js diff --git a/frontend/src/metabase/components/AccordionList.info.js b/frontend/src/metabase/components/AccordionList/AccordionList.info.js similarity index 67% rename from frontend/src/metabase/components/AccordionList.info.js rename to frontend/src/metabase/components/AccordionList/AccordionList.info.js index cf0fab94f7d..5daee074b68 100644 --- a/frontend/src/metabase/components/AccordionList.info.js +++ b/frontend/src/metabase/components/AccordionList/AccordionList.info.js @@ -1,5 +1,8 @@ import React from "react"; +import styled from "styled-components"; + import AccordionList from "metabase/components/AccordionList"; +import TippyPopover from "metabase/components/Popover/TippyPopover"; export const component = AccordionList; export const category = "pickers"; @@ -8,6 +11,9 @@ export const description = ` An expandable and searchable list of sections and items. `; +const PopoverContent = styled.div` + padding: 1em; +`; const sections = [ { name: "Widgets", @@ -51,4 +57,20 @@ export const examples = { hideSingleSectionTitle /> ), + "List Item Popover": ( + <AccordionList + className="text-brand full" + sections={sections} + itemIsSelected={item => item.name === "Foo"} + renderItemWrapper={(itemContent, item) => ( + <TippyPopover + placement="left-start" + interactive + content={<PopoverContent>{item.name}</PopoverContent>} + > + {itemContent} + </TippyPopover> + )} + /> + ), }; diff --git a/frontend/src/metabase/components/AccordionList.jsx b/frontend/src/metabase/components/AccordionList/AccordionList.jsx similarity index 99% rename from frontend/src/metabase/components/AccordionList.jsx rename to frontend/src/metabase/components/AccordionList/AccordionList.jsx index fd3fc967f39..bd02760ba88 100644 --- a/frontend/src/metabase/components/AccordionList.jsx +++ b/frontend/src/metabase/components/AccordionList/AccordionList.jsx @@ -73,6 +73,7 @@ export default class AccordionList extends Component { renderItemDescription: PropTypes.func, renderItemIcon: PropTypes.func, renderItemExtra: PropTypes.func, + renderItemWrapper: PropTypes.func, getItemClassName: PropTypes.func, alwaysTogglable: PropTypes.bool, @@ -474,6 +475,7 @@ const AccordionListCell = ({ renderItemDescription, renderItemIcon, renderItemExtra, + renderItemWrapper, searchText, onChangeSearchText, searchPlaceholder, @@ -601,6 +603,10 @@ const AccordionListCell = ({ )} </div> ); + + if (renderItemWrapper) { + content = renderItemWrapper(content, item); + } } return ( diff --git a/frontend/test/metabase/components/AccordionList.unit.spec.js b/frontend/src/metabase/components/AccordionList/AccordionList.unit.spec.js similarity index 78% rename from frontend/test/metabase/components/AccordionList.unit.spec.js rename to frontend/src/metabase/components/AccordionList/AccordionList.unit.spec.js index d53e4c832fc..7f9382680c0 100644 --- a/frontend/test/metabase/components/AccordionList.unit.spec.js +++ b/frontend/src/metabase/components/AccordionList/AccordionList.unit.spec.js @@ -1,7 +1,9 @@ import React from "react"; import { render, screen, fireEvent } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; import AccordionList from "metabase/components/AccordionList"; +import TippyPopover from "metabase/components/Popover/TippyPopover"; const SECTIONS = [ { @@ -80,6 +82,28 @@ describe("AccordionList", () => { fireEvent.change(SEARCH_FIELD, { target: { value: "Something Else" } }); assertAbsence(["Foo", "Bar", "Baz"]); }); + + describe("with the `renderItemWrapper` prop", () => { + it("should be able to wrap the list items in components like popovers", async () => { + const renderItemWrapper = (itemContent, item) => { + return ( + <TippyPopover content={<div>popover</div>}> + {itemContent} + </TippyPopover> + ); + }; + + render( + <AccordionList + sections={SECTIONS} + renderItemWrapper={renderItemWrapper} + />, + ); + + userEvent.hover(screen.getByText("Foo")); + expect(await screen.findByText("popover")).toBeVisible(); + }); + }); }); function assertAbsence(array) { diff --git a/frontend/src/metabase/components/AccordionList/index.js b/frontend/src/metabase/components/AccordionList/index.js new file mode 100644 index 00000000000..5e468a3c3f4 --- /dev/null +++ b/frontend/src/metabase/components/AccordionList/index.js @@ -0,0 +1 @@ +export { default } from "./AccordionList"; -- GitLab