Raccourci clavier : Ctrl + K
Commencer

Panneaux redimensionnables

VResizable partage un espace entre deux VResizablePanel ou plus et place une poignée entre chaque paire. Une poignée se fait glisser au pointeur, ou reçoit le focus et se déplace avec les flèches.

Utilisation

vue
Navigation
Content
<script setup lang="ts">
import { VResizable, VResizablePanel } from 'vectis-ui'
</script>

<template>
  <VResizable class="group">
    <VResizablePanel class="pane" label="Navigation" :default-size="30">Navigation</VResizablePanel>
    <VResizablePanel class="pane">Content</VResizablePanel>
  </VResizable>
</template>

<style scoped>
.group {
  block-size: 14rem;
  border: 1px solid var(--vectis-color-border);
  border-radius: var(--vectis-radius-surface);
}

.pane {
  padding: var(--vectis-space-4);
}
</style>

Exemples

Vertical

orientation="vertical" empile les panneaux. Le groupe a alors besoin d’une hauteur. grip dessine une pastille sur chaque poignée.

vue
Editor
Terminal
<script setup lang="ts">
import { VResizable, VResizablePanel } from 'vectis-ui'
</script>

<template>
  <VResizable class="group" orientation="vertical" grip>
    <VResizablePanel class="pane" label="Editor">Editor</VResizablePanel>
    <VResizablePanel class="pane" label="Terminal" :default-size="35">Terminal</VResizablePanel>
  </VResizable>
</template>

<style scoped>
.group {
  block-size: 14rem;
  border: 1px solid var(--vectis-color-border);
  border-radius: var(--vectis-radius-surface);
}

.pane {
  padding: var(--vectis-space-4);
}
</style>

Limites

minSize et maxSize acceptent un nombre en pourcentage ou une longueur CSS comme 10rem. Quand un panneau atteint son minimum, la poignée prend le reste au panneau suivant.

vue
Files: 10rem to 40%
Editor: at least 20%
Outline: at least 15%
<script setup lang="ts">
import { VResizable, VResizablePanel } from 'vectis-ui'
</script>

<template>
  <VResizable class="group">
    <VResizablePanel class="pane" label="Files" :default-size="25" min-size="10rem" max-size="40%">
      Files: 10rem to 40%
    </VResizablePanel>
    <VResizablePanel class="pane" label="Editor" :min-size="20"
      >Editor: at least 20%</VResizablePanel
    >
    <VResizablePanel class="pane" label="Outline" :default-size="25" :min-size="15">
      Outline: at least 15%
    </VResizablePanel>
  </VResizable>
</template>

<style scoped>
.group {
  block-size: 14rem;
  border: 1px solid var(--vectis-color-border);
  border-radius: var(--vectis-radius-surface);
}

.pane {
  padding: var(--vectis-space-4);
}
</style>

Panneaux repliables

Un panneau collapsible se replie quand on le tire au-delà de la moitié de son minimum, ou avec Entrée sur sa poignée, et se rouvre à sa taille précédente. v-model:collapsed suit son état. collapsedSize garde une bande, comme un rail d’icônes ; à 0, le contenu sort de la mise en page et de l’ordre de tabulation.

vue

Drag the line to the edge, or press Enter on it.

Content
<script setup lang="ts">
import { ref } from 'vue'
import { VButton, VResizable, VResizablePanel } from 'vectis-ui'

const collapsed = ref(false)
</script>

<template>
  <VResizable class="group">
    <VResizablePanel
      v-model:collapsed="collapsed"
      class="pane"
      :class="{ rail: collapsed }"
      label="Sidebar"
      :default-size="30"
      :min-size="20"
      collapsible
      collapsed-size="3.5rem"
    >
      <VButton
        size="sm"
        variant="ghost"
        :aria-label="collapsed ? 'Expand the sidebar' : 'Collapse the sidebar'"
        @click="collapsed = !collapsed"
      >
        {{ collapsed ? '»' : '«' }}
      </VButton>
      <p v-if="!collapsed">Drag the line to the edge, or press Enter on it.</p>
    </VResizablePanel>
    <VResizablePanel class="pane">Content</VResizablePanel>
  </VResizable>
</template>

<style scoped>
.group {
  block-size: 14rem;
  border: 1px solid var(--vectis-color-border);
  border-radius: var(--vectis-radius-surface);
}

.pane {
  padding: var(--vectis-space-4);
}

.rail {
  padding: var(--vectis-space-2);
}
</style>

Groupes imbriqués

Un panneau peut contenir son propre groupe. Donnez au groupe intérieur height: 100%.

vue
Files
Editor
Terminal
<script setup lang="ts">
import { VResizable, VResizablePanel } from 'vectis-ui'
</script>

<template>
  <VResizable class="group" grip>
    <VResizablePanel class="pane" label="Files" :default-size="30">Files</VResizablePanel>
    <VResizablePanel>
      <VResizable class="inner" orientation="vertical" grip>
        <VResizablePanel class="pane" label="Editor">Editor</VResizablePanel>
        <VResizablePanel class="pane" label="Terminal" :default-size="35">Terminal</VResizablePanel>
      </VResizable>
    </VResizablePanel>
  </VResizable>
</template>

<style scoped>
.group {
  block-size: 14rem;
  border: 1px solid var(--vectis-color-border);
  border-radius: var(--vectis-radius-surface);
}

.pane {
  padding: var(--vectis-space-4);
}

.inner {
  block-size: 100%;
}
</style>

Enregistrer les tailles

Le v-model contient les tailles en pourcentage et change pendant le glisser. change est émis quand elles se stabilisent : c’est le moment de les enregistrer. Pour une page rendue sur le serveur, un cookie permet au serveur d’afficher directement les tailles enregistrées.

vue
Resize, then reload the page.
Content

Sizes: 40 / 60

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { VResizable, VResizablePanel } from 'vectis-ui'

const KEY = 'docs-resizable-sizes'
const sizes = ref<number[]>([40, 60])

onMounted(() => {
  const saved = JSON.parse(localStorage.getItem(KEY) ?? 'null')
  if (Array.isArray(saved) && saved.length === 2) sizes.value = saved
})

function save(value: number[]) {
  localStorage.setItem(KEY, JSON.stringify(value))
}
</script>

<template>
  <div class="stack">
    <VResizable v-model="sizes" class="group" @change="save">
      <VResizablePanel class="pane">Resize, then reload the page.</VResizablePanel>
      <VResizablePanel class="pane">Content</VResizablePanel>
    </VResizable>
    <p class="sizes">Sizes: {{ sizes.map((size) => Math.round(size)).join(' / ') }}</p>
  </div>
</template>

<style scoped>
.group {
  block-size: 14rem;
  border: 1px solid var(--vectis-color-border);
  border-radius: var(--vectis-radius-surface);
}

.pane {
  padding: var(--vectis-space-4);
}

.stack {
  display: grid;
  gap: var(--vectis-space-3);
}

.sizes {
  margin: 0;
}
</style>

API

Props

VResizable
PropTypeDéfaut
orientationResizableOrientation'horizontal' | 'vertical''horizontal'
Panneaux côte à côte, dans le sens du texte, ou empilés.
disabledbooleanfalse
Fige les tailles. Les poignées ne se déplacent plus et ne reçoivent plus le focus.
gripbooleanfalse
Dessine une pastille au milieu de chaque poignée.
stepnumber5
Déplacement d’une poignée par touche fléchée, en pourcentage.
v-modelnumber[]aucune
Taille de chaque panneau en pourcentage de l’espace partagé, pour un total de 100. Sans liaison, les panneaux partent de leur defaultSize.
VResizablePanel
PropTypeDéfaut
indexnumber0
Position du panneau, attribuée par le groupe. Ne pas la définir.
defaultSizenumberaucune
Taille de départ en pourcentage quand le v-model n’en donne pas. Les panneaux sans taille se partagent le reste.
minSizeResizableLength0
Taille minimale : un nombre en pourcentage ou une longueur CSS.
maxSizeResizableLengthaucune
Taille maximale : un nombre en pourcentage ou une longueur CSS.
collapsiblebooleanfalse
Permet de replier le panneau en le faisant glisser ou avec Entrée sur sa poignée.
collapsedSizeResizableLength0
Taille du panneau replié, en pourcentage ou en longueur CSS. À 0, le contenu est masqué.
labelstringaucune
Nom accessible de la poignée qui redimensionne le panneau.
v-model:collapsedbooleanfalse
État replié. Le modifier replie ou rouvre le panneau.

Événements

VResizable
ÉvénementType
change[sizes: number[]]
Émet les tailles une fois stabilisées : après un glisser, une touche ou un repli.

Slots

VResizable
SlotType
default{}
Les VResizablePanel, au moins deux.
VResizablePanel
SlotType
default{}
Contenu du panneau.

Types

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

export type ResizableLength = number | string

Variables CSS

TokenValeur
--vectis-control-size-resizable-hit0.75rem
--vectis-control-size-resizable-grip-length1.5rem
--vectis-control-size-resizable-grip-thickness0.5rem