Secure way to create a form that takes username/password?

Hi plasmic team, I am wondering what is a secure way to create a form that takes the username and password from inputs in plasmic? @parliamentary_trout

For forms, you will need to wrap the PlasmicComponent, passing in props to properly handle the username and password input elements.
https://docs.plasmic.app/learn/code-component-substitution/

For example in your initialization file:

PLASMIC.substituteComponent(MyForm, "Form")

Then you can create a MyForm component that properly handles the inputs:

function MyForm() {
  const [username, setUsername] = React.useState("");
  return (
    <PlasmicRootProvider loader={PLASMIC}>
      <PlasmicComponent
        component="Form"
        componentProps={{
          username: {
            value: username,
            onChange: (e) => setUsername(e.target.value),
          }
        }}
      />
    </PlasmicRootProvider>
  );
}

Ok thanks! We are using codegen with nextjs and typescript and I was wondering if I could just wrap the plasmic component that has inputs for username/password in a form?

Something like
return (

username={{ props:{ id: "username" } }} password={{ props:{ id: "password" } }} );

Oh its even easier in codegen, you already have a wrapper component that we generate for you automatically. (Form.tsx). This is where you’d add the props.

function Form() {
  const [username, setUsername] = React.useState("");
  return (
      <PlasmicForm
        username={{
          value: username,
          onChange: (e) => setUsername(e.target.value),
        }}
      />
  );
}

That makes sense for the username but I am not sure I want to store password in a state but I want to send the form data directly to the server. Is there a way to do this?

// const {
// register,
// formState: { errors },
// handleSubmit,
// } = useForm();
return <PlasmicForm
root={{
wrap: (content) => content
}}
/>

I see in the api explorer in plasmic that I can wrap the root of the component. Would wrapping this in a form be redundant?

I think I would do the same for the password. The state is local to the client, so the security surface is the same as other solutions

Ok thanks!

Hi Raymond, I am trying to override the onClick function for a component where the root is a button and am having some trouble. Here is what I have, where submit is a component with button as root

submit={{
              props: {
                onClick: (e) => submit()
              }
}}

// I can also access the onClick from in the submit component itself using this

<PlasmicButton onClick={(e) => null} />

can you share more detail what problem you’re experiencing? The onclick handler isn’t triggering?

what is submit? is that a button? have you wired the wrapper component to accept an onClick prop?

Yes the onClick is not triggering,
here is the submit button wrapper

interface ButtonProps extends DefaultButtonProps {
  onClick?: React.MouseEventHandler,
}
function Button_(props: ButtonProps, ref: HTMLElementRefOf<"div">) {
  return <PlasmicButton 
  onClick={(e) => props.onClick}
  />;
}
const Button = React.forwardRef(Button_);
export default Button;

Here is the wrapper where the form is located

<PlasmicDashboardProfile 
   //form inputs here
              submit= {{
                props:{
                  onClick: (e) => (
                    resetPassword(),
                  console.log(error)
                  ),
                }
              }}
        />

I want to have the styling of this button used many times then override the onClick for the button in different places. Is this the best way to accomplish that?

Ok I added {…props} to the button wrapper and it works. Thanks for your help!