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

Custom component properties override remove ref #2721

Closed
11 tasks done
melloware opened this issue Apr 6, 2022 · 4 comments · Fixed by #2728 or #2730
Closed
11 tasks done

Custom component properties override remove ref #2721

melloware opened this issue Apr 6, 2022 · 4 comments · Fixed by #2728 or #2730
Assignees
Labels
Type: Bug Issue contains a defect related to a specific component.
Milestone

Comments

@melloware
Copy link
Member

melloware commented Apr 6, 2022

Based on: #2708

Components Affected:

  • AutoComplete
  • CascadeSelect
  • Checkbox
  • DataTable
  • Dropdown
  • ListBox
  • MultiSelect
  • RadioButton
  • SelectButton
  • TreeSelect
  • TreeTable

I have a custom component that I wrap PrimeReact AutoComplete like this...

/**
 * Properties for this component which extends PrimeReact AutoComplete.
 */
export interface ActiveDirectoryAutocompleteProps extends AutoCompleteProps {
    value?: ActiveDirectoryUser | ActiveDirectoryUser[];
    suggestions?: ActiveDirectoryUser[];
}

/**
 * JSON object which represents the users in the dropdown.
 */
export interface ActiveDirectoryUser {
    givenName?: string;
    surname?: string;
    jobTitle?: string;
    location?: string;
}

/**
 * Autocomplete for displaying users from Active Directory.
 * 
 * @param {ActiveDirectoryAutocompleteProps} props properties to configure this component
 * @returns {ActiveDirectoryAutocomplete} component
 */
export const ActiveDirectoryAutocomplete = (props: ActiveDirectoryAutocompleteProps) => {

    const selectedItemTemplate = (item: ActiveDirectoryUser) => {
        return `${item.firstName} ${item.lastName}`;
    }

    const itemTemplate = (item: ActiveDirectoryUser) => {
        return (
            <span className="add-user-item flex">
                <div className="flex-initial flex align-items-center justify-content-center">
                    <LetterAvatar fullname={`${item.firstName} ${item.lastName}`} />
                </div>
                <div className="ml-3">
                    <div className="w-full">
                        <span className="block font-bold white-space-nowrap">{item.firstName} {item.lastName}</span>
                    </div>
                    <div style={{ color: "var(--text-color-secondary)" }}>
                        <span className="block text-overflow-ellipsis">{item.email} | {item.jobTitle} | {item.location}</span>
                    </div>
                </div>
            </span>
        );
    }

    return (
        <AutoComplete
            selectedItemTemplate={selectedItemTemplate}
            itemTemplate={itemTemplate}
            delay={400}
            placeholder={!props.value ? "Start typing user name" : ''}
            {...props}
        />
    )
}

However now when I am passing {...props} to do property expansion its failing to compile with... This works in 7.2.1 but now doesn't like it even though above I am extends AutoCompleteProps.

src/components/misc/ActiveDirectoryAutocomplete.tsx:77:10 - error TS2769: No overload matches this call.
  Overload 1 of 2, '(props: AutoCompleteProps | Readonly<AutoCompleteProps>): AutoComplete', gave the following error.
    Type '{ id?: string | undefined; inputRef?: Ref<HTMLInputElement> | undefined; value?: any; name?: string | undefined; type?: string | undefined; suggestions?: any[] | undefined; ... 316 more ...; width?: string | ... 1 more ... | undefined; }' is not assignable to type 'IntrinsicClassAttributes<AutoComplete>'.
      Types of property 'ref' are incompatible.
        Type 'LegacyRef<HTMLSpanElement> | undefined' is not assignable to type 'LegacyRef<AutoComplete> | undefined'.
          Type '(instance: HTMLSpanElement | null) => void' is not assignable to type 'LegacyRef<AutoComplete> | undefined'.
            Type '(instance: HTMLSpanElement | null) => void' is not assignable to type '(instance: AutoComplete | null) => void'.
              Types of parameters 'instance' and 'instance' are incompatible.
                Type 'AutoComplete | null' is not assignable to type 'HTMLSpanElement | null'.
                  Type 'AutoComplete' is missing the following properties from type 'HTMLSpanElement': addEventListener,
``

The change was this...

```ts
export interface AutoCompleteProps extends Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, 'onChange' | 'onSelect'> {
  • React version:
    17.0.2

  • PrimeReact version:
    8.0.0-rc1

  • Language: Typecript

@melloware melloware added this to the 8.0.0-rc.2 milestone Apr 6, 2022
@melloware melloware added the Type: Bug Issue contains a defect related to a specific component. label Apr 6, 2022
@melloware
Copy link
Member Author

cc @kalinkrustev

melloware added a commit to melloware/primereact that referenced this issue Apr 8, 2022
@melloware melloware assigned melloware and unassigned mertsincan Apr 8, 2022
@melloware melloware changed the title AutoComplete: Custom component properties override Custom component properties override remove ref Apr 8, 2022
@melloware
Copy link
Member Author

I did a quick check and seems there are more components, that seem to need a similar fix:

  • AutoComplete
  • CascadeSelect
  • Checkbox
  • DataTable
  • Dropdown
  • ListBox
  • MultiSelect
  • RadioButton
  • SelectButton
  • TreeSelect
  • TreeTable

I checked with this code:

interface myAutoCompleteProps extends AutoCompleteProps {};
export const myAutoComplete = (props: myAutoCompleteProps) => <AutoComplete {...props} />;

interface myCascadeSelectProps extends CascadeSelectProps {};
export const myCascadeSelect = (props: myCascadeSelectProps) => <CascadeSelect {...props} />;

interface myCheckboxProps extends CheckboxProps {};
export const myCheckbox = (props: myCheckboxProps) => <Checkbox {...props} />;

interface myDataTableProps extends DataTableProps {};
export const myDataTable = (props: myDataTableProps) => <DataTable {...props} />;

interface myDropdownProps extends DropdownProps {};
export const myDropdown = (props: myDropdownProps) => <Dropdown {...props} />;

interface myListBoxProps extends ListBoxProps {};
export const myListBox = (props: myListBoxProps) => <ListBox {...props} />;

interface myMultiSelectProps extends MultiSelectProps {};
export const myMultiSelect = (props: myMultiSelectProps) => <MultiSelect {...props} />;

interface myRadioButtonProps extends RadioButtonProps {};
export const myRadioButton = (props: myRadioButtonProps) => <RadioButton {...props} />;

interface mySelectButtonProps extends SelectButtonProps {};
export const mySelectButton = (props: mySelectButtonProps) => <SelectButton {...props} />;

interface myTreeSelectProps extends TreeSelectProps {};
export const myTreeSelect = (props: myTreeSelectProps) => <TreeSelect {...props} />;

interface myTreeTableProps extends TreeTableProps {};
export const myTreeTable = (props: myTreeTableProps) => <TreeTable {...props} />;

@mertsincan
Copy link
Member

I'm not sure about this change. I'll check it tomorrow.

@mertsincan mertsincan reopened this Apr 9, 2022
@mertsincan mertsincan self-assigned this Apr 9, 2022
@melloware
Copy link
Member Author

Just to follow up I think I am going for "the element of least surprise".

if I do this...

interface myAutoCompleteProps extends AutoCompleteProps {};
export const myAutoComplete = (props: myAutoCompleteProps) => <AutoComplete {...props} />;

I would not expect the component to fail because the myAutoCompleteProps is identical to myAutoCompleteProps and its even an instanceof AutoComplete props so to pass it down and have it fail seems not logical to me. Just my two cents. 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Issue contains a defect related to a specific component.
Projects
None yet
2 participants