diff --git a/.changeset/lovely-pears-talk.md b/.changeset/lovely-pears-talk.md new file mode 100644 index 00000000000..8d60c08ede5 --- /dev/null +++ b/.changeset/lovely-pears-talk.md @@ -0,0 +1,5 @@ +--- +'@itwin/itwinui-react': patch +--- + +Fixed `Select` and `LabeledSelect` to correctly handle generic types. diff --git a/packages/itwinui-react/src/core/LabeledSelect/LabeledSelect.test.tsx b/packages/itwinui-react/src/core/LabeledSelect/LabeledSelect.test.tsx index d299f8418b9..38a9204143e 100644 --- a/packages/itwinui-react/src/core/LabeledSelect/LabeledSelect.test.tsx +++ b/packages/itwinui-react/src/core/LabeledSelect/LabeledSelect.test.tsx @@ -188,3 +188,16 @@ it('should handle required attribute', () => { expect(container.querySelector('.iui-input-label.iui-required')).toBeTruthy(); }); + +it('should allow passing ref to LabeledSelect', () => { + const selectRef = React.createRef(); + render( + , + ); + + expect(selectRef?.current).toHaveAttribute('data-select'); +}); diff --git a/packages/itwinui-react/src/core/LabeledSelect/LabeledSelect.tsx b/packages/itwinui-react/src/core/LabeledSelect/LabeledSelect.tsx index e631de7f808..11a5a693d98 100644 --- a/packages/itwinui-react/src/core/LabeledSelect/LabeledSelect.tsx +++ b/packages/itwinui-react/src/core/LabeledSelect/LabeledSelect.tsx @@ -163,6 +163,8 @@ export const LabeledSelect = React.forwardRef( ); }, -); +) as ( + props: LabeledSelectProps & { ref?: React.ForwardedRef }, +) => JSX.Element; export default LabeledSelect; diff --git a/packages/itwinui-react/src/core/LabeledSelect/LabeledSelect.types-test.tsx b/packages/itwinui-react/src/core/LabeledSelect/LabeledSelect.types-test.tsx new file mode 100644 index 00000000000..8b32cc7e8da --- /dev/null +++ b/packages/itwinui-react/src/core/LabeledSelect/LabeledSelect.types-test.tsx @@ -0,0 +1,87 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Bentley Systems, Incorporated. All rights reserved. + * See LICENSE.md in the project root for license terms and full copyright notice. + *--------------------------------------------------------------------------------------------*/ +/** + * This test file tests some LabeledSelect type related cases that have not been tested in other files + * (e.g. react-workshop, unit tests, etc.) + */ + +import React, { useRef } from 'react'; +import LabeledSelect from './LabeledSelect.js'; + +() => { + const ref = useRef(null); + return ( + <> + { + const returnValue: number = value; + return returnValue; + }} + ref={ref} + /> + + ); +}; + +() => { + return ( + <> + + options={[ + { value: 1, label: 'Option 1' }, + { value: 2, label: 'Option 2' }, + { value: 3, label: 'Option 3' }, + ]} + onChange={(value) => { + const returnValue: number = value; + return returnValue; + }} + /> + + ); +}; + +() => { + return ( + <> + + label='Select Label' + options={[ + { value: '1', label: 'Item #1' }, + { value: '2', label: 'Item #2' }, + { value: '3', label: 'Item #3' }, + ]} + onChange={(value) => { + const returnValue: string = value; + return returnValue; + }} + /> + + ); +}; + +() => { + return ( + <> + + label='Select Label' + options={[ + // There should be error: TS 2322 + // @ts-expect-error (TS 2322): Type 'number' is not assignable to type 'string'. + { value: 1, label: 'Item #1' }, + ]} + onChange={(value) => { + const returnValue: string = value; + return returnValue; + }} + /> + + ); +}; diff --git a/packages/itwinui-react/src/core/Select/Select.test.tsx b/packages/itwinui-react/src/core/Select/Select.test.tsx index 69204c43842..4db21a9d073 100644 --- a/packages/itwinui-react/src/core/Select/Select.test.tsx +++ b/packages/itwinui-react/src/core/Select/Select.test.tsx @@ -598,3 +598,16 @@ it.each([true, false] as const)( expect(selectButton).toHaveTextContent('B'); }, ); + +it('should allow passing ref to Select', () => { + const selectRef = React.createRef(); + render( + { + const returnValue: number = value; + return returnValue; + }} + ref={ref} + /> + + ); +}; + +() => { + return ( + <> + + options={[ + { value: 1, label: 'Option 1' }, + { value: 2, label: 'Option 2' }, + { value: 3, label: 'Option 3' }, + ]} + onChange={(value) => { + const returnValue: number = value; + return returnValue; + }} + /> + + ); +}; + +() => { + return ( + <> + + options={[ + { value: '1', label: 'Option 1' }, + { value: '2', label: 'Option 2' }, + { value: '3', label: 'Option 3' }, + ]} + onChange={(value) => { + const returnValue: string = value; + return returnValue; + }} + /> + + ); +}; + +() => { + return ( + <> + + label='Select Label' + options={[ + // There should be error: TS 2322 + // @ts-expect-error (TS 2322): Type 'number' is not assignable to type 'string'. + { value: 1, label: 'Item #1' }, + ]} + onChange={(value) => { + const returnValue: string = value; + return returnValue; + }} + /> + + ); +}; diff --git a/packages/itwinui-react/src/react-table/react-table.types-test.tsx b/packages/itwinui-react/src/react-table/react-table.types-test.tsx index 8c934dd0bb9..0c73342e07c 100644 --- a/packages/itwinui-react/src/react-table/react-table.types-test.tsx +++ b/packages/itwinui-react/src/react-table/react-table.types-test.tsx @@ -3,7 +3,7 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** - * This test file to test some Table type related cases that have not been tested in other files + * This test file tests some Table type related cases that have not been tested in other files * (e.g. react-workshop, unit tests, etc.) */ diff --git a/packages/itwinui-react/tsconfig.test.json b/packages/itwinui-react/tsconfig.test.json index 3cc7301e3d2..c651755a89a 100644 --- a/packages/itwinui-react/tsconfig.test.json +++ b/packages/itwinui-react/tsconfig.test.json @@ -1,5 +1,10 @@ { "extends": "./tsconfig.json", // TODO: Test all the files, and not just the Table files or just the build files. - "include": ["src/core/Table/**/*", "src/react-table/*"] + "include": [ + "src/core/Table/**/*", + "src/react-table/*", + "src/core/Select/**/*", + "src/core/LabeledSelect/**/*" + ] }