# Controllers

Read and change a component from outside its parts.

A controller connects code to a mounted component. Use one when the button or action that changes it lives somewhere else.

## Connect a Controller

Create it once in your component and pass it to the root:

```vue
<script setup lang="ts">
import { createToggleController, Toggle } from "@ui-sdk/vue/toggle"

const toggle = createToggleController()
</script>

<template>
  <button @click="() => toggle.toggle()">Toggle Bold</button>
  <Toggle :controller="toggle">Bold</Toggle>
</template>
```

Controller methods run the same change callbacks as user input. Controlled values and cancellation follow [State and Events](/docs/vue/state-and-events).

Each component lists its methods, such as `open()`, `close()`, `setValue()`, or `focus()`.

A read like `toggle.isPressed()` answers when you call it, so call it from an event handler or async code. It returns `undefined` until the component mounts, and the template doesn't update when the state changes. To render the state, keep it in a ref with `v-model:pressed`.

## Share a Popup

External triggers can use the same controller. A `payload` tells the content which item was opened:

```vue
<script setup lang="ts">
import {
  createPopoverController,
  Popover,
  PopoverContent,
  PopoverTitle,
  PopoverTrigger,
} from "@ui-sdk/vue/popover"

const editor = createPopoverController<string>()
</script>

<template>
  <PopoverTrigger :controller="editor" payload="Notes"
    >Edit Notes</PopoverTrigger
  >
  <PopoverTrigger :controller="editor" payload="Tasks"
    >Edit Tasks</PopoverTrigger
  >
  <Popover :controller="editor">
    <PopoverContent v-slot="{ state }"
      ><PopoverTitle>Edit {{ state.payload }}</PopoverTitle></PopoverContent
    >
  </Popover>
</template>
```

## Wait for a Popup to Close

A popup controller's `open()` returns a promise. It settles when the popup closes, with its reason and return value:

```ts
const result = await editor.open({ payload: "Notes" })
console.log(result.reason, result.returnValue)
```

For confirmations, [Alert Dialog](/docs/vue/components/alert-dialog) provides `createConfirm()`, which gives you a function you can await.
