# All files / form OptGroup.tsx

86.04% Statements 74/86
100% Branches 0/0
0% Functions 0/1
86.04% Lines 74/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
    871x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x

    1x
     "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>
        );
      }
    );