# All files / src/form OptGroup.tsx

0% Statements 0/86
0% Branches 0/1
0% Functions 0/1
0% Lines 0/86

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87

     "use client";
    import { forwardRef, type ReactNode } from "react";
    import { type ListElement, type ListProps } from "../list/List.js";
    import {
      ListSubheader,
      type ListSubheaderProps,
    } from "../list/ListSubheader.js";
    import { MenuItemGroup } from "../menu/MenuItemGroup.js";
    import { type PropsWithRef } from "../types.js";
    import { useEnsuredId } from "../useEnsuredId.js";

    /** @remarks \@since 6.0.0 */
    export interface OptGroupProps extends Omit<ListProps, "role"> {
      /**
       * This is really the `children` to display in a `ListSubheader` that
       * describes the optgroup. It was named `label` to match the native
       * `<optgroup>` element.
       *
       * @see {@link labelProps} for additional styling and options.
       */
      label: ReactNode;

      /**
       * This can be used to apply any additional props to the `ListSubheader` that
       * describes the group of options.
       */
      labelProps?: PropsWithRef<
        Omit<ListSubheaderProps, "role" | "children">,
        HTMLLIElement
      >;

      /**
       * This should be any `Option`s to display within the group.
       */
      children: ReactNode;
    }

    /**
     * **Client Component**
     *
     * This component is more of a "convenience component" to help enforce the
     * correct accessibility when creating an `<optgroup>` with the `Select`
     * component.
     *
     * @example
     * Simple Example
     * ```tsx
     * import { Select, OptGroup, Option } from "@react-md/core";
     * import FavoriteIcon from "@react-md/material-icons/FavoriteIcon";
     * import type { ReactElement } from "react";
     *
     * function Example(): ReactElement {
     *   return (
     *     <Select label="Choose an animal">
     *       <OptGroup label="Land" labelProps={{ className: "custom-class-name" }}>
     *         <Option value={0}>Cat</Option>
     *         <Option value={1}>Dog</Option>
     *         <Option value={2}>Tiger</Option>
     *       </OptGroup>
     *       <OptGroup label="Water" labelProps={{ rightAddon: <FavoriteIcon /> }}>
     *         <Option value={3}>Dolphin</Option>
     *         <Option value={4}>Flounder</Option>
     *       </OptGroup>
     *     </Select>
     *
     *   );
     * }
     * ```
     *
     * @remarks \@since 6.0.0
     */
    export const OptGroup = forwardRef<ListElement, OptGroupProps>(
      function OptGroup(props, ref) {
        const { children, label, labelProps, ...remaining } = props;
        const labelId = useEnsuredId(labelProps?.id, "optgroup");

        return (
          <MenuItemGroup aria-labelledby={labelId} {...remaining} ref={ref}>
            <ListSubheader {...labelProps} id={labelId}>
              {label}
            </ListSubheader>
            {children}
          </MenuItemGroup>
        );
      }
    );