> ## Documentation Index
> Fetch the complete documentation index at: https://anvil.servicetitan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Select Trigger – Design

> Select Trigger provides a means of displaying selection without using a Popover.

export const LiveCode = ({children, customHeight, clickToLoad, example, fullWidth, fullHeight, hideCodeInLiveCode, screenshot, screenshotOnly, showCode: showCodeProp}) => {
  const SCREENSHOTS_BASE = "https://servicetitan.github.io/anvil2-docs-live-code/screenshots";
  const STACKBLITZ_BASE = "https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples";
  const [showCodeBlock, setShowCodeBlock] = useState(showCodeProp ?? false);
  const [isLocalOverride, setIsLocalOverride] = useState(false);
  useEffect(() => {
    const examplePath = `/images/live-code-screenshots-tmp/${example}.png`;
    fetch(examplePath, {
      method: "HEAD"
    }).then(r => {
      if (r.ok) setIsLocalOverride(true);
    }).catch(() => {});
  }, [example]);
  const screenshotBase = isLocalOverride ? "/images/live-code-screenshots-tmp" : SCREENSHOTS_BASE;
  if (screenshotOnly) {
    return <Frame className="flex flex-col">
        <div className="flex dark:hidden" style={{
      justifyContent: "center",
      alignItems: "center",
      width: fullWidth ? "100%" : "50%",
      minHeight: fullHeight ? "284px" : undefined,
      background: "#FFFFFF"
    }}>
          <img srcset={`${screenshotBase}/${example}.png, ${screenshotBase}/${example}-2x.png 2x`} src={`${screenshotBase}/${example}.png`} alt={example} noZoom />
        </div>
        <div className="hidden dark:flex" style={{
      justifyContent: "center",
      alignItems: "center",
      width: fullWidth ? "100%" : "50%",
      minHeight: fullHeight ? "284px" : undefined,
      background: "#141414"
    }}>
          <img srcset={`${screenshotBase}/${example}-dark.png, ${screenshotBase}/${example}-dark-2x.png 2x`} src={`${screenshotBase}/${example}-dark.png`} alt={example} noZoom />
        </div>
      </Frame>;
  }
  if (screenshot) {
    return <Frame className="flex flex-col -mb-2">
        <div className="flex dark:hidden bg-white dark:bg-codeblock border border-gray-950/10 dark:border-white/10 dark:twoslash-dark rounded-2xl overflow-hidden" style={{
      justifyContent: "center",
      alignItems: "center",
      width: fullWidth ? "100%" : "50%",
      minHeight: fullHeight ? "284px" : undefined
    }}>
          <img srcset={`${screenshotBase}/${example}.png, ${screenshotBase}/${example}-2x.png 2x`} src={`${screenshotBase}/${example}.png`} alt={example} noZoom />
        </div>

        <div className="hidden dark:flex bg-white dark:bg-codeblock border border-gray-950/10 dark:border-white/10 dark:twoslash-dark rounded-2xl overflow-hidden" style={{
      background: "#141414",
      justifyContent: "center",
      alignItems: "center",
      width: fullWidth ? "100%" : "50%",
      minHeight: fullHeight ? "284px" : undefined
    }}>
          <img srcset={`${screenshotBase}/${example}-dark.png, ${screenshotBase}/${example}-dark-2x.png 2x`} src={`${screenshotBase}/${example}-dark.png`} alt={example} noZoom />
        </div>

        <div className="flex justify-end items-center text-xs py-2 px-1 gap-4">
          {!showCodeProp ? <button className="inline-flex justify-end items-center text-gray-700 dark:text-gray-50 hover:text-blue-500 dark:hover:text-blue-300 transition-colors group self-end gap-1 cursor-pointer" onClick={() => setShowCodeBlock(!showCodeBlock)} style={{
      appearance: "none"
    }}>
              <Icon icon="code" size="12px" className="group-hover:bg-blue-500 dark:group-hover:bg-blue-300" />
              <span>{showCodeBlock ? "Hide code" : "Show code"}</span>
            </button> : null}

          <a className="inline-flex justify-end items-center hover:text-blue-500 dark:hover:text-blue-300 transition-colors group self-end gap-1" href={`${STACKBLITZ_BASE}/${example}?file=src/App.tsx`} target="_blank" rel="noreferrer">
            <Icon icon="bolt" size="12px" className="group-hover:bg-blue-500 dark:group-hover:bg-blue-300" />
            <span>StackBlitz demo</span>
          </a>
        </div>

        <div className="grid transition-[grid-template-rows] duration-300 ease-in-out overflow-auto overflow-y-hidden overflow-x-auto" style={showCodeBlock ? {
      gridTemplateRows: "1fr"
    } : {
      gridTemplateRows: "0fr"
    }}>
          <div style={{
      minHeight: 0,
      overflowX: "auto",
      overflowY: "hidden",
      marginBlockStart: "-1.25rem",
      marginBlockEnd: "-1.5rem"
    }}>
            {children}
          </div>
        </div>
      </Frame>;
  } else {
    return <div style={{
      display: "flex",
      width: fullWidth ? "100%" : "50%",
      minHeight: customHeight ? customHeight : "316px",
      resize: "vertical",
      overflow: "auto"
    }}>
        <iframe title={example} style={{
      flex: 1,
      width: fullWidth ? "100%" : "50%",
      minHeight: customHeight ? customHeight : "316px"
    }} src={`${STACKBLITZ_BASE}/${example}?embed=1&hideNavigation=1&hideExplorer=1&terminalHeight=0&file=src/App.tsx${clickToLoad ? "&ctl=1" : ""}${hideCodeInLiveCode ? "&view=preview" : ""}`} allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts" />
      </div>;
  }
};

export const CodePreviewPlaceholder = ({double, fullWidth}) => {
  const single = <div style={{
    width: fullWidth ? "100%" : "50%",
    borderRadius: "1rem",
    display: "flex",
    padding: "1rem",
    flexDirection: "column",
    gap: "0.5rem",
    height: "10rem",
    marginBlockEnd: "1rem"
  }} className="border-width-default border-color-subdued">
      <div className="bg-strong border-radius-large" style={{
    width: "100%",
    flexGrow: "1"
  }} />
      <div className="bg-strong border-radius-large" style={{
    width: "100%",
    flexGrow: "1"
  }} />
    </div>;
  return double ? <div style={{
    display: "flex",
    gap: "1rem"
  }}>
      {single}
      {single}
    </div> : single;
};

<LiveCode example="selecttrigger-dialog-apply" customHeight="500px" fullWidth>
  ```tsx lines theme={null}
  import {
    SelectTrigger,
    Flex,
    Dialog,
    Grid,
    SearchField,
    ListView,
    Text,
    Button,
  } from "@servicetitan/anvil2";
  import { useState } from "react";

  type Item = {
    id: number;
    name: string;
  };

  const items = [
    { id: 1, name: "First item" },
    { id: 2, name: "Second item" },
    { id: 3, name: "Third item" },
    { id: 4, name: "Fourth item" },
    { id: 5, name: "Fifth item" },
  ];

  function App() {
    const [selectedItems, setSelectedItems] = useState<Item[] | null>([
      items[2],
      items[3],
    ]);
    const [dialogSelectedItems, setDialogSelectedItems] = useState<Item[]>([
      items[2],
      items[3],
    ]);
    const [openDialog, setOpenDialog] = useState(true);

    const handleDialogClose = () => setOpenDialog(false);

    const handleCancelClick = () => setDialogSelectedItems(selectedItems ?? []);

    const handleApplyClick = () => {
      setOpenDialog(false);
      setSelectedItems(dialogSelectedItems);
    };

    const handleSelectionChange = (selectedLabels: string[]) => {
      const selectedItems = items.filter((item) =>
        selectedLabels.includes(item.name),
      );
      setDialogSelectedItems(selectedItems);
    };

    const selectedLabels = dialogSelectedItems.map((item) => item.name);

    return (
      <div style={{ minHeight: "443px", minWidth: "455px" }}>
        <div style={{ padding: "1.5rem" }}>
          <Flex direction="column" gap="6">
            <SelectTrigger
              multiple
              selectedItems={selectedItems ?? []}
              itemToString={(item) => (item ? item.name : "")}
              onChange={(items: Item[] | null) => setSelectedItems(items)}
              onClick={() => {
                setDialogSelectedItems(selectedItems ?? []);
                setOpenDialog(true);
              }}
              label="Label"
              placeholder="Placeholder"
              hint="Hint text"
              moreInfo="More info"
              size="large"
              required
            />
          </Flex>

          <Dialog open={openDialog} onClose={handleDialogClose}>
            <Dialog.Header>Dialog Header</Dialog.Header>

            <Dialog.Content>
              <Grid flexGrow="1" gap="4">
                <SearchField style={{ gap: 0 }} />
                <ListView
                  onSelectionChange={handleSelectionChange}
                  selected={selectedLabels}
                >
                  {items.map((item) => (
                    <ListView.Option key={item.id} label={item.name}>
                      <Text>{item.name}</Text>
                    </ListView.Option>
                  ))}
                </ListView>
              </Grid>
            </Dialog.Content>

            <Dialog.Footer>
              <Flex gap="3" justifyContent="flex-end">
                <Dialog.CancelButton onClick={handleCancelClick}>
                  Cancel
                </Dialog.CancelButton>
                <Button appearance="primary" onClick={handleApplyClick}>
                  Apply
                </Button>
              </Flex>
            </Dialog.Footer>
          </Dialog>
        </div>
      </div>
    );
  }

  export default App;
  ```
</LiveCode>

## Anatomy

Select Trigger consists of two primary elements that work together to display and manage selections.

<Frame>
  <div className="w-full h-full bg-[#FFFFFF] p-2 rounded flex items-center justify-center">
    <img
      src="https://mintcdn.com/servicetitan/MMRqs3hy702UF0GS/images/docs/web/components/select-trigger/anatomy.png?fit=max&auto=format&n=MMRqs3hy702UF0GS&q=85&s=2bd364ce099a1715d0e35bead8497481"
      alt="Anatomy of a
Select Trigger"
      width="726"
      height="140"
      data-path="images/docs/web/components/select-trigger/anatomy.png"
    />
  </div>
</Frame>

1. **Trigger** - Identifies the field and its purpose
2. **Clear button** (Optional) - Removes all selections when clicked

## Options

Select Trigger supports the following configurations to accommodate various selection scenarios.

### Single and multiple selection

<LiveCode example="selecttrigger-playground" screenshot fullWidth>
  ```tsx lines theme={null}
  import {
    SelectTrigger,
    Flex,
    Dialog,
    Checkbox,
    Button,
    type CheckboxProps,
  } from "@servicetitan/anvil2";
  import { useState } from "react";

  type Item = {
    id: number;
    name: string;
  };

  const items = [
    { id: 1, name: "First item" },
    { id: 2, name: "Second item" },
    { id: 3, name: "Third item" },
    { id: 4, name: "Fourth item" },
    { id: 5, name: "Fifth item" },
  ];

  function App() {
    const [selectedItems, setSelectedItems] = useState<Item[] | null>([
      items[2],
      items[3],
    ]);
    const [dialogSelectedItems, setDialogSelectedItems] = useState<Item[]>([
      items[2],
      items[3],
    ]);
    const [openDialog, setOpenDialog] = useState(false);

    const handleDialogClose = () => setOpenDialog(false);

    const handleCancelClick = () => setDialogSelectedItems(selectedItems ?? []);

    const handleApplyClick = () => {
      setOpenDialog(false);
      setSelectedItems(dialogSelectedItems);
    };

    const handleCheckboxClick: CheckboxProps["onClick"] = (e, state) => {
      if (e && state) {
        const { checked } = state;

        if (checked) {
          setDialogSelectedItems((prevItems) =>
            prevItems.filter(
              (item) => item.name !== (e.target as HTMLInputElement).value,
            ),
          );
        } else {
          const selectedItem = items.find(
            (item) => item.name === (e.target as HTMLInputElement).value,
          );

          if (selectedItem) {
            setDialogSelectedItems((prevItems) => [...prevItems, selectedItem]);
          }
        }
      }
    };

    return (
      <div style={{ minHeight: "284px" }}>
        <div style={{ padding: "1.5rem" }}>
          <Flex direction="column" gap="6">
            <SelectTrigger
              multiple
              selectedItems={selectedItems ?? []}
              itemToString={(item) => (item ? item.name : "")}
              onChange={(items: Item[] | null) => setSelectedItems(items)}
              onClick={() => {
                setDialogSelectedItems(selectedItems ?? []);
                setOpenDialog(true);
              }}
              label="Label"
              placeholder="Placeholder"
              hint="Hint text"
              moreInfo="More info"
              size="large"
              required
            />
          </Flex>

          <Dialog open={openDialog} onClose={handleDialogClose}>
            <Dialog.Header>Dialog Header</Dialog.Header>

            <Dialog.Content>
              <Checkbox.Group legend="Choose item(s)" required>
                {items.map((item) => (
                  <Checkbox
                    key={item.name}
                    label={item.name}
                    value={item.name}
                    checked={dialogSelectedItems.includes(item)}
                    onClick={handleCheckboxClick}
                  />
                ))}
              </Checkbox.Group>
            </Dialog.Content>

            <Dialog.Footer>
              <Flex gap="3" justifyContent="flex-end">
                <Dialog.CancelButton onClick={handleCancelClick}>
                  Cancel
                </Dialog.CancelButton>
                <Button appearance="primary" onClick={handleApplyClick}>
                  Apply
                </Button>
              </Flex>
            </Dialog.Footer>
          </Dialog>
        </div>
      </div>
    );
  }

  export default App;
  ```
</LiveCode>

Select Trigger supports both single and multiple selection modes. In single selection mode, the component displays the selected item as text. In multiple selection mode, selected items appear as Chips that users can remove individually.

### Opening of custom overlays

Clicking the Select Trigger's input area opens up a custom overlay element. This is typically a [Dialog](/docs/web/components/dialog/design). This is not explicitly part of the Select Trigger, an implementor will need to customize what content is in the overlay component.

### Field properties

Field properties follow the same options as the [Combobox](/docs/web/components/combobox/design). This includes, but not limited to, field sizes, prefixes, suffixes, Chip color customization, and max rows.

## Behavior

Select Trigger responds to user interaction with distinct visual feedback while maintaining consistent interaction patterns.

### Selection display

Selected items appear as Chips in multiple selection mode. Each Chip includes a close button that removes that specific item. The component displays a placeholder when no items are selected.

### Clear selection

A clear button appears when items are selected, allowing users to remove all selections at once. The clear button is hidden when the component is disabled or read-only, or when `disableClearSelection` is set to true.

## Usage Guidelines

Use Select Trigger when you need to display selections in a field-like component without using a Popover, especially for complex selection scenarios that require Dialog interfaces.

### When to Use

Use Select Trigger when you need:

* Complex selection interfaces that require Dialog components
* Selection scenarios with secondary actions, tabs, or multiple steps
* Selection interfaces that need more space than a Popover provides
* Integration with components like ListView, CheckboxGroup, or custom selection UIs

### When not to use

Avoid using Select Trigger when:

* **Simple selection needs** - Use [Combobox](/docs/web/components/combobox/design) for basic single or multiple selection with a Popover
* **Dropdown or Popover selection** - Use [Combobox](/docs/web/components/combobox/design) instead.
* **No selection interface needed** - Use TextField if you don't need a selection interface

### Alternatives

#### Select Trigger vs Combobox

Combobox provides a complete selection interface with a Popover, including search and filtering capabilities. Use Combobox for standard selection scenarios. Use Select Trigger when you need a Dialog for complex selection interfaces with tabs, secondary actions, or custom layouts.

#### Select Trigger vs Select Field

[Select Field](/docs/web/components/select-field/design) displays options in a built-in Popover or Dialog with integrated search and filtering. Select Trigger opens a custom overlay — typically a Dialog — that the implementor fully controls.

### How to Use

#### Basic multiple selection

Use Select Trigger with a Dialog containing a ListView or CheckboxGroup for selection. Maintain separate state for the Select Trigger's selected items and the Dialog's temporary selection state.

<LiveCode example="selecttrigger-dialog-apply" screenshot fullWidth>
  ```tsx lines theme={null}
  import {
    SelectTrigger,
    Flex,
    Dialog,
    Grid,
    SearchField,
    ListView,
    Text,
    Button,
  } from "@servicetitan/anvil2";
  import { useState } from "react";

  type Item = {
    id: number;
    name: string;
  };

  const items = [
    { id: 1, name: "First item" },
    { id: 2, name: "Second item" },
    { id: 3, name: "Third item" },
    { id: 4, name: "Fourth item" },
    { id: 5, name: "Fifth item" },
  ];

  function App() {
    const [selectedItems, setSelectedItems] = useState<Item[] | null>([
      items[2],
      items[3],
    ]);
    const [dialogSelectedItems, setDialogSelectedItems] = useState<Item[]>([
      items[2],
      items[3],
    ]);
    const [openDialog, setOpenDialog] = useState(true);

    const handleDialogClose = () => setOpenDialog(false);

    const handleCancelClick = () => setDialogSelectedItems(selectedItems ?? []);

    const handleApplyClick = () => {
      setOpenDialog(false);
      setSelectedItems(dialogSelectedItems);
    };

    const handleSelectionChange = (selectedLabels: string[]) => {
      const selectedItems = items.filter((item) =>
        selectedLabels.includes(item.name),
      );
      setDialogSelectedItems(selectedItems);
    };

    const selectedLabels = dialogSelectedItems.map((item) => item.name);

    return (
      <div style={{ minHeight: "443px", minWidth: "455px" }}>
        <div style={{ padding: "1.5rem" }}>
          <Flex direction="column" gap="6">
            <SelectTrigger
              multiple
              selectedItems={selectedItems ?? []}
              itemToString={(item) => (item ? item.name : "")}
              onChange={(items: Item[] | null) => setSelectedItems(items)}
              onClick={() => {
                setDialogSelectedItems(selectedItems ?? []);
                setOpenDialog(true);
              }}
              label="Label"
              placeholder="Placeholder"
              hint="Hint text"
              moreInfo="More info"
              size="large"
              required
            />
          </Flex>

          <Dialog open={openDialog} onClose={handleDialogClose}>
            <Dialog.Header>Dialog Header</Dialog.Header>

            <Dialog.Content>
              <Grid flexGrow="1" gap="4">
                <SearchField style={{ gap: 0 }} />
                <ListView
                  onSelectionChange={handleSelectionChange}
                  selected={selectedLabels}
                >
                  {items.map((item) => (
                    <ListView.Option key={item.id} label={item.name}>
                      <Text>{item.name}</Text>
                    </ListView.Option>
                  ))}
                </ListView>
              </Grid>
            </Dialog.Content>

            <Dialog.Footer>
              <Flex gap="3" justifyContent="flex-end">
                <Dialog.CancelButton onClick={handleCancelClick}>
                  Cancel
                </Dialog.CancelButton>
                <Button appearance="primary" onClick={handleApplyClick}>
                  Apply
                </Button>
              </Flex>
            </Dialog.Footer>
          </Dialog>
        </div>
      </div>
    );
  }

  export default App;
  ```
</LiveCode>

Use Select Trigger with Dialog for complex selection scenarios that require more space and flexibility than a Popover.

#### Selection with secondary actions

Use Select Trigger with Dialog when selection items need secondary actions like editing or additional information.

<LiveCode example="selecttrigger-dialog-secondary" screenshot fullWidth>
  ```tsx lines theme={null}
  import {
    SelectTrigger,
    Flex,
    Dialog,
    Grid,
    SearchField,
    ListView,
    Text,
    Tooltip,
    Button,
  } from "@servicetitan/anvil2";
  import Edit from "@servicetitan/anvil2/assets/icons/material/round/edit.svg";
  import { useState } from "react";

  type Item = {
    id: number;
    name: string;
  };

  const items = [
    { id: 1, name: "First item" },
    { id: 2, name: "Second item" },
    { id: 3, name: "Third item" },
    { id: 4, name: "Fourth item" },
    { id: 5, name: "Fifth item" },
  ];

  function App() {
    const [selectedItems, setSelectedItems] = useState<Item[] | null>([
      items[2],
      items[3],
    ]);
    const [dialogSelectedItems, setDialogSelectedItems] = useState<Item[]>([
      items[2],
      items[3],
    ]);
    const [openDialog, setOpenDialog] = useState(true);

    const handleDialogClose = () => setOpenDialog(false);

    const handleCancelClick = () => setDialogSelectedItems(selectedItems ?? []);

    const handleApplyClick = () => {
      setOpenDialog(false);
      setSelectedItems(dialogSelectedItems);
    };

    const handleSelectionChange = (selectedLabels: string[]) => {
      const selectedItems = items.filter((item) =>
        selectedLabels.includes(item.name),
      );
      setDialogSelectedItems(selectedItems);
    };

    const selectedLabels = dialogSelectedItems.map((item) => item.name);

    return (
      <div style={{ minHeight: "497px", minWidth: "455px" }}>
        <div style={{ padding: "1.5rem" }}>
          <Flex direction="column" gap="6">
            <SelectTrigger
              multiple
              selectedItems={selectedItems ?? []}
              itemToString={(item) => (item ? item.name : "")}
              onChange={(items: Item[] | null) => setSelectedItems(items)}
              onClick={() => {
                setDialogSelectedItems(selectedItems ?? []);
                setOpenDialog(true);
              }}
              label="Label"
              placeholder="Placeholder"
              hint="Hint text"
              moreInfo="More info"
              size="large"
              required
            />
          </Flex>

          <Dialog open={openDialog} onClose={handleDialogClose}>
            <Dialog.Header>Dialog Header</Dialog.Header>

            <Dialog.Content>
              <Grid flexGrow="1" gap="4">
                <SearchField style={{ gap: 0 }} />
                <ListView
                  onSelectionChange={handleSelectionChange}
                  selected={selectedLabels}
                >
                  {items.map((item) => (
                    <ListView.Option key={item.id} label={item.name}>
                      <Text flexGrow={1}>{item.name}</Text>
                      <Tooltip placement="top-end">
                        <Tooltip.Content>Edit Item</Tooltip.Content>
                        <Tooltip.Trigger>
                          <Button size="small" icon={Edit} />
                        </Tooltip.Trigger>
                      </Tooltip>
                    </ListView.Option>
                  ))}
                </ListView>
              </Grid>
            </Dialog.Content>

            <Dialog.Footer>
              <Flex gap="3" justifyContent="flex-end">
                <Dialog.CancelButton onClick={handleCancelClick}>
                  Cancel
                </Dialog.CancelButton>
                <Button appearance="primary" onClick={handleApplyClick}>
                  Apply
                </Button>
              </Flex>
            </Dialog.Footer>
          </Dialog>
        </div>
      </div>
    );
  }

  export default App;
  ```
</LiveCode>

Use Select Trigger with Dialog when selected items require secondary actions or additional context.

#### Tabbed selection interface

Use Select Trigger with Dialog containing Tabs to organize selection options, such as showing all items in one tab and selected items in another.

<LiveCode example="selecttrigger-dialog-tab" screenshot fullWidth>
  ```tsx lines theme={null}
  import {
    SelectTrigger,
    Flex,
    Dialog,
    Grid,
    SearchField,
    Tab,
    ListView,
    Text,
    Button,
  } from "@servicetitan/anvil2";
  import { useState } from "react";

  type Item = {
    id: number;
    name: string;
  };

  const items = [
    { id: 1, name: "First item" },
    { id: 2, name: "Second item" },
    { id: 3, name: "Third item" },
    { id: 4, name: "Fourth item" },
    { id: 5, name: "Fifth item" },
  ];

  function App() {
    const [selectedItems, setSelectedItems] = useState<Item[] | null>([
      items[2],
      items[3],
    ]);
    const [dialogSelectedItems, setDialogSelectedItems] = useState<Item[]>([
      items[2],
      items[3],
    ]);
    const [openDialog, setOpenDialog] = useState(true);

    const handleDialogClose = () => setOpenDialog(false);

    const handleCancelClick = () => setDialogSelectedItems(selectedItems ?? []);

    const handleApplyClick = () => {
      setOpenDialog(false);
      setSelectedItems(dialogSelectedItems);
    };

    const handleSelectionChange = (selectedLabels: string[]) => {
      const selectedItems = items.filter((item) =>
        selectedLabels.includes(item.name),
      );
      setDialogSelectedItems(selectedItems);
    };

    const selectedLabels = dialogSelectedItems.map((item) => item.name);

    return (
      <div style={{ minHeight: "443px", minWidth: "455px" }}>
        <div style={{ padding: "1.5rem" }}>
          <Flex direction="column" gap="6">
            <SelectTrigger
              multiple
              selectedItems={selectedItems ?? []}
              itemToString={(item) => (item ? item.name : "")}
              onChange={(items: Item[] | null) => setSelectedItems(items)}
              onClick={() => {
                setDialogSelectedItems(selectedItems ?? []);
                setOpenDialog(true);
              }}
              label="Label"
              placeholder="Placeholder"
              hint="Hint text"
              moreInfo="More info"
              size="large"
              required
            />
          </Flex>

          <Dialog open={openDialog} onClose={handleDialogClose}>
            <Dialog.Header>Dialog Header</Dialog.Header>

            <Dialog.Content>
              <Grid flexGrow="1" gap="2">
                <SearchField style={{ gap: 0 }} />

                <Tab defaultIndex={0} fill>
                  <Tab.List>
                    <Tab.Button id="t1" controls="p1">
                      All
                    </Tab.Button>
                    <Tab.Button id="t2" controls="p2">
                      Selected
                    </Tab.Button>
                  </Tab.List>
                  <Tab.Panel id="p1">
                    <Flex gap="4" direction="column">
                      <ListView
                        onSelectionChange={handleSelectionChange}
                        selected={selectedLabels}
                      >
                        {items.map((item) => (
                          <ListView.Option key={item.id} label={item.name}>
                            <Text>{item.name}</Text>
                          </ListView.Option>
                        ))}
                      </ListView>
                    </Flex>
                  </Tab.Panel>
                  <Tab.Panel id="p2">
                    <Flex gap="4" direction="column">
                      <ListView
                        onSelectionChange={handleSelectionChange}
                        selected={selectedLabels}
                      >
                        {dialogSelectedItems.map((item) => (
                          <ListView.Option key={item.id} label={item.name}>
                            <Text>{item.name}</Text>
                          </ListView.Option>
                        ))}
                      </ListView>
                    </Flex>
                  </Tab.Panel>
                </Tab>
              </Grid>
            </Dialog.Content>

            <Dialog.Footer>
              <Flex gap="3" justifyContent="flex-end">
                <Dialog.CancelButton onClick={handleCancelClick}>
                  Cancel
                </Dialog.CancelButton>
                <Button appearance="primary" onClick={handleApplyClick}>
                  Apply
                </Button>
              </Flex>
            </Dialog.Footer>
          </Dialog>
        </div>
      </div>
    );
  }

  export default App;
  ```
</LiveCode>

Use Select Trigger with Dialog containing Tabs to organize complex selection scenarios with multiple views.

## Content

Content within Select Trigger should clearly communicate the selection state and provide appropriate labels and hints.

### Labels and hints

* Use clear, descriptive labels that explain what users are selecting
* Provide hint text when the selection behavior or options need clarification
* Use required indicators when selection is mandatory
* Include moreInfo content when additional context is helpful

### Placeholder text

* Use placeholder text to guide users on what to select
* Keep placeholder text concise and actionable
* Avoid using placeholder text as the primary instruction

## Keyboard Interaction

Users can navigate Select Trigger using standard keyboard controls.

| Key   | Description                                        |
| ----- | -------------------------------------------------- |
| Tab   | Moves focus to the Select Trigger input area       |
| Enter | Opens the selection interface (Typically a Dialog) |
| Space | Opens the selection interface (Typically a Dialog) |

Select Trigger provides keyboard support for opening the selection interface. Once the Dialog opens, keyboard interaction follows the patterns of that component. Individual Chips in multiple selection mode can be removed using their close buttons, which are accessible via keyboard navigation.
