Skip to content

Commit

Permalink
Revert "[Select] Update renderValue prop's TypeScript type (#34177)"
Browse files Browse the repository at this point in the history
This reverts commit fea32da.
  • Loading branch information
michaldudak committed Jan 5, 2023
1 parent fb1846b commit 0f1a159
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 161 deletions.
108 changes: 25 additions & 83 deletions packages/mui-material/src/Select/Select.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { OutlinedInputProps } from '../OutlinedInput';

export { SelectChangeEvent };

interface CommonProps<T>
export interface SelectProps<T = unknown>
extends StandardProps<InputProps, 'value' | 'onChange'>,
Omit<OutlinedInputProps, 'value' | 'onChange'>,
Pick<SelectInputProps<T>, 'onChange'> {
Expand Down Expand Up @@ -41,6 +41,17 @@ interface CommonProps<T>
* The default value. Use when the component is not controlled.
*/
defaultValue?: T;
/**
* If `true`, a value is displayed even if no items are selected.
*
* In order to display a meaningful value, a function can be passed to the `renderValue` prop which
* returns the value to be displayed when no items are selected.
*
* ⚠️ When using this prop, make sure the label doesn't overlap with the empty displayed value.
* The label should either be hidden or forced to a shrunk state.
* @default false
*/
displayEmpty?: boolean;
/**
* The icon that displays the arrow.
* @default ArrowDropDownIcon
Expand Down Expand Up @@ -72,6 +83,11 @@ interface CommonProps<T>
* Props applied to the [`Menu`](/material-ui/api/menu/) element.
*/
MenuProps?: Partial<MenuProps>;
/**
* If `true`, `value` must be an array and the menu will support multiple selections.
* @default false
*/
multiple?: boolean;
/**
* If `true`, the component uses a native `select` element.
* @default false
Expand Down Expand Up @@ -105,6 +121,14 @@ interface CommonProps<T>
* You can only use it when the `native` prop is `false` (default).
*/
open?: boolean;
/**
* Render the selected value.
* You can only use it when the `native` prop is `false` (default).
*
* @param {any} value The `value` provided to the component.
* @returns {ReactNode}
*/
renderValue?: (value: T) => React.ReactNode;
/**
* Props applied to the clickable div element.
*/
Expand All @@ -128,88 +152,6 @@ interface CommonProps<T>
variant?: 'standard' | 'outlined' | 'filled';
}

type ConditionalRenderValueType<T> =
| {
/**
* If `true`, a value is displayed even if no items are selected.
*
* In order to display a meaningful value, a function can be passed to the `renderValue` prop which
* returns the value to be displayed when no items are selected.
*
* ⚠️ When using this prop, make sure the label doesn't overlap with the empty displayed value.
* The label should either be hidden or forced to a shrunk state.
* @default false
*/
displayEmpty?: false;
/**
* If `true`, `value` must be an array and the menu will support multiple selections.
* @default false
*/
multiple?: boolean;
/**
* Render the selected value.
* You can only use it when the `native` prop is `false` (default).
*
* @param {any} value The `value` provided to the component.
* @returns {ReactNode}
*/
renderValue?: (value: T) => React.ReactNode;
}
| {
/**
* If `true`, a value is displayed even if no items are selected.
*
* In order to display a meaningful value, a function can be passed to the `renderValue` prop which
* returns the value to be displayed when no items are selected.
*
* ⚠️ When using this prop, make sure the label doesn't overlap with the empty displayed value.
* The label should either be hidden or forced to a shrunk state.
* @default false
*/
displayEmpty: true;
/**
* If `true`, `value` must be an array and the menu will support multiple selections.
* @default false
*/
multiple?: false;
/**
* Render the selected value.
* You can only use it when the `native` prop is `false` (default).
*
* @param {any} value The `value` provided to the component.
* @returns {ReactNode}
*/
renderValue?: (value: T | '') => React.ReactNode;
}
| {
/**
* If `true`, a value is displayed even if no items are selected.
*
* In order to display a meaningful value, a function can be passed to the `renderValue` prop which
* returns the value to be displayed when no items are selected.
*
* ⚠️ When using this prop, make sure the label doesn't overlap with the empty displayed value.
* The label should either be hidden or forced to a shrunk state.
* @default false
*/
displayEmpty: true;
/**
* If `true`, `value` must be an array and the menu will support multiple selections.
* @default false
*/
multiple: true;
/**
* Render the selected value.
* You can only use it when the `native` prop is `false` (default).
*
* @param {any} value The `value` provided to the component.
* @returns {ReactNode}
*/
renderValue?: (value: T) => React.ReactNode;
};

export type SelectProps<T = unknown> = CommonProps<T> & ConditionalRenderValueType<T>;

/**
*
* Demos:
Expand Down
78 changes: 0 additions & 78 deletions packages/mui-material/src/Select/Select.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,81 +45,3 @@ function genericValueTest() {
// disabledUnderline prop should be available (inherited from InputProps) and NOT throw typescript error
<Select disableUnderline />;
}

function App() {
enum MyEnum {
FIRST = 'first',
SECOND = 'second',
}

const [selectedValue, setSelectedValue] = React.useState<MyEnum | ''>('');
const [personName, setPersonName] = React.useState<string[]>([]);

return (
<React.Fragment>
{/* displayEmpty is true */}
<Select
renderValue={(value) => {
if (value === '') {
return 'None selected';
}
return value;
}}
displayEmpty
value={selectedValue}
onChange={(e) => setSelectedValue(e.target.value as MyEnum)}
>
<MenuItem value="">
<em>Blank</em>
</MenuItem>
<MenuItem value="first">first</MenuItem>
<MenuItem value="second">second</MenuItem>
</Select>

{/* displayEmpty is false */}
<Select
renderValue={(value) => {
// @ts-expect-error value cannot be empty string since displayEmpty is false
if (value === '') {
return 'None selected';
}
return value;
}}
value={selectedValue}
onChange={(e) => setSelectedValue(e.target.value as MyEnum)}
>
<MenuItem value="">
<em>Blank</em>
</MenuItem>
<MenuItem value="first">first</MenuItem>
<MenuItem value="second">second</MenuItem>
</Select>

{/* displayEmpty is true, multiple is true */}
<Select
displayEmpty
multiple
renderValue={(value) => {
// @ts-expect-error value cannot be empty string
if (value === '') {
return 'None selected';
}

if (value.length === 0) {
return <em>Placeholder</em>;
}

return value.join(', ');
}}
value={personName}
onChange={(e) => setPersonName(e.target.value as string[])}
>
<MenuItem value="">
<em>Blank</em>
</MenuItem>
<MenuItem value="Oliver Hansen">Oliver Hansen</MenuItem>
<MenuItem value="Van Henry">Van Henry</MenuItem>
</Select>
</React.Fragment>
);
}

0 comments on commit 0f1a159

Please sign in to comment.