1.0.0 • Published 5 years ago

use-component v1.0.0

Weekly downloads
4
License
MIT
Repository
github
Last release
5 years ago

useComponent React hook

NPM Version NPM Downloads GitHub issues Telegram

Get the resulting component you want to wrap inside your target component by checking props, context or a fallback.

Installation

npm install use-component

or

yarn add use-component

Example

https://codesandbox.io/s/vm2zlr1qo3

Usage

useComponent

import { useComponent } from 'use-component'

Pass an entry of current component to the hook (this means that you need wrap your current component in an object and pass it to the entry option) as well as component from prop, a fallback, or an object of components and you will get a resulting component:

export const Input = ({
  children,
  component,
  ...fieldProps
}) => {
  const Component = useComponent({
    entry: { Input },
    component,
    fallback: 'input',
  });

  return (
    <Field {...fieldProps}>
      {({ input, meta, ...customProps }) => {
        return (
          <>
            {typeof Component === 'string' ? (
              <Component {...input} {...customProps} />
            ) : (
              <Component
                {...input}
                {...customProps}
                label={children}
                meta={meta}
                message={getErrorMessage(meta)}
              />
            )}
          </>
        );
      }}
    </Field>
  );
};

You can now pass any component as prop which will be used inside Input component. You can pass a styled component, for example, or any custom component, which will receive internal input, meta, label and message props.

<Input
  component={CustomInput}
  type="password"
  name="password"
  placeholder="Password"
/>

ComponentsContext

You can also create a context provider:

export const Form = ({
  children,
  onSubmit,
  component,
  components,
  ...otherProps
}) => {
  const Component = useComponent({
    entry: { Form },
    component,
    fallback: 'form',
    components,
  });

  const { handleSubmit } = useContext(FormContext);

  return (
    <ComponentsContext.Provider value={components}>
      <Component onSubmit={onSubmit || handleSubmit} {...otherProps}>
        {children}
      </Component>
    </ComponentsContext.Provider>
  );
};

And then just pass your components to it:

  <Form
    component={FormBox}
    components={{
      Input: StyledInput,
      ErrorMessage: ErrorBox,
    }}
  >
    <Heading>Login</Heading>
    <LoginFormBox>
      <FieldBox>
        <FieldLabelText>Email</FieldLabelText>
        <Input
          type="text"
          name="login"
          placeholder="E-mail"
        />
      </FieldBox>
      <FieldBox>
        <FieldLabelText>Password</FieldLabelText>
        <Input
          component={CustomInput}
          type="password"
          name="password"
          placeholder="Password"
        />
      </FieldBox>
      <StyledButton type="submit">Login</StyledButton>
    </LoginFormBox>
  </Form>

You can still use your original Input and ErrorMessage, but they will use your specified components under the hood passing some internal props to them.

Tip

If you found this hook useful, please star this package on GitHub

Author

@doasync