Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OptionUnstyled] Define ownerState and slot props' types #32717

Merged
merged 3 commits into from
May 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as React from 'react';
import OptionGroupUnstyled, {
OptionGroupUnstyledLabelSlotProps,
OptionGroupUnstyledListSlotProps,
OptionGroupUnstyledRootSlotProps,
} from '@mui/base/OptionGroupUnstyled';

const Root = React.forwardRef(function Root(
props: OptionGroupUnstyledRootSlotProps,
ref: React.ForwardedRef<HTMLLIElement>,
) {
return <li {...props} ref={ref} />;
});

const Label = React.forwardRef(function Label(
props: OptionGroupUnstyledLabelSlotProps,
ref: React.ForwardedRef<HTMLLIElement>,
) {
return <li {...props} ref={ref} />;
});

const List = React.forwardRef(function List(
props: OptionGroupUnstyledListSlotProps,
ref: React.ForwardedRef<HTMLLIElement>,
) {
return <li {...props} ref={ref} />;
});

const option = <OptionGroupUnstyled components={{ Root, Label, List }} />;
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import React from 'react';
import composeClasses from '../composeClasses';
import { getOptionGroupUnstyledUtilityClass } from './optionGroupUnstyledClasses';
import OptionGroupUnstyledProps from './OptionGroupUnstyledProps';
import { OptionGroupUnstyledProps } from './OptionGroupUnstyled.types';

function useUtilityClasses(disabled: boolean) {
const slots = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';

export interface OptionGroupUnstyledComponentsPropsOverrides {}

export default interface OptionGroupUnstyledProps {
export interface OptionGroupUnstyledProps {
/**
* The human-readable description of the group.
*/
Expand Down Expand Up @@ -41,3 +41,19 @@ export default interface OptionGroupUnstyledProps {
list?: React.ComponentPropsWithRef<'ul'> & OptionGroupUnstyledComponentsPropsOverrides;
};
}

export type OptionGroupUnstyledRootSlotProps = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was surprised at first that we don't have here ownerState, but saw later that we indeed don't have it for simple components :) I guess having the correct types will be helpful for developers :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If developers complain about not having it, we may define type OptionGroupUnstyledOwnerState = OptionGroupUnstyledProps, and pass it to the slots, but I don't think it's necessary now.

children?: React.ReactNode;
className: string;
ref: React.Ref<HTMLLIElement>;
};

export type OptionGroupUnstyledLabelSlotProps = {
children?: React.ReactNode;
className: string;
};

export type OptionGroupUnstyledListSlotProps = {
children?: React.ReactNode;
className: string;
};
3 changes: 1 addition & 2 deletions packages/mui-base/src/OptionGroupUnstyled/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export { default } from './OptionGroupUnstyled';

export type { default as OptionGroupUnstyledProps } from './OptionGroupUnstyledProps';
export * from './OptionGroupUnstyledProps';
export * from './OptionGroupUnstyled.types';

export { default as optionGroupUnstyledClasses } from './optionGroupUnstyledClasses';
export * from './optionGroupUnstyledClasses';
13 changes: 13 additions & 0 deletions packages/mui-base/src/OptionUnstyled/OptionUnstyled.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as React from 'react';
import OptionUnstyled, { OptionUnstyledRootSlotProps } from '@mui/base/OptionUnstyled';

const Root = React.forwardRef(function Root<TValue>(
props: OptionUnstyledRootSlotProps<TValue>,
ref: React.ForwardedRef<HTMLLIElement>,
) {
const { ownerState, ...other } = props;

return <li data-selected={ownerState.selected} {...other} ref={ref} />;
});

const option = <OptionUnstyled value={null} components={{ Root }} />;
9 changes: 8 additions & 1 deletion packages/mui-base/src/OptionUnstyled/OptionUnstyled.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ const dummyGetOptionState = () => ({
selected: false,
});

const dummyGetOptionProps = () => ({});
const dummyGetOptionProps = () => ({
'aria-disabled': false,
'aria-selected': false,
label: '',
onClick: () => {},
role: 'option',
value: '',
});

describe('OptionUnstyled', () => {
const mount = createMount();
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-base/src/OptionUnstyled/OptionUnstyled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import { unstable_useForkRef as useForkRef } from '@mui/utils';
import { OptionState } from '../ListboxUnstyled';
import composeClasses from '../composeClasses';
import OptionUnstyledProps, { OptionUnstyledOwnerState } from './OptionUnstyledProps';
import { OptionUnstyledProps, OptionUnstyledOwnerState } from './OptionUnstyled.types';
import { SelectUnstyledContext } from '../SelectUnstyled/SelectUnstyledContext';
import { getOptionUnstyledUtilityClass } from './optionUnstyledClasses';
import appendOwnerState from '../utils/appendOwnerState';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React from 'react';
import { Simplify } from '@mui/types';
import { OptionState } from '../ListboxUnstyled';
import { UseSelectOptionSlotProps } from '../SelectUnstyled/useSelect.types';

export interface OptionUnstyledComponentsPropsOverrides {}

export default interface OptionUnstyledProps<TValue> {
export interface OptionUnstyledProps<TValue> {
/**
* The value of the option.
*/
Expand Down Expand Up @@ -44,4 +46,13 @@ export default interface OptionUnstyledProps<TValue> {
label?: string;
}

export type OptionUnstyledOwnerState<TValue> = OptionUnstyledProps<TValue> & OptionState;
export type OptionUnstyledOwnerState<TValue> = Simplify<OptionUnstyledProps<TValue> & OptionState>;

export type OptionUnstyledRootSlotProps<TValue> = Simplify<
UseSelectOptionSlotProps & {
children?: React.ReactNode;
className: string;
ref: React.Ref<HTMLLIElement>;
ownerState: OptionUnstyledOwnerState<TValue>;
}
>;
3 changes: 1 addition & 2 deletions packages/mui-base/src/OptionUnstyled/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export { default } from './OptionUnstyled';

export type { default as OptionUnstyledProps } from './OptionUnstyledProps';
export * from './OptionUnstyledProps';
export * from './OptionUnstyled.types';

export { default as optionUnstyledClasses } from './optionUnstyledClasses';
export * from './optionUnstyledClasses';
4 changes: 2 additions & 2 deletions packages/mui-base/src/SelectUnstyled/SelectUnstyledContext.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as React from 'react';
import { OptionState } from '../ListboxUnstyled';
import { SelectOption } from './useSelect.types';
import { SelectOption, UseSelectOptionSlotProps } from './useSelect.types';

export interface SelectUnstyledContextType {
getOptionState: (value: SelectOption<any>) => OptionState;
getOptionProps: (option: SelectOption<any>) => Record<string, any>;
getOptionProps: (option: SelectOption<any>) => UseSelectOptionSlotProps;
listboxRef: React.RefObject<HTMLElement>;
}

Expand Down