<script setup lang="ts">
import { ref } from 'vue'

import Button from "~/components/ui/Button.vue"
import OptionsButton from "~/components/ui/button/Options.vue"
import Pill from "~/components/ui/Pill.vue"
import Popover from "~/components/ui/Popover.vue"
import PopoverCheckbox from "~/components/ui/popover/PopoverCheckbox.vue"
import PopoverItem from "~/components/ui/popover/PopoverItem.vue"
import PopoverRadio from "~/components/ui/popover/PopoverRadio.vue"
import PopoverSubmenu from "~/components/ui/popover/PopoverSubmenu.vue"

// String values

const privacyChoices = ['public', 'private', 'pod']
const bcPrivacy = ref('pod')
const ccPrivacy = ref('public')

// Boolean values

const bc = ref(false)
const cc = ref(false)
const share = ref(false)

// Alert control

const alert = (message: string) => window.alert(message)

// Menu controls

const emptyMenu = ref(false)
// const separator = ref(false)
const singleItemMenu = ref(false)
const checkboxMenu = ref(false)
const radioMenu = ref(false)
const seperatorMenu = ref(false)
const subMenu = ref(false)
const extraItemsMenu = ref(false)
const fullMenu= ref(false)
const isOpen = ref(false)
</script>

# Popover (Dropdown Menu)

Popovers (`Popover`) are dropdown menus activated by a button. Use popovers to create dropdown menus ranging from simple lists to complex nested menus.

Common uses:

- "More actions" dropdown menus
- Navigation menus
- Settings menus
- Context menus (right-click menus)

| Prop   | Data type | Required? | Description                                                |
| ------ | --------- | --------- | ---------------------------------------------------------- |
| `open` | Boolean   | No        | Controls whether the popover is open. Defaults to `false`. |

## Options button

The options button (`OptionsButton`) is a stylized button you can use to hide and show your popover. Use [Vue event handling](https://vuejs.org/guide/essentials/event-handling.html) to map the button to a boolean value.

```vue{7}
<script setup lang="ts">
  const open = ref(false)
</script>

<template>
  <Popover v-model:open="open">
    <OptionsButton @click="open = !open" />
  </Popover>
</template>
```

<Popover v-model:open="emptyMenu">
  <OptionsButton @click="emptyMenu = !emptyMenu" />
</Popover>

You can also use the `toggleOpen` prop in the `<template #default`> tag if you prefer not to use refs to control the menu's visibility.

```vue{8-12}
<script setup lang="ts">
const open = ref(false)
const privacyChoices = ['pod', 'public', 'private']
const bcPrivacy = ref('pod')
</script>

<template>
  <Popover v-model:open="isOpen">
    <template #default="{ toggleOpen }">
      <Pill
      @click="(e) => {
        console.log('Pill clicked');
        console.log('Before toggleOpen:', isOpen);
        toggleOpen();
        console.log('After toggleOpen:', isOpen);
      }"
        :blue="bcPrivacy === 'pod'"
        :red="bcPrivacy === 'public'"
      >
        {{ bcPrivacy }}
      </Pill>
    </template>
    <template #items>
      <PopoverRadio v-model="bcPrivacy" :choices="privacyChoices"/>
    </template>
  </Popover>
</template>
```

<Popover v-model:open="isOpen">
  <template #default="{ toggleOpen }">
    <Pill
    @click="(e) => {
      console.log('Pill clicked');
      console.log('Before toggleOpen:', isOpen);
      toggleOpen();
      console.log('After toggleOpen:', isOpen);
    }"
      :blue="bcPrivacy === 'pod'"
      :red="bcPrivacy === 'public'"
    >
      {{ bcPrivacy }}
    </Pill>
  </template>
  <template #items>
    <PopoverRadio v-model="bcPrivacy" :choices="privacyChoices"/>
  </template>
</Popover>

## Items

Popovers contain a list of menu items. Items can contain different information based on their type.

::: info
Lists of items must be nested inside a `<template #items>` tag directly under the `<Popover>` tag.
:::

### Popover item

The popover item (`PopoverItem`) is a simple button that uses [Vue event handling](https://vuejs.org/guide/essentials/event-handling.html). Each item contains a [slot](https://vuejs.org/guide/components/slots.html) which you can use to add a menu label and icon.

```vue{10-13}
<script setup lang="ts">
  const alert = (message: string) => window.alert(message)
  const open = ref(false)
</script>

<template>
  <Popover v-model:open="open">
    <OptionsButton @click="open = !open" />
    <template #items>
      <PopoverItem @click="alert('Report this object?')">
        <i class="bi bi-exclamation" />
        Report
      </PopoverItem>
    </template>
  </Popover>
</template>
```

<Popover v-model:open="singleItemMenu">
  <OptionsButton @click="singleItemMenu = !singleItemMenu" />
  <template #items>
    <PopoverItem @click="alert('Report this object?')">
      <i class="bi bi-exclamation" />
      Report
    </PopoverItem>
  </template>
</Popover>

### Checkbox

The checkbox (`PopoverCheckbox`) is an item that acts as a selectable box. Use [`v-model`](https://vuejs.org/api/built-in-directives.html#v-model) to bind the checkbox to a boolean value. Each checkbox contains a [slot](https://vuejs.org/guide/components/slots.html) which you can use to add a menu label.

```vue{11-16}
<script setup lang="ts">
const bc = ref(false)
const cc = ref(false)
const open = ref(false)
</script>

<template>
  <Popover v-model:open="open">
    <OptionsButton @click="open = !open" />
    <template #items>
      <PopoverCheckbox v-model="bc">
        Bandcamp
      </PopoverCheckbox>
      <PopoverCheckbox v-model="cc">
        Creative commons
      </PopoverCheckbox>
    </template>
  </Popover>
</template>
```

<Popover v-model:open="checkboxMenu">
  <OptionsButton @click="checkboxMenu = !checkboxMenu" />
  <template #items>
    <PopoverCheckbox v-model="bc">
      Bandcamp
    </PopoverCheckbox>
    <PopoverCheckbox v-model="cc">
      Creative commons
    </PopoverCheckbox>
  </template>
</Popover>

### Radio

The radio (`PopoverRadio`) is an item that acts as a radio selector.

| Prop         | Data type       | Required? | Description                                                                                                                      |
| ------------ | --------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `modelValue` | String          | Yes       | The current value of the radio. Use [`v-model`](https://vuejs.org/api/built-in-directives.html#v-model) to bind this to a value. |
| `choices`    | Array\<String\> | Yes       | A list of choices.                                                                                                               |

```vue
<script setup lang="ts">
const open = ref(false);
const currentChoice = ref("pod");
const privacy = ["public", "private", "pod"];
</script>

<template>
  <Popover v-model:open="open">
    <OptionsButton @click="open = !open" />
    <template #items>
      <PopoverRadio v-model="currentChoice" :choices="choices" />
    </template>
  </Popover>
</template>
```

<Popover v-model:open="radioMenu">
  <OptionsButton @click="radioMenu = !radioMenu" />
    <template #items>
      <PopoverRadio v-model="bcPrivacy" :choices="privacyChoices"/>
    </template>
</Popover>

### Separator

Use a standard horizontal rule (`<hr>`) to add visual separators to popover lists.

```vue{14}
<script setup lang="ts">
const bc = ref(false)
const cc = ref(false)
const open = ref(false)
</script>

<template>
  <Popover v-model:open="open">
    <OptionsButton @click="open = !open" />
    <template #items>
      <PopoverCheckbox v-model="bc">
        Bandcamp
      </PopoverCheckbox>
      <hr>
      <PopoverCheckbox v-model="cc">
        Creative commons
      </PopoverCheckbox>
    </template>
  </Popover>
</template>
```

<Popover v-model:open="seperatorMenu">
  <OptionsButton @click="seperatorMenu = !seperatorMenu" />
  <template #items>
    <PopoverCheckbox v-model="bc">
      Bandcamp
    </PopoverCheckbox>
    <hr>
    <PopoverCheckbox v-model="cc">
      Creative commons
    </PopoverCheckbox>
  </template>
</Popover>

## Submenus

To create more complex menus, you can use submenus (`PopoverSubmenu`). Submenus are menu items which contain other menu items.

```vue{10-18}
<script setup lang="ts">
const bc = ref(false)
const open = ref(false)
</script>

<template>
  <Popover v-model:open="open">
    <OptionsButton @click="open = !open" />
    <template #items>
      <PopoverSubmenu>
        <i class="bi bi-collection" />
        Organize and share
        <template #items>
          <PopoverCheckbox v-model="bc">
            Bandcamp
          </PopoverCheckbox>
        </template>
      </PopoverSubmenu>
    </template>
  </Popover>
</template>
```

<Popover v-model:open="subMenu">
  <OptionsButton @click="subMenu = !subMenu" />
  <template #items>
    <PopoverSubmenu>
      <i class="bi bi-collection" />
      Organize and share
      <template #items>
        <PopoverCheckbox v-model="bc">
          Bandcamp
        </PopoverCheckbox>
      </template>
    </PopoverSubmenu>
  </template>
</Popover>

## Extra items

You can add extra items to the right hand side of a popover item by nesting them in a `<template #after>` tag. Use this to add additional menus or buttons to menu items.

```vue{18-29,34-37}
<script setup lang="ts">
const bc = ref(false)
const privacyChoices = ['public', 'private', 'pod']
const bcPrivacy = ref('pod')
const open = ref(false)
</script>

<template>
  <Popover v-model:open="open">
    <OptionsButton @click="open = !open" />
    <template #items>
      <PopoverSubmenu>
        <i class="bi bi-collection" />
        Organize and share
        <template #items>
          <PopoverCheckbox v-model="bc">
            Bandcamp
            <template #after>
              <Popover>
                <template #default="{ toggleOpen }">
                  <Pill @click.stop="toggleOpen" :blue="bcPrivacy === 'pod'" :red="bcPrivacy === 'public'">
                    {{ bcPrivacy }}
                  </Pill>
                </template>
                <template #items>
                  <PopoverRadio v-model="bcPrivacy" :choices="privacyChoices"/>
                </template>
              </Popover>
            </template>
          </PopoverCheckbox>
          <hr>
          <PopoverCheckbox v-model="share">
            Share by link
            <template #after>
              <Button @click.stop="alert('Link copied to clipboard')" color="secondary" round icon="bi-link" />
              <Button @click.stop="alert('Here is your code')" color="secondary" round icon="bi-code" />
            </template>
          </PopoverCheckbox>
        </template>
      </PopoverSubmenu>
    </template>
  </Popover>
</template>
```

<Popover v-model:open="extraItemsMenu">
  <OptionsButton @click="extraItemsMenu = !extraItemsMenu" />
  <template #items>
    <PopoverSubmenu>
      <i class="bi bi-collection" />
      Organize and share
      <template #items>
        <PopoverCheckbox v-model="bc">
          Bandcamp
          <template #after>
            <Popover>
              <template #default="{ toggleOpen }">
                <Pill @click.stop="toggleOpen" :blue="bcPrivacy === 'pod'" :red="bcPrivacy === 'public'">
                  {{ bcPrivacy }}
                </Pill>
              </template>
              <template #items>
                <PopoverRadio v-model="bcPrivacy" :choices="privacyChoices"/>
              </template>
            </Popover>
          </template>
        </PopoverCheckbox>
        <hr>
        <PopoverCheckbox v-model="share">
          Share by link
          <template #after>
            <Button @click.stop="alert('Link copied to clipboard')" secondary round icon="bi-link" />
            <Button @click.stop="alert('Here is your code')" secondary round icon="bi-code" />
          </template>
        </PopoverCheckbox>
      </template>
    </PopoverSubmenu>
  </template>
</Popover>

## Menu

Here is an example of a completed menu containing all supported features.

```vue
<script setup lang="ts">
const open = ref(false);
const bc = ref(false);
const cc = ref(false);
const share = ref(false);
const bcPrivacy = ref("pod");
const ccPrivacy = ref("public");
const privacyChoices = ["private", "pod", "public"];
</script>

<template>
  <Popover v-model:open="open">
    <OptionsButton @click="open = !open" />
    <template #items>
      <PopoverItem>
        <i class="bi bi-arrow-up-right" />
        Play next
      </PopoverItem>
      <PopoverItem>
        <i class="bi bi-arrow-down-right" />
        Append to queue
      </PopoverItem>
      <PopoverSubmenu>
        <i class="bi bi-music-note-list" />
        Add to playlist
        <template #items>
          <PopoverItem>
            <i class="bi bi-music-note-list" />
            Sample playlist
          </PopoverItem>
          <hr />
          <PopoverItem>
            <i class="bi bi-plus-lg" />
            New playlist
          </PopoverItem>
        </template>
      </PopoverSubmenu>
      <hr />
      <PopoverItem>
        <i class="bi bi-heart" />
        Add to favorites
      </PopoverItem>
      <PopoverSubmenu>
        <i class="bi bi-collection" />
        Organize and share
        <template #items>
          <PopoverCheckbox v-model="bc">
            Bandcamp
            <template #after>
              <Popover>
                <template #default="{ toggleOpen }">
                  <Pill
                    @click.stop="toggleOpen"
                    :blue="bcPrivacy === 'pod'"
                    :red="bcPrivacy === 'public'"
                  >
                    {{ bcPrivacy }}
                  </Pill>
                </template>
                <template #items>
                  <PopoverRadio v-model="bcPrivacy" :choices="privacyChoices" />
                </template>
              </Popover>
            </template>
          </PopoverCheckbox>
          <PopoverCheckbox v-model="cc">
            Creative Commons
            <template #after>
              <Popover v-model:open="isOpen">
                <template #default="{ toggleOpen }">
                  <Pill
                    @click="toggleOpen"
                    :blue="ccPrivacy === 'pod'"
                    :red="ccPrivacy === 'public'"
                  >
                    {{ ccPrivacy }}
                  </Pill>
                </template>
                <template #items>
                  <PopoverRadio v-model="ccPrivacy" :choices="privacyChoices" />
                </template>
              </Popover>
            </template>
          </PopoverCheckbox>
          <hr />
          <PopoverItem>
            <i class="bi bi-plus-lg" />
            New library
          </PopoverItem>
          <hr />
          <PopoverCheckbox v-model="share">
            Share by link
            <template #after>
              <Button @click.stop color="secondary" round icon="bi-link" />
              <Button @click.stop color="secondary" round icon="bi-code" />
            </template>
          </PopoverCheckbox>
        </template>
      </PopoverSubmenu>
      <PopoverItem>
        <i class="bi bi-cloud-download" />
        Download
      </PopoverItem>
      <hr />
      <PopoverItem>
        <i class="bi bi-exclamation" />
        Report
      </PopoverItem>
    </template>
  </Popover>
</template>
```

<Popover v-model:open="fullMenu">
  <OptionsButton @click="fullMenu = !fullMenu" />
  <template #items>
    <PopoverItem>
      <i class="bi bi-arrow-up-right" />
      Play next
    </PopoverItem>
    <PopoverItem>
      <i class="bi bi-arrow-down-right" />
      Append to queue
    </PopoverItem>
    <PopoverSubmenu>
      <i class="bi bi-music-note-list" />
      Add to playlist
      <template #items>
        <PopoverItem>
          <i class="bi bi-music-note-list" />
          Sample playlist
        </PopoverItem>
        <hr>
        <PopoverItem>
          <i class="bi bi-plus-lg" />
          New playlist
        </PopoverItem>
      </template>
    </PopoverSubmenu>
    <hr>
    <PopoverItem>
      <i class="bi bi-heart" />
      Add to favorites
    </PopoverItem>
    <PopoverSubmenu>
      <i class="bi bi-collection" />
      Organize and share
      <template #items>
        <PopoverCheckbox v-model="bc">
          Bandcamp
          <template #after>
            <Popover v-model:open="isOpen">
              <template #default="{ toggleOpen }">
                <Pill @click.stop="toggleOpen" :blue="bcPrivacy === 'pod'" :red="bcPrivacy === 'public'">
                  {{ bcPrivacy }}
                </Pill>
              </template>
              <template #items>
                <PopoverRadio v-model="bcPrivacy" :choices="privacyChoices"/>
              </template>
            </Popover>
          </template>
        </PopoverCheckbox>
        <PopoverCheckbox v-model="cc">
          Creative Commons
          <template #after>
            <Popover v-model:open="isOpen">
              <template #default="{ toggleOpen }">
                <Pill @click="toggleOpen" :blue="ccPrivacy === 'pod'" :red="ccPrivacy === 'public'">
                  {{ ccPrivacy }}
                </Pill>
              </template>
              <template #items>
                <PopoverRadio v-model="ccPrivacy" :choices="privacyChoices"/>
              </template>
            </Popover>
          </template>
        </PopoverCheckbox>
        <hr>
        <PopoverItem>
          <i class="bi bi-plus-lg" />
          New library
        </PopoverItem>
        <hr>
        <PopoverCheckbox v-model="share">
          Share by link
          <template #after>
            <Button @click.stop color="secondary" round icon="bi-link" />
            <Button @click.stop color="secondary" round icon="bi-code" />
          </template>
        </PopoverCheckbox>
      </template>
    </PopoverSubmenu>
    <PopoverItem>
      <i class="bi bi-cloud-download" />
      Download
    </PopoverItem>
    <hr>
    <PopoverItem>
      <i class="bi bi-exclamation" />
      Report
    </PopoverItem>
  </template>
</Popover>
