Raccourci clavier : Ctrl + K
Commencer

Bouton divisé

VSplitButton associe une action principale à un menu d’actions voisines. L’action principale est un VButton ; le bouton accolé ouvre un VMenu.

Utilisation

vue

Last action: Nothing yet

<script setup lang="ts">
import { ref } from 'vue'
import { VMenuItem, VMenuSeparator, VSplitButton, VTypography } from 'vectis-ui'

const last = ref('Nothing yet')
</script>

<template>
  <div class="demo">
    <VSplitButton label="Save" @click="last = 'Saved'">
      <VMenuItem label="Save as draft" @select="last = 'Saved as draft'" />
      <VMenuItem label="Save and close" @select="last = 'Saved and closed'" />
      <VMenuSeparator />
      <VMenuItem label="Discard changes" tone="danger" @select="last = 'Changes discarded'" />
    </VSplitButton>
    <VTypography variant="body-sm" tone="muted">Last action: {{ last }}</VTypography>
  </div>
</template>

<style scoped>
.demo {
  display: grid;
  gap: var(--vectis-space-3);
  justify-items: start;
}
</style>

Exemples

Variantes et tons

variant, tone, size, compact et elevated reprennent les valeurs de VButton et s’appliquent aux deux moitiés. Un trait les sépare toujours.

vue
<script setup lang="ts">
import { VMenuItem, VSplitButton } from 'vectis-ui'
</script>

<template>
  <div class="row">
    <VSplitButton label="Publish">
      <VMenuItem label="Schedule" />
    </VSplitButton>
    <VSplitButton label="Publish" variant="soft">
      <VMenuItem label="Schedule" />
    </VSplitButton>
    <VSplitButton label="Export" variant="outline" tone="neutral">
      <VMenuItem label="Export as CSV" />
    </VSplitButton>
    <VSplitButton label="Delete" variant="ghost" tone="danger">
      <VMenuItem label="Delete all versions" tone="danger" />
    </VSplitButton>
  </div>
</template>

<style scoped>
.row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vectis-space-4);
}
</style>

Tailles

Le bouton de menu reste carré à toutes les tailles.

vue
<script setup lang="ts">
import { VMenuItem, VSplitButton } from 'vectis-ui'
</script>

<template>
  <div class="row">
    <VSplitButton
      v-for="size in ['xs', 'sm', 'md', 'lg', 'xl'] as const"
      :key="size"
      :size="size"
      label="Save"
    >
      <VMenuItem label="Save as draft" />
    </VSplitButton>
  </div>
</template>

<style scoped>
.row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--vectis-space-4);
}
</style>

Chargement et désactivation

loading place l’indicateur dans l’action principale et désactive aussi le bouton de menu, puisqu’une action est déjà en cours. disabled désactive les deux moitiés.

vue
<script setup lang="ts">
import { ref } from 'vue'
import { VMenuItem, VSplitButton } from 'vectis-ui'

const saving = ref(false)

function save() {
  saving.value = true
  setTimeout(() => (saving.value = false), 1500)
}
</script>

<template>
  <div class="row">
    <VSplitButton label="Save" :loading="saving" @click="save">
      <VMenuItem label="Save as draft" />
    </VSplitButton>
    <VSplitButton label="Save" disabled>
      <VMenuItem label="Save as draft" />
    </VSplitButton>
  </div>
</template>

<style scoped>
.row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vectis-space-4);
}
</style>

href fait de l’action principale un lien. iconStart et iconEnd appartiennent à l’action principale, et menuIcon remplace le chevron. menuLabel remplace le nom que les lecteurs d’écran donnent au bouton de menu, « Plus d’options » par défaut.

vue
Open report
<script setup lang="ts">
import { VMenuItem, VSplitButton } from 'vectis-ui'
import { description } from 'vectis-ui/icons'
</script>

<template>
  <VSplitButton
    href="#link-and-icons"
    variant="outline"
    tone="neutral"
    :icon-start="description"
    menu-label="Other formats"
    label="Open report"
  >
    <VMenuItem label="Download as CSV" />
    <VMenuItem label="Download as PDF" />
  </VSplitButton>
</template>

Pleine largeur et position du menu

Le menu est ancré à l’ensemble du contrôle et s’aligne par défaut sur sa fin. Avec fullWidth, l’action principale prend la place et le bouton de menu reste carré ; matchWidth garde le menu au moins aussi large que le contrôle.

vue
<script setup lang="ts">
import { VMenuItem, VSplitButton } from 'vectis-ui'
</script>

<template>
  <div class="column">
    <VSplitButton full-width match-width placement="bottom-start" label="Export">
      <VMenuItem label="Export as CSV" />
      <VMenuItem label="Export as PDF" />
      <VMenuItem label="Export as JSON" />
    </VSplitButton>
  </div>
</template>

<style scoped>
.column {
  max-inline-size: 22rem;
}
</style>

API

Props

PropTypeDéfaut
labelstringaucune
Texte de l’action principale.
variantButtonVariant'solid' | 'outline' | 'ghost' | 'soft''solid'
Poids visuel des deux moitiés.
toneButtonTone'accent' | 'neutral' | 'danger''accent'
Couleur des deux moitiés.
sizeButtonSize'xs' | 'sm' | 'md' | 'lg' | 'xl''md'
Hauteur des deux moitiés, sur l’échelle commune des contrôles.
compactbooleanfalse
Retire 4px à la hauteur.
elevatedbooleanfalse
Surélève le contrôle avec une ombre.
fullWidthbooleanfalse
Remplit le parent. L’action principale prend la place ; le bouton de menu reste carré.
hrefstringaucune
Fait de l’action principale un lien, inerte s’il est désactivé ou en chargement.
typeButtonHTMLAttributes['type']'button'
Type natif du bouton principal.
disabledbooleanfalse
Désactive les deux moitiés.
loadingbooleanfalse
Affiche un indicateur dans l’action principale et désactive le bouton de menu.
iconStartIconSourceaucune
Icône avant le libellé de l’action principale.
iconEndIconSourceaucune
Icône après le libellé de l’action principale.
iconFilledbooleanfalse
Affiche les icônes de l’action principale en version pleine.
menuLabelstringaucune
Nom accessible du bouton de menu. « Plus d’options » par défaut.
menuIconIconSourceexpand_more
Icône du bouton de menu.
placementMenuPlacement'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end''bottom-end'
Position du menu par rapport à l’ensemble du contrôle ; s’ajuste si la place manque.
menuSizeMenuSize'sm' | 'md' | 'lg''sm'
Hauteur des lignes du menu.
menuWidthnumber | stringaucune
Largeur du menu. Un nombre est lu en pixels ; une chaîne en longueur ou mot-clé CSS.
matchWidthbooleanfalse
Garde le menu au moins aussi large que l’ensemble du contrôle.
v-model:openbooleanfalse
État d’ouverture du menu.

Événements

ÉvénementType
click[event: MouseEvent]
L’action principale a été activée.

Slots

SlotType
default{}
Enfants VMenuItem, VMenuGroup et VMenuSeparator.

Types

Types utilisés dans les tables d’API. Importez les types exportés depuis vectis-ui.

export interface BuiltinIcon {
  name: string
  paths: readonly [string] | readonly [string, string]
}
export type IconRender =
  | { path: string; viewBox?: string }
  | { component: Component; props?: Record<string, unknown> }
  | { src: string }
  | { text: string; class?: string }
  | { class: string }
export type IconSource = string | BuiltinIcon | IconRender