TagGroup

PreviousNext
Docs
react-ariaui

Preview

Loading preview…
components/ui/TagGroup.tsx
'use client';
import {
  Button,
  Tag as AriaTag,
  TagGroup as AriaTagGroup,
  TagGroupProps as AriaTagGroupProps,
  TagList,
  TagListProps,
  TagProps,
} from 'react-aria-components';
import {Description, Label} from '@/registry/react-aria/ui/Form';
import {Text} from '@/registry/react-aria/ui/Content';
import {X} from 'lucide-react';
import './TagGroup.css';

export interface TagGroupProps<T>
  extends
    Omit<AriaTagGroupProps, 'children'>,
    Pick<TagListProps<T>, 'items' | 'children' | 'renderEmptyState'> {
  label?: string;
  description?: string;
  errorMessage?: string;
}

export function TagGroup<T extends object>(
  {
    label,
    description,
    errorMessage,
    items,
    children,
    renderEmptyState,
    ...props
  }: TagGroupProps<T>
) {
  return (
    (
      <AriaTagGroup {...props}>
        {label && <Label>{label}</Label>}
        <TagList items={items} renderEmptyState={renderEmptyState}>
          {children}
        </TagList>
        {description && <Description>{description}</Description>}
        {errorMessage && <Text slot="errorMessage">{errorMessage}</Text>}
      </AriaTagGroup>
    )
  );
}

export function Tag(
  { children, ...props }: Omit<TagProps, 'children'> & {
    children?: React.ReactNode;
  }
) {
  let textValue = typeof children === 'string' ? children : undefined;
  return (
    (
      <AriaTag textValue={textValue} {...props} className="react-aria-Tag button-base">
        {({ allowsRemoving }) => (
          <>
            {children}
            {allowsRemoving && <Button slot="remove" className="remove-button"><X /></Button>}
          </>
        )}
      </AriaTag>
    )
  );
}

Installation

npx shadcn@latest add @react-aria/css-taggroup

Usage

import { CssTaggroup } from "@/components/ui/css-taggroup"
<CssTaggroup />