From fb372157e93cc171fa596ca9d74b299851db216c Mon Sep 17 00:00:00 2001 From: edleeks87 Date: Thu, 3 Oct 2024 14:59:42 +0100 Subject: [PATCH] fix(option): makes `value` and `text` props optional Updates Option interface to allow `value` and `text` to be optional to allow users to compose `children` for complex layouts. This ensures that `SelectList` height is set relatively when a custom option is passed as child so that there is no overflow fix #6939 --- .../select-list/select-list.component.tsx | 7 +-- .../__internal__/utils/with-filter.hoc.tsx | 4 +- .../select/option/option.component.tsx | 13 ++--- src/components/select/option/option.style.ts | 19 ++++--- src/components/select/option/option.test.tsx | 26 ++++++++++ .../simple-select/components.test-pw.tsx | 49 +++++++++++++++++++ .../simple-select-test.stories.tsx | 48 ++++++++++++++++++ .../select/simple-select/simple-select.mdx | 4 ++ .../select/simple-select/simple-select.pw.tsx | 21 ++++++++ 9 files changed, 173 insertions(+), 18 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 95e642e875..03bb666cc0 100644 --- a/src/components/select/__internal__/select-list/select-list.component.tsx +++ b/src/components/select/__internal__/select-list/select-list.component.tsx @@ -291,11 +291,12 @@ const SelectList = React.forwardRef( const optionChildrenList = useMemo( () => - childrenList.filter( - (child) => + childrenList.filter((child) => { + return ( React.isValidElement(child) && (child.type === Option || child.type === OptionRow) - ), + ); + }), [childrenList] ); diff --git a/src/components/select/__internal__/utils/with-filter.hoc.tsx b/src/components/select/__internal__/utils/with-filter.hoc.tsx index 1f162c349b..92c2d4a2fb 100644 --- a/src/components/select/__internal__/utils/with-filter.hoc.tsx +++ b/src/components/select/__internal__/utils/with-filter.hoc.tsx @@ -150,7 +150,9 @@ const withFilter = ( } return ( - {noResultsMessage || noResultsText} + + {noResultsMessage || noResultsText} + ); } diff --git a/src/components/select/option/option.component.tsx b/src/components/select/option/option.component.tsx index 4fa9679878..03ff613b77 100644 --- a/src/components/select/option/option.component.tsx +++ b/src/components/select/option/option.component.tsx @@ -16,11 +16,11 @@ export interface OptionProps */ id?: string; /** The option's visible text, displayed within `` of `` (eg: an icon, an image, etc) */ + text?: string; + /** Alternative rendered content, displayed within `` of ` {}} + onOpen={() => {}} + onListScrollBottom={() => {}} + > + + + + ); +}; diff --git a/src/components/select/simple-select/simple-select-test.stories.tsx b/src/components/select/simple-select/simple-select-test.stories.tsx index 4e2983e953..1a14a0376c 100644 --- a/src/components/select/simple-select/simple-select-test.stories.tsx +++ b/src/components/select/simple-select/simple-select-test.stories.tsx @@ -663,3 +663,51 @@ export const SimpleSelectWithTruncatedText = () => { ); }; + +export const ComplexCustomChildren = () => { + return ( + + + + ); +}; diff --git a/src/components/select/simple-select/simple-select.mdx b/src/components/select/simple-select/simple-select.mdx index 9c6437eba8..9c6d0f19a4 100644 --- a/src/components/select/simple-select/simple-select.mdx +++ b/src/components/select/simple-select/simple-select.mdx @@ -127,6 +127,10 @@ This prop will be called every time a user scrolls to the bottom of the list. ### Custom Option content +It is also possible to render non-interactive content within the `Option` component. +This can be achieved by passing `children` with no `value` or `text` props set. However, +we recommend checking that there are no accessibility issues with this approach before using it. + ### With multiple columns diff --git a/src/components/select/simple-select/simple-select.pw.tsx b/src/components/select/simple-select/simple-select.pw.tsx index 98e449fb87..0efb533986 100644 --- a/src/components/select/simple-select/simple-select.pw.tsx +++ b/src/components/select/simple-select/simple-select.pw.tsx @@ -19,6 +19,7 @@ import { SimpleSelectControlled, WithObjectAsValue, ListWidth, + ComplexCustomChildren, } from "./components.test-pw"; import { commonDataElementInputPreview, @@ -1131,6 +1132,26 @@ test.describe("SimpleSelect component", () => { await expect(selectInput(page)).toHaveCSS("border-radius", "4px"); await expect(selectListWrapper(page)).toHaveCSS("border-radius", "4px"); }); + + test("should display the custom option in full when list is opened", async ({ + mount, + page, + }) => { + await mount(); + + await selectText(page).click(); + const customOptionContent = selectListCustomChild(page, 1).nth(0); + const wrapper = selectListWrapper(page); + const customOptionHeight = await selectList(page) + .locator("li") + .evaluate((element) => element.getBoundingClientRect().height); + const wrapperHeight = await wrapper.evaluate( + (element) => element.getBoundingClientRect().height + ); + + await expect(customOptionContent).toBeVisible(); + expect(wrapperHeight).toBe(customOptionHeight); + }); }); test.describe("Check height of Select list when opened", () => {