funkwhale/front/ui-docs/components/ui/popover.md

589 wiersze
17 KiB
Markdown
Czysty Zwykły widok Historia

<script setup lang="ts">
import { ref } from '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)
</script>
# Popover
Popovers (`fw-popover`) are visually hidden menus of items activated by a simple button. Use popovers to create complex menus in a visually appealing way.
| Prop | Data type | Required? | Description |
| ------ | --------- | --------- | ---------------------------------------------------------- |
| `open` | Boolean | No | Controls whether the popover is open. Defaults to `false`. |
## Options button
The options button (`fw-options-button`) 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>
<fw-popover v-model:open="open">
<fw-options-button @click="open = !open" />
</fw-popover>
</template>
```
<fw-popover v-model:open="emptyMenu">
<fw-options-button @click="emptyMenu = !emptyMenu" />
</fw-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 privacyChoices = ['pod', 'public', 'private']
const bcPrivacy = ref('pod')
</script>
<template>
<fw-popover>
<template #default="{ toggleOpen }">
<fw-pill @click.stop="toggleOpen" :blue="bcPrivacy === 'pod'" :red="bcPrivacy === 'public'">
{{ bcPrivacy }}
</fw-pill>
</template>
<template #items>
<fw-popover-radio v-model="bcPrivacy" :choices="privacyChoices"/>
</template>
</fw-popover>
</template>
```
<fw-popover>
<template #default="{ toggleOpen }">
<fw-pill @click.stop="toggleOpen" :blue="bcPrivacy === 'pod'" :red="bcPrivacy === 'public'">
{{ bcPrivacy }}
</fw-pill>
</template>
<template #items>
<fw-popover-radio v-model="bcPrivacy" :choices="privacyChoices"/>
</template>
</fw-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 `<fw-popover>` tag.
:::
### Popover item
The popover item (`fw-popover-item`) 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>
<fw-popover v-model:open="open">
<fw-options-button @click="open = !open" />
<template #items>
<fw-popover-item @click="alert('Report this object?')">
<i class="bi bi-exclamation" />
Report
</fw-popover-item>
</template>
</fw-popover>
</template>
```
<fw-popover v-model:open="singleItemMenu">
<fw-options-button @click="singleItemMenu = !singleItemMenu" />
<template #items>
<fw-popover-item @click="alert('Report this object?')">
<i class="bi bi-exclamation" />
Report
</fw-popover-item>
</template>
</fw-popover>
### Checkbox
The checkbox (`fw-popover-checkbox`) 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>
<fw-popover v-model:open="open">
<fw-options-button @click="open = !open" />
<template #items>
<fw-popover-checkbox v-model="bc">
Bandcamp
</fw-popover-checkbox>
<fw-popover-checkbox v-model="cc">
Creative commons
</fw-popover-checkbox>
</template>
</fw-popover>
</template>
```
<fw-popover v-model:open="checkboxMenu">
<fw-options-button @click="checkboxMenu = !checkboxMenu" />
<template #items>
<fw-popover-checkbox v-model="bc">
Bandcamp
</fw-popover-checkbox>
<fw-popover-checkbox v-model="cc">
Creative commons
</fw-popover-checkbox>
</template>
</fw-popover>
### Radio
The radio (`fw-popover-radio`) 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>
<fw-popover v-model:open="open">
<fw-options-button @click="open = !open" />
<template #items>
<fw-popover-radio v-model="currentChoice" :choices="choices" />
</template>
</fw-popover>
</template>
```
<fw-popover v-model:open="radioMenu">
<fw-options-button @click="radioMenu = !radioMenu" />
<template #items>
<fw-popover-radio v-model="bcPrivacy" :choices="privacyChoices"/>
</template>
</fw-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>
<fw-popover v-model:open="open">
<fw-options-button @click="open = !open" />
<template #items>
<fw-popover-checkbox v-model="bc">
Bandcamp
</fw-popover-checkbox>
<hr>
<fw-popover-checkbox v-model="cc">
Creative commons
</fw-popover-checkbox>
</template>
</fw-popover>
</template>
```
<fw-popover v-model:open="seperatorMenu">
<fw-options-button @click="seperatorMenu = !seperatorMenu" />
<template #items>
<fw-popover-checkbox v-model="bc">
Bandcamp
</fw-popover-checkbox>
<hr>
<fw-popover-checkbox v-model="cc">
Creative commons
</fw-popover-checkbox>
</template>
</fw-popover>
## Submenus
To create more complex menus, you can use submenus (`fw-popover-submenu`). 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>
<fw-popover v-model:open="open">
<fw-options-button @click="open = !open" />
<template #items>
<fw-popover-submenu>
<i class="bi bi-collection" />
Organize and share
<template #items>
<fw-popover-checkbox v-model="bc">
Bandcamp
</fw-popover-checkbox>
</template>
</fw-popover-submenu>
</template>
</fw-popover>
</template>
```
<fw-popover v-model:open="subMenu">
<fw-options-button @click="subMenu = !subMenu" />
<template #items>
<fw-popover-submenu>
<i class="bi bi-collection" />
Organize and share
<template #items>
<fw-popover-checkbox v-model="bc">
Bandcamp
</fw-popover-checkbox>
</template>
</fw-popover-submenu>
</template>
</fw-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>
<fw-popover v-model:open="open">
<fw-options-button @click="open = !open" />
<template #items>
<fw-popover-submenu>
<i class="bi bi-collection" />
Organize and share
<template #items>
<fw-popover-checkbox v-model="bc">
Bandcamp
<template #after>
<fw-popover>
<template #default="{ toggleOpen }">
<fw-pill @click.stop="toggleOpen" :blue="bcPrivacy === 'pod'" :red="bcPrivacy === 'public'">
{{ bcPrivacy }}
</fw-pill>
</template>
<template #items>
<fw-popover-radio v-model="bcPrivacy" :choices="privacyChoices"/>
</template>
</fw-popover>
</template>
</fw-popover-checkbox>
<hr>
<fw-popover-checkbox v-model="share">
Share by link
<template #after>
<fw-button @click.stop="alert('Link copied to clipboard')" color="secondary" round icon="bi-link" />
<fw-button @click.stop="alert('Here is your code')" color="secondary" round icon="bi-code" />
</template>
</fw-popover-checkbox>
</template>
</fw-popover-submenu>
</template>
</fw-popover>
</template>
```
<fw-popover v-model:open="extraItemsMenu">
<fw-options-button @click="extraItemsMenu = !extraItemsMenu" />
<template #items>
<fw-popover-submenu>
<i class="bi bi-collection" />
Organize and share
<template #items>
<fw-popover-checkbox v-model="bc">
Bandcamp
<template #after>
<fw-popover>
<template #default="{ toggleOpen }">
<fw-pill @click.stop="toggleOpen" :blue="bcPrivacy === 'pod'" :red="bcPrivacy === 'public'">
{{ bcPrivacy }}
</fw-pill>
</template>
<template #items>
<fw-popover-radio v-model="bcPrivacy" :choices="privacyChoices"/>
</template>
</fw-popover>
</template>
</fw-popover-checkbox>
<hr>
<fw-popover-checkbox v-model="share">
Share by link
<template #after>
<fw-button @click.stop="alert('Link copied to clipboard')" secondary round icon="bi-link" />
<fw-button @click.stop="alert('Here is your code')" secondary round icon="bi-code" />
</template>
</fw-popover-checkbox>
</template>
</fw-popover-submenu>
</template>
</fw-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>
<fw-popover v-model:open="open">
<fw-options-button @click="open = !open" />
<template #items>
<fw-popover-item>
<i class="bi bi-arrow-up-right" />
Play next
</fw-popover-item>
<fw-popover-item>
<i class="bi bi-arrow-down-right" />
Append to queue
</fw-popover-item>
<fw-popover-submenu>
<i class="bi bi-music-note-list" />
Add to playlist
<template #items>
<fw-popover-item>
<i class="bi bi-music-note-list" />
Sample playlist
</fw-popover-item>
<hr />
<fw-popover-item>
<i class="bi bi-plus-lg" />
New playlist
</fw-popover-item>
</template>
</fw-popover-submenu>
<hr />
<fw-popover-item>
<i class="bi bi-heart" />
Add to favorites
</fw-popover-item>
<fw-popover-submenu>
<i class="bi bi-collection" />
Organize and share
<template #items>
<fw-popover-checkbox v-model="bc">
Bandcamp
<template #after>
<fw-popover>
<template #default="{ toggleOpen }">
<fw-pill
@click.stop="toggleOpen"
:blue="bcPrivacy === 'pod'"
:red="bcPrivacy === 'public'"
>
{{ bcPrivacy }}
</fw-pill>
</template>
<template #items>
<fw-popover-radio
v-model="bcPrivacy"
:choices="privacyChoices"
/>
</template>
</fw-popover>
</template>
</fw-popover-checkbox>
<fw-popover-checkbox v-model="cc">
Creative Commons
<template #after>
<fw-popover>
<template #default="{ toggleOpen }">
<fw-pill
@click.stop="toggleOpen"
:blue="ccPrivacy === 'pod'"
:red="ccPrivacy === 'public'"
>
{{ ccPrivacy }}
</fw-pill>
</template>
<template #items>
<fw-popover-radio
v-model="ccPrivacy"
:choices="privacyChoices"
/>
</template>
</fw-popover>
</template>
</fw-popover-checkbox>
<hr />
<fw-popover-item>
<i class="bi bi-plus-lg" />
New library
</fw-popover-item>
<hr />
<fw-popover-checkbox v-model="share">
Share by link
<template #after>
<fw-button @click.stop color="secondary" round icon="bi-link" />
<fw-button @click.stop color="secondary" round icon="bi-code" />
</template>
</fw-popover-checkbox>
</template>
</fw-popover-submenu>
<fw-popover-item>
<i class="bi bi-cloud-download" />
Download
</fw-popover-item>
<hr />
<fw-popover-item>
<i class="bi bi-exclamation" />
Report
</fw-popover-item>
</template>
</fw-popover>
</template>
```
<fw-popover v-model:open="fullMenu">
<fw-options-button @click="fullMenu = !fullMenu" />
<template #items>
<fw-popover-item>
<i class="bi bi-arrow-up-right" />
Play next
</fw-popover-item>
<fw-popover-item>
<i class="bi bi-arrow-down-right" />
Append to queue
</fw-popover-item>
<fw-popover-submenu>
<i class="bi bi-music-note-list" />
Add to playlist
<template #items>
<fw-popover-item>
<i class="bi bi-music-note-list" />
Sample playlist
</fw-popover-item>
<hr>
<fw-popover-item>
<i class="bi bi-plus-lg" />
New playlist
</fw-popover-item>
</template>
</fw-popover-submenu>
<hr>
<fw-popover-item>
<i class="bi bi-heart" />
Add to favorites
</fw-popover-item>
<fw-popover-submenu>
<i class="bi bi-collection" />
Organize and share
<template #items>
<fw-popover-checkbox v-model="bc">
Bandcamp
<template #after>
<fw-popover>
<template #default="{ toggleOpen }">
<fw-pill @click.stop="toggleOpen" :blue="bcPrivacy === 'pod'" :red="bcPrivacy === 'public'">
{{ bcPrivacy }}
</fw-pill>
</template>
<template #items>
<fw-popover-radio v-model="bcPrivacy" :choices="privacyChoices"/>
</template>
</fw-popover>
</template>
</fw-popover-checkbox>
<fw-popover-checkbox v-model="cc">
Creative Commons
<template #after>
<fw-popover>
<template #default="{ toggleOpen }">
<fw-pill @click.stop="toggleOpen" :blue="ccPrivacy === 'pod'" :red="ccPrivacy === 'public'">
{{ ccPrivacy }}
</fw-pill>
</template>
<template #items>
<fw-popover-radio v-model="ccPrivacy" :choices="privacyChoices"/>
</template>
</fw-popover>
</template>
</fw-popover-checkbox>
<hr>
<fw-popover-item>
<i class="bi bi-plus-lg" />
New library
</fw-popover-item>
<hr>
<fw-popover-checkbox v-model="share">
Share by link
<template #after>
<fw-button @click.stop color="secondary" round icon="bi-link" />
<fw-button @click.stop color="secondary" round icon="bi-code" />
</template>
</fw-popover-checkbox>
</template>
</fw-popover-submenu>
<fw-popover-item>
<i class="bi bi-cloud-download" />
Download
</fw-popover-item>
<hr>
<fw-popover-item>
<i class="bi bi-exclamation" />
Report
</fw-popover-item>
</template>
</fw-popover>