Menu options
This component provides a container for grouping menu items that behave like options, allowing only one to be selected at a time. Its layout can be adjusted based on the isHorizontal prop. When set to horizontal, it applies a specific style; otherwise, it defaults to a vertical layout.
Selection is tracked by identity rather than position: each item is matched on its vnode :key when it has one, falling back to its index for keyless static lists. Give items an explicit :key so the selection survives conditional or reordered items.
Props
model-value: string | number
Identifies the highlighted or selected option. Matches the option's vnode key (:key) when present, falling back to its position for keyless static lists.
is-horizontal?: boolean
Indicates that the items should flow horizontally.
is-persistent?: boolean
Keeps the surrounding menu open after an option is clicked. Defaults to true, since options menus are meant to stay open while selecting. Set to false to close the menu on selection.
Default: true
mode?: "highlight" | "select"
The active mode of the option.
Default: highlight
Emits
update:model-value: [string, number]
Triggered when the active option changes. Emits the option's vnode key when it has one, otherwise its index.
Slots
default
The content of the options group.
Examples
Alignment
Horizontal option menus can be used to allow users to select an alignment.
<template>
<FluxFlex
direction="vertical"
:gap="12">
<FluxPane style="width: 270px">
<FluxMenu>
<FluxMenuOptions
v-model="alignment"
is-horizontal>
<FluxMenuItem icon-leading="align-left"/>
<FluxMenuItem icon-leading="align-center"/>
<FluxMenuItem icon-leading="align-right"/>
<FluxMenuItem icon-leading="align-justify"/>
</FluxMenuOptions>
</FluxMenu>
</FluxPane>
<small><kbd>Result = {{ ALIGNMENTS[alignment] }}</kbd></small>
</FluxFlex>
</template>
<script
lang="ts"
setup>
import { FluxFlex, FluxMenu, FluxMenuItem, FluxMenuOptions, FluxPane } from '@flux-ui/components';
import { ref } from 'vue';
const ALIGNMENTS = {
0: 'left',
1: 'center',
2: 'right',
3: 'justify'
} as const;
const alignment = ref<keyof typeof ALIGNMENTS>(0);
</script>Option
Vertical option menus can be used to allow the user to switch between different view modes.
<template>
<FluxFlex
direction="vertical"
:gap="12">
<FluxPane style="width: 270px">
<FluxMenu>
<FluxMenuOptions
v-model="view"
mode="select">
<FluxMenuItem
key="list"
icon-leading="list"
label="List"/>
<FluxMenuItem
key="grid"
icon-leading="grid-2"
label="Grid"/>
</FluxMenuOptions>
</FluxMenu>
</FluxPane>
<small><kbd>Result = {{ view }}</kbd></small>
</FluxFlex>
</template>
<script
lang="ts"
setup>
import { FluxFlex, FluxMenu, FluxMenuItem, FluxMenuOptions, FluxPane } from '@flux-ui/components';
import { ref } from 'vue';
const view = ref<'list' | 'grid'>('list');
</script>Inside a flyout
Option menus stay open while selecting, even inside a flyout. Pass :is-persistent="false" if you want the menu to close on selection instead.
<template>
<FluxFlex
direction="vertical"
:gap="12">
<FluxFlyout>
<template #opener="{ open }">
<FluxSecondaryButton
icon-trailing="angle-down"
:label="`View: ${VIEWS[view]}`"
@click="open()"/>
</template>
<FluxMenu style="width: 200px">
<FluxMenuOptions
v-model="view"
mode="select">
<FluxMenuItem
icon-leading="list"
label="List"/>
<FluxMenuItem
icon-leading="grid-2"
label="Grid"/>
<FluxMenuItem
icon-leading="image"
label="Gallery"/>
</FluxMenuOptions>
</FluxMenu>
</FluxFlyout>
<small><kbd>Selecting an option keeps the menu open</kbd></small>
</FluxFlex>
</template>
<script
lang="ts"
setup>
import { FluxFlex, FluxFlyout, FluxMenu, FluxMenuItem, FluxMenuOptions, FluxSecondaryButton } from '@flux-ui/components';
import { ref } from 'vue';
const VIEWS = ['List', 'Grid', 'Gallery'];
const view = ref(0);
</script>