Skip to main content

Common Examples

import { Button, Dialog, DrillDown, Flex } from "@servicetitan/anvil2";

function ExampleComponent() {
  return (
    <Dialog>
      <Dialog.Header>Dialog Header</Dialog.Header>
      <Dialog.Content>This is the dialog body content.</Dialog.Content>
      <Dialog.Footer>
        <Flex gap="3" justifyContent="flex-end">
          <Dialog.CancelButton>Cancel</Dialog.CancelButton>
          <Button appearance="primary">Continue</Button>
        </Flex>
      </Dialog.Footer>
      <DrillDown index={0}>
        <DrillDown.Header>DrillDown Index 0</DrillDown.Header>
        <DrillDown.Content>This is the drilldown body content.</DrillDown.Content>
        <DrillDown.Footer>
          <Flex gap="3" justifyContent="flex-end">
            <DrillDown.PrevButton>Cancel</DrillDown.PrevButton>
            <DrillDown.NextButton appearance="primary">
              Continue
            </DrillDown.NextButton>
          </Flex>
        </DrillDown.Footer>
      </DrillDown>
    </Dialog>
  );
}

Use as children of Dialog, Drawer, or Page.Panel

Any number of DrillDown components can be added as children of the Dialog, Drawer, or Page.Panel component. When a DrillDown is visible, it will cover the entire contents of the Dialog or Drawer.
<Dialog>
  <Dialog.Header>{...}</Dialog.Header>
  <Dialog.Content>{...}</Dialog.Content>
  <Dialog.Footer>{...}</Dialog.Footer>

  <DrillDown index={0}>{...}</DrillDown>
  <DrillDown index={1}>{...}</DrillDown>
  <DrillDown index={2}>{...}</DrillDown>
  <DrillDown index={3}>{...}</DrillDown>
</Dialog>
<Drawer>
  <Drawer.Header>{...}</Drawer.Header>
  <Drawer.Content>{...}</Drawer.Content>
  <Drawer.Footer>{...}</Drawer.Footer>

  <DrillDown index={0}>{...}</DrillDown>
  <DrillDown index={1}>{...}</DrillDown>
  <DrillDown index={2}>{...}</DrillDown>
  <DrillDown index={3}>{...}</DrillDown>
</Drawer>
Each DrillDown requires a unique indexDrillDown sibling components are identified by their index prop. Numbers used for the index prop are zero-based, and calling next or clicking the DrillDown.NextButton will display the next index in numerical order.

Uncontrolled usage

import { Drawer, Drilldown } from "@servicetitan/anvil2";

function ExampleComponent() {
  const [isOpen, setIsOpen] = useState(true);

  return (
    <Drawer open={isOpen} onClose={() => setIsOpen(false)}>
      <Drawer.Header>Drawer Header</Drawer.Header>
      <Drawer.Content>This is the drawer body content.</Drawer.Content>
      <Drawer.Footer>
        <Flex gap="3" justifyContent="flex-end">
          <Drawer.CancelButton>Cancel</Drawer.CancelButton>
          <DrillDown.NextButton appearance="primary">Continue</DrillDown.NextButton>
        </Flex>
      </Drawer.Footer>

      <DrillDown index={0} onClose={() => setIsOpen(false)}>
        <DrillDown.Header>DrillDown Index 0</DrillDown.Header>
        <DrillDown.Content>This is the drilldown body content.</DrillDown.Content>
        <DrillDown.Footer>
          <Flex gap="3" justifyContent="flex-end">
            <DrillDown.PrevButton>Cancel</DrillDown.PrevButton>
            <DrillDown.NextButton appearance="primary">
              Continue
            </DrillDown.NextButton>
          </Flex>
        </DrillDown.Footer>
      </DrillDown>
    </Drawer>
  );
}

Using DrillDown.NextButton and DrillDown.PrevButton

The DrillDown can be used with uncontrolled state by using the DrillDown.NextButton to move forward to each DrillDown index in ascending numerical order. The DrillDown.PrevButton will similarly move backward in descending numerical order, and will close the DrillDown if the current visible DrillDown is index 0.

Controlled usage

import { Drawer, Drilldown } from "@servicetitan/anvil2";

function ExampleComponent() {
  const { drillDownProps, back, next } = useDrillDown();
  const [isOpen, setIsOpen] = useState(true);

  return (
    <Drawer {...drillDownProps} open={isOpen} onClose={() => setIsOpen(false)}>
      <Drawer.Header>Drawer Header</Drawer.Header>
      <Drawer.Content>This is the drawer body content.</Drawer.Content>
      <Drawer.Footer>
        <Flex gap="3" justifyContent="flex-end">
          <Drawer.CancelButton>Cancel</Drawer.CancelButton>
          <Button appearance="primary" onClick={next}>Continue</Button>
        </Flex>
      </Drawer.Footer>

      <DrillDown index={0} onClose={() => setIsOpen(false)}>
        <DrillDown.Header>DrillDown Index 0</DrillDown.Header>
        <DrillDown.Content>This is the drilldown body content.</DrillDown.Content>
        <DrillDown.Footer>
          <Flex gap="3" justifyContent="flex-end">
            <Button onClick={back}>Cancel</Button>
            <Button appearance="primary" onClick={next}>
              Continue
            </Button>
          </Flex>
        </DrillDown.Footer>
      </DrillDown>
    </Drawer>
  );
}

Using the useDrillDown hook

The useDrillDown hook returns a next and back function to allow for programmatically navigating between DrillDown components in numerical index order. (The hook also returns a setIndex function to allow navigating to arbitrary index values.)To allow this hook to work, the drillDownProps return value also needs to be spread onto the parent component.
import { Drawer, Drilldown } from "@servicetitan/anvil2";

function ExampleComponent() {
  const { drillDownProps, back, next } = useDrillDown();
  const [isOpen, setIsOpen] = useState(true);

  return (
    <Drawer {...drillDownProps} open={isOpen} onClose={() => setIsOpen(false)}>
      {...}
    </Drawer>
  );
}

Closing from within a DrillDown

By default, the DrillDown.Header does not display a close button. To display a close button in the DrillDown.Header, add an onClose handler to the DrillDown.
<DrillDown index={0} onClose={() => setOpen(false)}>
  <DrillDown.Header>DrillDown Index 0</DrillDown.Header>
  <DrillDown.Content>This is the drilldown body content.</DrillDown.Content>
  <DrillDown.Footer>
    <Flex gap="3" justifyContent="flex-end">
      <DrillDown.PrevButton>Cancel</DrillDown.PrevButton>
      <DrillDown.NextButton appearance="primary">
        Continue
      </DrillDown.NextButton>
    </Flex>
  </DrillDown.Footer>
</DrillDown>
Last modified on January 23, 2026