mui-tel-input

repository·master·Indexed 42 days ago

https://github.com/viclafouch/mui-tel-input

A phone number input component for the Material UI (MUI) React library, built with libphonenumber-js for robust parsing and formatting. Version 11.0.0 features include country and continent filtering, custom flag rendering, and a matchIsValidTel utility for phone number validation. It inherits all MUI TextField props and provides integration guides for Next.js and React Hook Form.

Tokens
9.3K
Snippets
35
Records
39
Agent score
52%

What's inside mui-tel-input

  1. Use ISO alpha-2 country codes for filtering and preferences

    master

    The MuiTelInput component uses two-letter ISO alpha-2 country codes (e.g., US) to manage country selection. You can use these codes with the following properties to customize the input behavior:

    • onlyCountries: A list of country codes that are the only ones allowed to be selected.
    • excludedCountries: A list of country codes that are forbidden from being selected.
    • preferredCountries: A list of country codes that should appear at the top of the selection list.

    The library supports all officially assigned ISO alpha-2 codes, plus a few additional ones such as AC (Ascension Island), TA (Tristan da Cunha), and XK (Kosovo).

    // Example usage of country code properties
    <MuiTelInput 
      onlyCountries={['US', 'CA']} 
      preferredCountries={['FR', 'GB']} 
      excludedCountries={['CN']} 
    />
  2. Deploy the website

    master

    You can deploy the website using different methods depending on your hosting setup:

    Using SSH: Set the USE_SSH environment variable to true.

    Using GitHub Pages (Non-SSH): Provide your GitHub username via the GIT_USER environment variable. This command builds the website and pushes it to the gh-pages branch.

    # Using SSH
    $ USE_SSH=true yarn deploy
    
    # Using GitHub Pages
    $ GIT_USER=<Your GitHub username> yarn deploy
  3. Use TypeScript with mui-tel-input

    master

    The mui-tel-input package is written in TypeScript and provides built-in type definitions. You can import these types directly to type your component props, state, and event handlers.

    Key exported types include:

    • MuiTelInputProps: The main interface for the component's props.
    • MuiTelInputInfo: The information object passed to the onChange handler.
    • MuiTelInputCountry: Represents a specific country.
    • MuiTelInputContinent: Represents a continent (e.g., 'EU').
    • MuiTelInputFlagElement: The type for the element returned by getFlagElement or used in unknownFlagElement.
    import React from 'react'
    import {
      MuiTelInput,
      type MuiTelInputProps,
      type MuiTelInputCountry,
      type MuiTelInputInfo,
      type MuiTelInputContinent,
      type MuiTelInputFlagElement,
      type MuiTelInputReason
    } from 'mui-tel-input'
    
    const MyComponent = () => {
      const [value, setValue] = React.useState<string>('')
    
      const handleChange = (newValue: string, info: MuiTelInputInfo) => {
        setValue(newValue)
      }
    
      const continents: MuiTelInputContinent[] = ['EU']
      const excludedCountries: MuiTelInputCountry[] = ['FR']
      // It's also the return value for the `getFlagElement` function prop
      const unknownFlag: MuiTelInputFlagElement = <img src=".." />
    
      return (
        <MuiTelInput
          value={value}
          onChange={handleChange}
          continents={continents}
          unknownFlagElement={unknownFlag}
          excludedCountries={excludedCountries}
        />
      )
    }
  4. Override MuiTelInput styles using className

    master

    You can override the component's styles by passing a custom class name via the className prop. To target specific internal elements, use the global class names or the exported classes object to ensure a stable interface.

    <MuiTelInput className="my-class-name" />
  5. Integrate mui-tel-input with Next.js

    master

    Because mui-tel-input is an ESM package, you must add it to the transpilePackages array in your next.config.mjs file to ensure it works correctly within a Next.js project.

    // next.config.mjs
    /** @type {import('next').NextConfig} */
    const nextConfig = {
      transpilePackages: ['mui-tel-input'],
      // your config,
    }
    
    export default nextConfig
  6. Integrate MuiTelInput with React Hook Form

    master

    To use MuiTelInput within a react-hook-form managed form, use the <Controller /> component. This allows you to bridge the component's internal state with the form's state.

    Key integration steps:

    1. Use the render prop of <Controller /> to access field properties.
    2. Map field.value to the value prop of MuiTelInput (ensure you handle null/undefined with value ?? '').
    3. Map field.ref to the inputRef prop of MuiTelInput to ensure proper focus management.
    4. Spread fieldProps onto MuiTelInput to pass onChange, onBlur, and name.
    5. Use fieldState.invalid to drive the error and helperText props of MuiTelInput for visual feedback.
    6. Implement validation using the rules prop in <Controller />. You can use matchIsValidTel from mui-tel-input within the validate function to enforce specific country constraints.
    import React from "react";
    import Button from "@mui/material/Button";
    import { MuiTelInput, matchIsValidTel } from "mui-tel-input";
    import { Controller, useForm } from "react-hook-form";
    
    const App = () => {
      const { control, handleSubmit } = useForm({
        defaultValues: {
          tel: ""
        }
      });
    
      const onSubmit = (data) => {
        alert(JSON.stringify(data));
      };
    
      return (
        <form onSubmit={handleSubmit(onSubmit)}>
          <Controller
            name="tel"
            control={control}
            rules={{ validate: (value) => matchIsValidTel(value, { onlyCountries: ['FR'] }) }}
            render={({ field: { ref: fieldRef, value, ...fieldProps }, fieldState }) => (
              <MuiTelInput
                {...fieldProps}
                value={value ?? ''}
                inputRef={fieldRef}
                onlyCountries={["FR"]}
                helperText={fieldState.invalid ? "Tel is invalid" : ""}
                error={fieldState.invalid}
              />
            )}
          />
         <div>
            <Button type="submit" variant="contained" sx={{ mt: 2 }}>
              Submit
            </Button>
          </div>
        </form>
      )
    }