How to define props on components made in Plasmic?

Hi all
I would like to ask you a question again.:sob:

I want to set up an event for a component within a component, but I get a build error in TypeScript.

One idea I had was to convert addStock to Slot and set <AddStock onClick~~~~~ /> in the page.

However, I feel it would be inefficient to go through the trouble of generating it.

Is there any better way to access the subcomponents?

iOS の画像.jpg

What’s the Typescript error?

if addStock is an instance of AddStock, you should make sure to also add onClick to props of AddStock in AddStock.tsx

@robust_koi
Sorry, I forgot to add this error message.

Type '{ onClick: (e: React.MouseEvent<HTMLButtonElement>) => void; }' is not assignable to type 'ForwardRefExoticComponent<AddStockProps & RefAttributes<HTMLButtonElement>>'.
  Object literal may only specify known properties, and 'onClick' does not exist in type 'ForwardRefExoticComponent<AddStockProps & RefAttributes<HTMLButtonElement>>'.ts(2322)

@chungwu
yes, I already added onClick props in AddStock
and addStockProps in sideBarDocsArea

Very new to Plasmic, but I think you want AddStockProps as the type instead of typeof AddStock

@robust_koi
Thank you for your reply.

I feel that typeof AddStock is correct because I want to access the AddStock component contained in the SideBarDocsArea component.

Because,
AddStockProps can be accessed through AddStock, right?

It’s my understanding that what we pass through the Plasmic components are essentially “prop overrides”. So the prop type is what would be expected. (What I suggested worked in my local project, but your situation might be different.) Try it out?

I see.
I tried that, but it didn’t change the situation in my project.

Do you “Convert to a slot target” in Plasmic on that object?

As a test, I converted all the components I wanted to manipulate to Slot, and the Typescript error went away.

Even if I did not convert them to Slots, they were still behaving correctly.
The build error happens, but if I just run it, it works as expected:face_vomiting:

image.png

@chungwu I have a general question regarding the types. If AddStock component’s root element is button, shouldn’t it inherit the types automatically in the DefaultProps created within the Wrapper component?

I thought that was only true when overriding root props via the Headless API, but with Codegen it sort of “seals it off” to only the props you specify in the wrapping component. Also curious on the official answer.

@chungwu
If I build with atomic design, I will inevitably have to nest components, so I would like to know how to access child and grandchild components.

@zonal_mammal for codegen, the default props for the wrapper components are “conservative” - only the component variants and slots, plus className/style. The intention here with codegen is that you should be deliberate in curating your component props, since the wrapper components are meant to be reusable, “normal” components that you can use elsewhere in your codebase as well.

@dirty_eel In your example - it helps to approach this as “how would I structure the components if I were writing them by hand myself?” If something should happen when the user clicks on the add stock button, which component should control what happens?
• should AddStockButton itself control what happens? If you’ll just be interacting with some global context, then this may make sense; if so, you should add the onClick there and won’t have to modify any props (<PlasmicAddStockButton onClick=...)
• should SideBarDocsArea control what happens? If so, you should add an onClick prop to AddStockButton, which SideBarDocsArea can supply (<PlasmicSidebarDocsArea addStock={{onClick: ...}})
• should the root Homepage control what happens? If so, then you should add an onAddStockButtonClick prop to SideBarDocsArea, then an onClick prop to AddStockButton. Homepage calls <PlasmicHomepage sidebarDocs={{ onAddStockButtonClick: ...}} and SidebarDocsArea calls <PlasmicSidebarDocsArea addStock={{onClick: props.onAddStockButtonClick}}, etc.
So in short, the mindset with codegen is that you should think about the props for these components the same way as if you were writing them by hand; considerations on where state and logic lives should be the same. Plasmic just helps you with the rendering part.

@chungwu
I see.
But what does this mean?

Typescript is making a Type error as shown in this image.
But at the top, at the top, the error does not occur.
This is because onClick has already been added to AddStock.tsx.

The onClick event still works correctly for both buttons in this state.
In other words, I am able to access the descendants, as in sideBarDocArea : addStock : onClick.
(although there is a Build issue with Typescript).

image.png

is addStock a prop of SidebarDocsArea?

oh I see, you tried to add it above; you should make it addStock?: React.ComponentProps<typeof AddStock>

@chungwu
oh wow! It was correct!!!
Thank you sooo much!

I was creating a test project to try out different cases and this solved the problem.
Now I can switch our team’s design workflow from Figma to Plasmic.
So happy!!!