From 2f445b50b5cb6f0262fc71afe42a628feab53a5e Mon Sep 17 00:00:00 2001 From: nuria1110 Date: Thu, 19 Dec 2024 11:30:57 +0000 Subject: [PATCH] fix(select): ensure select-list has correct box-shadow when placement is top Adds correct box-shadow style to select-list when placement is "top". fix #7125 --- .../select-list/select-list.component.tsx | 23 ++++++++++ .../select-list/select-list.style.ts | 15 ++++-- .../filterable-select.stories.tsx | 41 ++++++++--------- .../multi-select/multi-select.stories.tsx | 41 ++++++++--------- .../select/simple-select/simple-select.pw.tsx | 46 +++++++++++++++++++ .../simple-select/simple-select.stories.tsx | 41 ++++++++--------- 6 files changed, 139 insertions(+), 68 deletions(-) diff --git a/src/components/select/__internal__/select-list/select-list.component.tsx b/src/components/select/__internal__/select-list/select-list.component.tsx index 6ca2aed6bd..587343f31b 100644 --- a/src/components/select/__internal__/select-list/select-list.component.tsx +++ b/src/components/select/__internal__/select-list/select-list.component.tsx @@ -142,9 +142,11 @@ const SelectList = React.forwardRef( ) => { const [currentOptionsListIndex, setCurrentOptionsListIndex] = useState(-1); const [scrollbarWidth, setScrollbarWidth] = useState(0); + const [actualPlacement, setActualPlacement] = useState(listPlacement); const lastFilter = useRef(""); const listRef = useRef(null); const tableRef = useRef(null); + const listWrapperRef = useRef(null); const listActionButtonRef = useRef(null); const { blockScroll, allowScroll } = useScrollBlock(); const actionButtonHeight = useRef(0); @@ -648,6 +650,25 @@ const SelectList = React.forwardRef( [listWidth, flipEnabled], ); + // set the placement of the list based on the floating placement + const setPlacement = useCallback(() => { + if (isOpen) { + const floatingPlacement = listWrapperRef.current?.getAttribute( + "data-floating-placement", + ) as ListPlacement; + + setActualPlacement(floatingPlacement); + } + }, [isOpen]); + + useEffect(() => { + setPlacement(); + window.addEventListener("resize", setPlacement); + return () => { + window.removeEventListener("resize", setPlacement); + }; + }, [setPlacement]); + const loader = isLoading ? ( @@ -705,9 +726,11 @@ const SelectList = React.forwardRef( animationFrame > ` height: ${({ listHeight }) => `${listHeight}px`}; `; -const StyledSelectListContainer = styled.div< - Pick ->` +interface StyledSelectListContainerProps { + isLoading?: boolean; + placement?: string; +} + +const StyledSelectListContainer = styled.div` background-color: white; - box-shadow: var(--boxShadow100); + box-shadow: ${({ placement }) => + placement === "top" + ? "0 -5px 5px 0 #00141e33, 0 -10px 10px 0 #00141e1a" + : "var(--boxShadow100)"}; animation: fadeIn 250ms ease-out; position: absolute; z-index: ${({ theme }) => theme.zIndex.popover}; diff --git a/src/components/select/filterable-select/filterable-select.stories.tsx b/src/components/select/filterable-select/filterable-select.stories.tsx index e4608ee7e7..3182a65665 100644 --- a/src/components/select/filterable-select/filterable-select.stories.tsx +++ b/src/components/select/filterable-select/filterable-select.stories.tsx @@ -55,27 +55,26 @@ Default.storyName = "Default"; export const ListPlacement: Story = () => { return ( - - - - + + ); }; ListPlacement.storyName = "List Placement"; diff --git a/src/components/select/multi-select/multi-select.stories.tsx b/src/components/select/multi-select/multi-select.stories.tsx index ddb368a757..ac0fee9962 100644 --- a/src/components/select/multi-select/multi-select.stories.tsx +++ b/src/components/select/multi-select/multi-select.stories.tsx @@ -46,27 +46,26 @@ Default.storyName = "Default"; export const ListPlacement: Story = () => { return ( - - - - + + ); }; ListPlacement.storyName = "List Placement"; diff --git a/src/components/select/simple-select/simple-select.pw.tsx b/src/components/select/simple-select/simple-select.pw.tsx index f1268dc298..a2571c78f4 100644 --- a/src/components/select/simple-select/simple-select.pw.tsx +++ b/src/components/select/simple-select/simple-select.pw.tsx @@ -1091,6 +1091,52 @@ test.describe("SimpleSelect component", () => { }); }); + ( + [ + [ + "top", + "rgba(0, 20, 30, 0.2) 0px -5px 5px 0px, rgba(0, 20, 30, 0.1) 0px -10px 10px 0px", + ], + [ + "bottom", + "rgba(0, 20, 30, 0.2) 0px 5px 5px 0px, rgba(0, 20, 30, 0.1) 0px 10px 10px 0px", + ], + ] as [NonNullable, string][] + ).forEach(([position, boxShadow]) => { + test(`should render list with expected box-shadow when listPosition is ${position}`, async ({ + mount, + page, + }) => { + await mount( + , + ); + + await selectText(page).click(); + const listElement = selectListPosition(page); + await expect(listElement).toHaveCSS("box-shadow", boxShadow); + await expect(listElement).toBeVisible(); + }); + }); + + test("should update box-shadow when placement changes due to window resize", async ({ + mount, + page, + }) => { + await mount(); + + await selectText(page).click(); + const listElement = selectListPosition(page); + await expect(listElement).toHaveCSS( + "box-shadow", + "rgba(0, 20, 30, 0.2) 0px 5px 5px 0px, rgba(0, 20, 30, 0.1) 0px 10px 10px 0px", + ); + await page.setViewportSize({ width: 1200, height: 250 }); + await expect(listElement).toHaveCSS( + "box-shadow", + "rgba(0, 20, 30, 0.2) 0px -5px 5px 0px, rgba(0, 20, 30, 0.1) 0px -10px 10px 0px", + ); + }); + test("should have correct hover state of list option", async ({ mount, page, diff --git a/src/components/select/simple-select/simple-select.stories.tsx b/src/components/select/simple-select/simple-select.stories.tsx index 35be78e013..7925ae7058 100644 --- a/src/components/select/simple-select/simple-select.stories.tsx +++ b/src/components/select/simple-select/simple-select.stories.tsx @@ -100,27 +100,26 @@ IsOptional.storyName = "IsOptional"; export const ListPlacement: Story = () => { return ( - - - + ); }; ListPlacement.storyName = "List Placement";