TagsInput 10.17.4

ARIA
RTL

TagsInput is an extension of the text input fields. This component allows users to both enter text and capture input results and display them as well.

These selected text entries are being displayed as tags. Tags represent a set of interactive keywords that help organize and categorize objects.

Tags can be added by pressing the Enter ⏎ key or removed by the mouse click from the input element.

Anatomy

The component <TagsInput /> can have as direct child the component <TagsInput.SelectedItem /> to show the actual

<TagsInput ...>
    <TagsInput.SelectedItem ... />
    <TagsInput.SelectedItem ... />
    ...
</TagsInput>

Default

"use client";

import { TagsInput } from "@heathmont/moon-core-tw";
import { useCallback, useState } from "react";

const Default = () => {
  const [selected, setSelected] = useState<string[]>([]);

  const onEnter = useCallback(
    (value: string) => {
      setSelected([...selected, value]);
    },
    [selected, setSelected],
  );

  const onClear = useCallback(
    (index: number) => {
      setSelected(selected.filter((item: string, id: number) => id !== index));
    },
    [selected, setSelected],
  );

  return (
    <div className="w-full max-w-sm">
      <TagsInput selected={selected} onEnter={onEnter} onClear={onClear}>
        {selected.map((text, index) => (
          <TagsInput.SelectedItem key={index} index={index} label={text} />
        ))}
      </TagsInput>
    </div>
  );
};

export default Default;

    Different sizes

    TagsInput component can vary its sizes according to the size prop, there's 3 possible sizes: small (sm), medium (md) and large(lg).

    Small

    Medium (default)

    Large

    "use client";
    
    import { TagsInput } from "@heathmont/moon-core-tw";
    import type Size from "@heathmont/moon-core-tw/lib/tagsInput/private/types/Size";
    import { useCallback, useState } from "react";
    
    const TagsInputWithLogic = ({ size }: { size?: Size }) => {
      const [selected, setSelected] = useState<string[]>([]);
      const onEnter = useCallback(
        (value: string) => {
          setSelected([...selected, value]);
        },
        [selected, setSelected],
      );
      const onClear = useCallback(
        (index: number) => {
          setSelected(selected.filter((item: string, id: number) => id !== index));
        },
        [selected, setSelected],
      );
    
      return (
        <TagsInput
          selected={selected}
          onEnter={onEnter}
          onClear={onClear}
          size={size as Size}
          className="mb-4"
        >
          {selected.map((text, index) => (
            <TagsInput.SelectedItem key={index} index={index} label={text} />
          ))}
        </TagsInput>
      );
    };
    
    const DifferentSizes = () => (
      <div className="w-full max-w-sm">
        <p>Small</p>
        <TagsInputWithLogic size="sm" />
        <p>Medium (default)</p>
        <TagsInputWithLogic />
        <p>Large</p>
        <TagsInputWithLogic size="lg" />
      </div>
    );
    
    export default DifferentSizes;
    

      Different states

      <TagsInput /> Component can be in different state to visually provide the user some important notification. In this example using Hint component is possible to show some informative information.

      Preset data
      Preset data
      "use client";
      
      import { Hint, TagsInput } from "@heathmont/moon-core-tw";
      import { GenericInfo } from "@heathmont/moon-icons-tw";
      import { useCallback, useState } from "react";
      
      const Example = () => {
        const [selected1, setSelected1] = useState<string[]>(["Preset data"]);
        const [selected2, setSelected2] = useState<string[]>(["Preset data"]);
      
        const onEnter1 = useCallback(
          (value: string) => {
            setSelected1([...selected1, value]);
          },
          [selected1, setSelected1],
        );
      
        const onEnter2 = useCallback(
          (value: string) => {
            setSelected2([...selected2, value]);
          },
          [selected2, setSelected2],
        );
      
        const onClear1 = useCallback(
          (index: number) => {
            setSelected1(
              selected1.filter((item: string, id: number) => id !== index),
            );
          },
          [selected1, setSelected1],
        );
      
        const onClear2 = useCallback(
          (index: number) => {
            setSelected2(
              selected2.filter((item: string, id: number) => id !== index),
            );
          },
          [selected2, setSelected2],
        );
      
        return (
          <div className="flex flex-col items-center w-full h-50">
            <div className="flex flex-col items-center lg:flex-row lg:justify-center lg:items-start w-full gap-2">
              <div className="flex flex-col w-full max-w-sm lg:max-w-md">
                <TagsInput
                  selected={selected1}
                  label="Disabled"
                  disabled
                  onEnter={onEnter1}
                  onClear={onClear1}
                >
                  {selected1.map((text, index) => (
                    <TagsInput.SelectedItem key={index} index={index} label={text} />
                  ))}
                </TagsInput>
                <Hint disabled>Informative message holder</Hint>
              </div>
              <div className="flex flex-col w-full max-w-sm lg:max-w-md">
                <TagsInput
                  selected={selected2}
                  label={<span className="text-chichi">Error</span>}
                  isError
                  onEnter={onEnter2}
                  onClear={onClear2}
                >
                  {selected2.map((text, index) => (
                    <TagsInput.SelectedItem key={index} index={index} label={text} />
                  ))}
                </TagsInput>
                <Hint error>
                  <GenericInfo />
                  Informative message holder
                </Hint>
              </div>
            </div>
          </div>
        );
      };
      
      export default Example;
      

        Different Items casing

        Using the prop isUppercase of the <TagsInput.SelectedItem /> is possible change how the tag will show the text.

        Preset data
        Preset data
        "use client";
        
        import { TagsInput } from "@heathmont/moon-core-tw";
        import { useCallback, useState } from "react";
        
        const Example = () => {
          const [selected1, setSelected1] = useState<string[]>(["Preset data"]);
          const [selected2, setSelected2] = useState<string[]>(["Preset data"]);
        
          const onEnter1 = useCallback(
            (value: string) => {
              setSelected1([...selected1, value]);
            },
            [selected1, setSelected1],
          );
        
          const onEnter2 = useCallback(
            (value: string) => {
              setSelected2([...selected2, value]);
            },
            [selected2, setSelected2],
          );
        
          const onClear1 = useCallback(
            (index: number) => {
              setSelected1(selected1.filter((item, id) => id !== index));
            },
            [selected1, setSelected1],
          );
        
          const onClear2 = useCallback(
            (index: number) => {
              setSelected2(selected2.filter((item, id) => id !== index));
            },
            [selected2, setSelected2],
          );
        
          return (
            <div className="flex flex-col items-center w-full h-50">
              <div className="flex flex-col items-center lg:flex-row lg:justify-center lg:items-start w-full gap-2">
                <div className="flex flex-col w-full max-w-sm lg:max-w-md">
                  <TagsInput
                    selected={selected1}
                    label="Lower"
                    onEnter={onEnter1}
                    onClear={onClear1}
                  >
                    {selected1.map((text, index) => (
                      <TagsInput.SelectedItem
                        isUppercase={false}
                        index={index}
                        label={text}
                        key={index}
                      />
                    ))}
                  </TagsInput>
                </div>
                <div className="flex flex-col w-full max-w-sm lg:max-w-md">
                  <TagsInput
                    selected={selected2}
                    label="Uppercase (default)"
                    onEnter={onEnter2}
                    onClear={onClear2}
                  >
                    {selected2.map((text, index) => (
                      <TagsInput.SelectedItem key={index} index={index} label={text} />
                    ))}
                  </TagsInput>
                </div>
              </div>
            </div>
          );
        };
        
        export default Example;
        

          TagsInput

          These are props specific to the TagsInput component:

          Name
          Type
          Default
          selected*
          "string[]"-
          label
          string-
          size
          "sm" | "md" | "lg"md
          type
          text
          placeholder
          string-
          isError
          booleanfalse
          disabled
          booleanfalse
          className
          string-
          onEnter
          (value: string) => void-
          onClear
          (index: number) => void-

          Properties indicated with * are required.

          TagsInput.Selected

          These are props specific to the TagsInput.Selected component:

          Name
          Type
          Default
          className
          string-
          index*
          number-
          label*
          string-

          Properties indicated with * are required.