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

Core: Child components do not inherit props correctly #6300

Closed
vaelu opened this issue Apr 4, 2024 · 7 comments · Fixed by #7246
Closed

Core: Child components do not inherit props correctly #6300

vaelu opened this issue Apr 4, 2024 · 7 comments · Fixed by #7246
Assignees
Labels
Component: Unstyled Issue related to unstyled/passthrough attributes
Milestone

Comments

@vaelu
Copy link
Contributor

vaelu commented Apr 4, 2024

Describe the bug

We noticed in the InputNumber component, that PrimeReact does not correctly inherit the props from the parent, so you don't have access to them in the PT you pass to children.

Problem

The InputNumber component has an input inside, which uses the InputText component. In the PT presets, this is the input property (https://github.com/primefaces/primereact/blob/master/components/lib/passthrough/tailwind/index.js#L808-L812).

In our case, we want to order the buttons and inputs with order-1, order-2 and order-3 (like it's done in styled mode). This means we need to style the InputText based on props of the InputNumber (props.showButtons && props.buttonLayout === "horizontal").

const pt = {
  input: {
    root: ({ props }: PInputNumberPassThroughMethodOptions) => ({
      className: classNames(INPUT_CLASSES, {
        'order-2': props.showButtons && props.buttonLayout === "horizontal"
      })
    })
  }
};

Unfortunately it seems that props in this case does not include showButtons or buttonLayout, because they are not inherited from their parent component InputNumber to InputText.

Workaround 1

I noticed that I can get the props with props.__parentMetadata.parent.props.showButtons and props.__parentMetadata.parent.props.buttonLayout, which is clearly wrong, becuase __parentMetadata looks like a private property.

const pt = {
  input: {
    root: ({ props }: PInputNumberPassThroughMethodOptions) => ({
      className: classNames(INPUT_CLASSES, {
        'order-2': props.__parentMetadata.parent.props.showButtons && props.__parentMetadata.parent.props.buttonLayout === 'horizontal'
      })
    })
  }
};

Workaround 2

Also, it's possible to rewrite the passthrough a bit, so that the props are passed in the parent PT (input) instead of the root PT of the input.

const pt = {
  input: ({ props }) => ({
    root: () => ({
      className: classNames(INPUT_CLASSES, {
        'order-2': props.showButtons && props.buttonLayout === "horizontal"
      })
    })
  })
};

This seems like a better solution to me than workaround 1, but still not a clean one, since TypeScript is erroring.

Is this behavior intentional? Is there any good solution for this?

cc @melloware @nitrogenous

Reproducer

https://stackblitz.com/edit/jiw5zb?file=src%2FApp.jsx

PrimeReact version

10.6.2

React version

18.x

Language

TypeScript

Build / Runtime

Vite

Browser(s)

No response

Steps to reproduce the behavior

No response

Expected behavior

No response

@vaelu vaelu added the Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible label Apr 4, 2024
@melloware melloware added Component: Unstyled Issue related to unstyled/passthrough attributes and removed Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible labels Apr 4, 2024
@vaelu
Copy link
Contributor Author

vaelu commented Apr 4, 2024

Update

I found out, that we can pass parent instead of props and then use parent.props.

const pt = {
  input: {
    // FIXME: any type because parent is not available in InputTextPassThroughMethodOptions
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    root: ({ parent }: any) => ({
      className: classNames(INPUT_CLASSES, {
        'order-2': parent.props.showButtons && parent.props.buttonLayout === "horizontal"
      })
    })
  }
};

However, this still gives a TypeScript error, since parent is not available in InputTextPassThroughMethodOptions. Is there a way to solve this?

@melloware
Copy link
Member

Yes if you look at Accordion.d.ts it has this...

/**
 * Custom passthrough(pt) option method.
 */
export interface AccordionTabPassThroughMethodOptions {
    props: AccordionTabProps;
    parent: AccordionPassThroughMethodOptions;
    context: AccordionContext;
}

I think we just need to add parent in the TS def.

@vaelu
Copy link
Contributor Author

vaelu commented Apr 4, 2024

@melloware Probably, yes. TS definitions are written manually in PrimeReact, right?

@melloware
Copy link
Member

Yes they are written manually and then the documentation is all generated off the TS. SO the website updates itself on build from the TS

@nrueckmann
Copy link

As a workaround (until a fix has been released), you could manually type hint the parent. Example:

export const Tailwind: PrimeReactPTOptions = {
  calendar: {
    input: {
      root: (options: InputTextPassThroughMethodOptions & { parent: CalendarPassThroughMethodOptions }) => ({
        className: "foobar"
      })
    }
  }
}

gcko added a commit to gcko/primereact that referenced this issue Sep 25, 2024
- Update `InputTextPassThroughMethodOptions` to include `parent`
@gcko gcko mentioned this issue Sep 25, 2024
@gcko
Copy link
Contributor

gcko commented Sep 25, 2024

Please check my pr #7246 @vaelu 🙏

@vaelu
Copy link
Contributor Author

vaelu commented Sep 25, 2024

@gcko I don't work with PrimeReact currently since I left the company where we used it, so I think someone else should look at the PR, probably @melloware.

@melloware melloware assigned gcko and unassigned nitrogenous Sep 25, 2024
@melloware melloware added this to the 10.8.4 milestone Sep 25, 2024
melloware pushed a commit that referenced this issue Sep 25, 2024
- Update `InputTextPassThroughMethodOptions` to include `parent`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Unstyled Issue related to unstyled/passthrough attributes
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants