Progresseur New

GitHub à
Une barre de progression divisée en plusieurs segments qui s'additionnent pour un total.

Utilisation

Utilisez le composant ProgressGroup pour afficher plusieurs valeurs sous forme de segments d'une seule barre de progression.

  • System19%
  • Apps6%
  • Documents9%
  • Multimedia33%
<script setup lang="ts">
import type { ProgressGroupItem } from '@nuxt/ui'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'System',
    value: 24,
    color: 'neutral',
    icon: 'i-lucide-cog'
  },
  {
    label: 'Apps',
    value: 8,
    color: 'error',
    icon: 'i-lucide-app-window'
  },
  {
    label: 'Documents',
    value: 12,
    color: 'warning',
    icon: 'i-lucide-file'
  },
  {
    label: 'Multimedia',
    value: 42,
    color: 'success',
    icon: 'i-lucide-film'
  }
])
</script>

<template>
  <UProgressGroup :max="128" :items="items" class="w-96" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ProgressGroupItem } from '@nuxt/ui'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'System',
    value: 24,
    color: 'neutral',
    icon: 'i-lucide-cog'
  },
  {
    label: 'Apps',
    value: 8,
    color: 'error',
    icon: 'i-lucide-app-window'
  },
  {
    label: 'Documents',
    value: 12,
    color: 'warning',
    icon: 'i-lucide-file'
  },
  {
    label: 'Multimedia',
    value: 42,
    color: 'success',
    icon: 'i-lucide-film'
  }
])
</script>

<template>
  <UProgressGroup :max="128" :items="items" class="w-96" />
</template>

éléments

Utilisez le prop items comme un tableau d'objets avec les propriétés suivantes:

  • Compute42%
  • Storage18%
  • Bandwidth9%
<script setup lang="ts">
import type { ProgressGroupItem } from '@nuxt/ui'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'Compute',
    value: 42,
    color: 'primary'
  },
  {
    label: 'Storage',
    value: 18,
    color: 'info'
  },
  {
    label: 'Bandwidth',
    value: 9,
    color: 'warning'
  }
])
</script>

<template>
  <UProgressGroup :items="items" class="w-96" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ProgressGroupItem } from '@nuxt/ui'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'Compute',
    value: 42,
    color: 'primary'
  },
  {
    label: 'Storage',
    value: 18,
    color: 'info'
  },
  {
    label: 'Bandwidth',
    value: 9,
    color: 'warning'
  }
])
</script>

<template>
  <UProgressGroup :items="items" class="w-96" />
</template>
Les éléments sans icon obtiennent un point coloré dans la liste à la place.

max

Utilisez la prop max pour définir la valeur à laquelle tous les éléments s'ajoutent. Defaults à 100.

  • Used25%
  • Reserved13%
<script setup lang="ts">
import type { ProgressGroupItem } from '@nuxt/ui'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'Used',
    value: 128,
    color: 'primary'
  },
  {
    label: 'Reserved',
    value: 64,
    color: 'neutral'
  }
])
</script>

<template>
  <UProgressGroup :max="512" :items="items" class="w-96" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ProgressGroupItem } from '@nuxt/ui'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'Used',
    value: 128,
    color: 'primary'
  },
  {
    label: 'Reserved',
    value: 64,
    color: 'neutral'
  }
])
</script>

<template>
  <UProgressGroup :max="512" :items="items" class="w-96" />
</template>
Les valeurs sont fixées entre 0 et max, et les segments qui s'additionnent à plus de max partagent la piste proportionnellement.

statut

Utilisez le prop status pour afficher la valeur additionnée au-dessus de la barre.

58%
  • System19%
  • Apps6%
  • Multimedia33%
<script setup lang="ts">
import type { ProgressGroupItem } from '@nuxt/ui'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'System',
    value: 24,
    color: 'neutral'
  },
  {
    label: 'Apps',
    value: 8,
    color: 'error'
  },
  {
    label: 'Multimedia',
    value: 42,
    color: 'success'
  }
])
</script>

<template>
  <UProgressGroup status :max="128" :items="items" class="w-96" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ProgressGroupItem } from '@nuxt/ui'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'System',
    value: 24,
    color: 'neutral'
  },
  {
    label: 'Apps',
    value: 8,
    color: 'error'
  },
  {
    label: 'Multimedia',
    value: 42,
    color: 'success'
  }
])
</script>

<template>
  <UProgressGroup status :max="128" :items="items" class="w-96" />
</template>
Le statut suit la fin de la barre, utilisez :ui="{ status: 'w-full' }" pour le faire couvrir toute la largeur à la place.

Couleur

Utilisez le prop color pour changer la couleur de chaque segment qui ne se définit pas.

  • Read42%
  • Write18%
<script setup lang="ts">
import type { ProgressGroupItem } from '@nuxt/ui'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'Read',
    value: 42
  },
  {
    label: 'Write',
    value: 18
  }
])
</script>

<template>
  <UProgressGroup color="neutral" :items="items" class="w-96" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ProgressGroupItem } from '@nuxt/ui'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'Read',
    value: 42
  },
  {
    label: 'Write',
    value: 18
  }
])
</script>

<template>
  <UProgressGroup color="neutral" :items="items" class="w-96" />
</template>
Cet accessoire et le color de chaque élément acceptent toutes les valeurs de couleur CSS, ce qui est pratique pour les palettes en dehors du thème.

Size électrique

Utilisez la prop size pour modifier la taille du ProgressGroup.

  • Read42%
  • Write18%
<script setup lang="ts">
import type { ProgressGroupItem } from '@nuxt/ui'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'Read',
    value: 42,
    color: 'primary'
  },
  {
    label: 'Write',
    value: 18,
    color: 'info'
  }
])
</script>

<template>
  <UProgressGroup size="xl" :items="items" class="w-96" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ProgressGroupItem } from '@nuxt/ui'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'Read',
    value: 42,
    color: 'primary'
  },
  {
    label: 'Write',
    value: 18,
    color: 'info'
  }
])
</script>

<template>
  <UProgressGroup size="xl" :items="items" class="w-96" />
</template>

Orientation

Utilisez la prop orientation pour modifier l'orientation du groupe ProgressGroup. Defaults à horizontal.

  • Read42%
  • Write18%
<script setup lang="ts">
import type { ProgressGroupItem } from '@nuxt/ui'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'Read',
    value: 42,
    color: 'primary'
  },
  {
    label: 'Write',
    value: 18,
    color: 'info'
  }
])
</script>

<template>
  <UProgressGroup orientation="vertical" :items="items" class="h-48" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ProgressGroupItem } from '@nuxt/ui'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'Read',
    value: 42,
    color: 'primary'
  },
  {
    label: 'Write',
    value: 18,
    color: 'info'
  }
])
</script>

<template>
  <UProgressGroup orientation="vertical" :items="items" class="h-48" />
</template>

exemples

With slot d'état

Utilisez l'emplacement #status pour remplacer le pourcentage additionné par votre propre contenu.

86GB used

42GB remaining

  • System19%
  • Apps6%
  • Documents9%
  • Multimedia33%
<script setup lang="ts">
import type { ProgressGroupItem } from '@nuxt/ui'

const max = 128

const items: ProgressGroupItem[] = [
  { label: 'System', value: 24, color: 'neutral', icon: 'i-lucide-cog' },
  { label: 'Apps', value: 8, color: 'error', icon: 'i-lucide-app-window' },
  { label: 'Documents', value: 12, color: 'warning', icon: 'i-lucide-file' },
  { label: 'Multimedia', value: 42, color: 'success', icon: 'i-lucide-film' }
]

const used = items.reduce((total, item) => total + (item.value ?? 0), 0)
</script>

<template>
  <UProgressGroup :items="items" :max="max" status class="w-96" :ui="{ status: 'w-full justify-between' }">
    <template #status>
      <p>{{ used }}GB used</p>
      <p class="text-muted">
        {{ max - used }}GB remaining
      </p>
    </template>
  </UProgressGroup>
</template>

Avec slots d'éléments

Utilisez les emplacements #item-label et #item-trailing pour modifier ce que chaque entrée affiche. Les deux reçoivent le item, son index et son percent.

  • System24GB
  • Apps8GB
  • Documents12GB
  • Multimedia42GB
<script setup lang="ts">
import type { ProgressGroupItem } from '@nuxt/ui'

const items: ProgressGroupItem[] = [
  { label: 'System', value: 24, color: 'neutral' },
  { label: 'Apps', value: 8, color: 'error' },
  { label: 'Documents', value: 12, color: 'warning' },
  { label: 'Multimedia', value: 42, color: 'success' }
]
</script>

<template>
  <UProgressGroup :items="items" :max="128" class="w-96">
    <template #item-label="{ item }">
      <span class="font-medium">{{ item.label }}</span>
    </template>

    <template #item-trailing="{ item }">
      {{ item.value }}GB
    </template>
  </UProgressGroup>
</template>

With couleurs personnalisées

Donnez à chaque élément une couleur CSS pour créer une ventilation en dehors de la palette de thèmes.

70% Full

~89.7K / 128K Tokens

  • System prompt4.2K
  • Tool definitions18.4K
  • Rules12.8K
  • Skills7.1K
  • MCP & dynamic tools17.1K
  • Subagent definitions5.5K
  • Conversation24.6K
<script setup lang="ts">
import type { ProgressGroupItem } from '@nuxt/ui'

const max = 128

const items: ProgressGroupItem[] = [
  { label: 'System prompt', value: 4.2, color: 'var(--color-neutral-400)' },
  { label: 'Tool definitions', value: 18.4, color: 'var(--color-violet-400)' },
  { label: 'Rules', value: 12.8, color: 'var(--color-green-400)' },
  { label: 'Skills', value: 7.1, color: 'var(--color-amber-400)' },
  { label: 'MCP & dynamic tools', value: 17.1, color: 'var(--color-rose-400)' },
  { label: 'Subagent definitions', value: 5.5, color: 'var(--color-sky-400)' },
  { label: 'Conversation', value: 24.6, color: 'var(--color-orange-400)' }
]

const used = items.reduce((total, item) => total + (item.value ?? 0), 0)
</script>

<template>
  <UProgressGroup :items="items" :max="max" status class="w-96" :ui="{ status: 'w-full justify-between' }">
    <template #status="{ percent }">
      <p>{{ percent }}% Full</p>
      <p class="text-muted">
        ~{{ used.toFixed(1) }}K / {{ max }}K Tokens
      </p>
    </template>

    <template #item-trailing="{ item }">
      {{ item.value }}K
    </template>
  </UProgressGroup>
</template>

API

Props équipements

Prop Default Type
as
'div'
any

The element or component this component should render as.

items
T[]
max
100
number

The value all items add up to, used to compute each segment's share of the track.

status
boolean

Display the summed progress value.

size
'md'
"2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
color
'primary'
"primary" | "secondary" | "success" | "info" | "warning" | "error" | "neutral" | string

Any theme color, or any CSS color value for palettes outside the theme.

orientation
'horizontal'
"horizontal" | "vertical"

The orientation of the progress bar.

ui
{ root?: SlotClass; base?: SlotClass; segment?: SlotClass; indicator?: SlotClass; status?: SlotClass; list?: SlotClass; item?: SlotClass; itemLeadingIcon?: SlotClass; itemLeadingDot?: SlotClass; itemLabel?: SlotClass; itemTrailing?: SlotClass; }

Slots

Slot Type
status
{ percent: number; }
item
{ item: T; index: number; percent: number; }
item-leading
{ item: T; index: number; percent: number; }
item-label
{ item: T; index: number; percent: number; }
item-trailing
{ item: T; index: number; percent: number; }

Thème

app.config.ts
export default defineAppConfig({
  ui: {
    progressGroup: {
      slots: {
        root: 'gap-2',
        base: 'flex overflow-hidden rounded-full bg-accented',
        segment: 'duration-200 ease-out motion-reduce:transition-none',
        indicator: 'size-full',
        status: 'flex text-dimmed duration-200 ease-out motion-reduce:transition-none',
        list: 'flex flex-col gap-1',
        item: 'flex items-center gap-1.5 min-w-0',
        itemLeadingIcon: 'shrink-0',
        itemLeadingDot: 'shrink-0 rounded-full',
        itemLabel: 'truncate',
        itemTrailing: 'ms-auto shrink-0 text-dimmed'
      },
      variants: {
        color: {
          primary: {
            indicator: 'bg-primary',
            itemLeadingIcon: 'text-primary',
            itemLeadingDot: 'bg-primary'
          },
          secondary: {
            indicator: 'bg-secondary',
            itemLeadingIcon: 'text-secondary',
            itemLeadingDot: 'bg-secondary'
          },
          success: {
            indicator: 'bg-success',
            itemLeadingIcon: 'text-success',
            itemLeadingDot: 'bg-success'
          },
          info: {
            indicator: 'bg-info',
            itemLeadingIcon: 'text-info',
            itemLeadingDot: 'bg-info'
          },
          warning: {
            indicator: 'bg-warning',
            itemLeadingIcon: 'text-warning',
            itemLeadingDot: 'bg-warning'
          },
          error: {
            indicator: 'bg-error',
            itemLeadingIcon: 'text-error',
            itemLeadingDot: 'bg-error'
          },
          neutral: {
            indicator: 'bg-inverted',
            itemLeadingIcon: 'text-highlighted',
            itemLeadingDot: 'bg-inverted'
          }
        },
        size: {
          '2xs': {
            status: 'text-xs',
            list: 'text-xs',
            itemLeadingIcon: 'size-3',
            itemLeadingDot: 'size-1.5'
          },
          xs: {
            status: 'text-xs',
            list: 'text-xs',
            itemLeadingIcon: 'size-3',
            itemLeadingDot: 'size-1.5'
          },
          sm: {
            status: 'text-sm',
            list: 'text-sm',
            itemLeadingIcon: 'size-4',
            itemLeadingDot: 'size-2'
          },
          md: {
            status: 'text-sm',
            list: 'text-sm',
            itemLeadingIcon: 'size-4',
            itemLeadingDot: 'size-2'
          },
          lg: {
            status: 'text-sm',
            list: 'text-sm',
            itemLeadingIcon: 'size-4',
            itemLeadingDot: 'size-2'
          },
          xl: {
            status: 'text-base',
            list: 'text-base',
            itemLeadingIcon: 'size-5',
            itemLeadingDot: 'size-2.5'
          },
          '2xl': {
            status: 'text-base',
            list: 'text-base',
            itemLeadingIcon: 'size-5',
            itemLeadingDot: 'size-2.5'
          }
        },
        orientation: {
          horizontal: {
            root: 'w-full flex flex-col',
            base: 'w-full flex-row',
            segment: 'h-full transition-[width]',
            status: 'flex-row items-center justify-end w-(--percent) min-w-fit transition-[width]'
          },
          vertical: {
            root: 'h-full flex flex-row',
            base: 'h-full flex-col',
            segment: 'w-full transition-[height]',
            status: 'flex-col justify-end h-(--percent) min-h-fit transition-[height]'
          }
        }
      },
      compoundVariants: [
        {
          orientation: 'horizontal',
          size: '2xs',
          class: 'h-px'
        },
        {
          orientation: 'horizontal',
          size: 'xs',
          class: 'h-0.5'
        },
        {
          orientation: 'horizontal',
          size: 'sm',
          class: 'h-1'
        },
        {
          orientation: 'horizontal',
          size: 'md',
          class: 'h-2'
        },
        {
          orientation: 'horizontal',
          size: 'lg',
          class: 'h-3'
        },
        {
          orientation: 'horizontal',
          size: 'xl',
          class: 'h-4'
        },
        {
          orientation: 'horizontal',
          size: '2xl',
          class: 'h-5'
        },
        {
          orientation: 'vertical',
          size: '2xs',
          class: 'w-px'
        },
        {
          orientation: 'vertical',
          size: 'xs',
          class: 'w-0.5'
        },
        {
          orientation: 'vertical',
          size: 'sm',
          class: 'w-1'
        },
        {
          orientation: 'vertical',
          size: 'md',
          class: 'w-2'
        },
        {
          orientation: 'vertical',
          size: 'lg',
          class: 'w-3'
        },
        {
          orientation: 'vertical',
          size: 'xl',
          class: 'w-4'
        },
        {
          orientation: 'vertical',
          size: '2xl',
          class: 'w-5'
        }
      ],
      defaultVariants: {
        color: 'primary',
        size: 'md'
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        progressGroup: {
          slots: {
            root: 'gap-2',
            base: 'flex overflow-hidden rounded-full bg-accented',
            segment: 'duration-200 ease-out motion-reduce:transition-none',
            indicator: 'size-full',
            status: 'flex text-dimmed duration-200 ease-out motion-reduce:transition-none',
            list: 'flex flex-col gap-1',
            item: 'flex items-center gap-1.5 min-w-0',
            itemLeadingIcon: 'shrink-0',
            itemLeadingDot: 'shrink-0 rounded-full',
            itemLabel: 'truncate',
            itemTrailing: 'ms-auto shrink-0 text-dimmed'
          },
          variants: {
            color: {
              primary: {
                indicator: 'bg-primary',
                itemLeadingIcon: 'text-primary',
                itemLeadingDot: 'bg-primary'
              },
              secondary: {
                indicator: 'bg-secondary',
                itemLeadingIcon: 'text-secondary',
                itemLeadingDot: 'bg-secondary'
              },
              success: {
                indicator: 'bg-success',
                itemLeadingIcon: 'text-success',
                itemLeadingDot: 'bg-success'
              },
              info: {
                indicator: 'bg-info',
                itemLeadingIcon: 'text-info',
                itemLeadingDot: 'bg-info'
              },
              warning: {
                indicator: 'bg-warning',
                itemLeadingIcon: 'text-warning',
                itemLeadingDot: 'bg-warning'
              },
              error: {
                indicator: 'bg-error',
                itemLeadingIcon: 'text-error',
                itemLeadingDot: 'bg-error'
              },
              neutral: {
                indicator: 'bg-inverted',
                itemLeadingIcon: 'text-highlighted',
                itemLeadingDot: 'bg-inverted'
              }
            },
            size: {
              '2xs': {
                status: 'text-xs',
                list: 'text-xs',
                itemLeadingIcon: 'size-3',
                itemLeadingDot: 'size-1.5'
              },
              xs: {
                status: 'text-xs',
                list: 'text-xs',
                itemLeadingIcon: 'size-3',
                itemLeadingDot: 'size-1.5'
              },
              sm: {
                status: 'text-sm',
                list: 'text-sm',
                itemLeadingIcon: 'size-4',
                itemLeadingDot: 'size-2'
              },
              md: {
                status: 'text-sm',
                list: 'text-sm',
                itemLeadingIcon: 'size-4',
                itemLeadingDot: 'size-2'
              },
              lg: {
                status: 'text-sm',
                list: 'text-sm',
                itemLeadingIcon: 'size-4',
                itemLeadingDot: 'size-2'
              },
              xl: {
                status: 'text-base',
                list: 'text-base',
                itemLeadingIcon: 'size-5',
                itemLeadingDot: 'size-2.5'
              },
              '2xl': {
                status: 'text-base',
                list: 'text-base',
                itemLeadingIcon: 'size-5',
                itemLeadingDot: 'size-2.5'
              }
            },
            orientation: {
              horizontal: {
                root: 'w-full flex flex-col',
                base: 'w-full flex-row',
                segment: 'h-full transition-[width]',
                status: 'flex-row items-center justify-end w-(--percent) min-w-fit transition-[width]'
              },
              vertical: {
                root: 'h-full flex flex-row',
                base: 'h-full flex-col',
                segment: 'w-full transition-[height]',
                status: 'flex-col justify-end h-(--percent) min-h-fit transition-[height]'
              }
            }
          },
          compoundVariants: [
            {
              orientation: 'horizontal',
              size: '2xs',
              class: 'h-px'
            },
            {
              orientation: 'horizontal',
              size: 'xs',
              class: 'h-0.5'
            },
            {
              orientation: 'horizontal',
              size: 'sm',
              class: 'h-1'
            },
            {
              orientation: 'horizontal',
              size: 'md',
              class: 'h-2'
            },
            {
              orientation: 'horizontal',
              size: 'lg',
              class: 'h-3'
            },
            {
              orientation: 'horizontal',
              size: 'xl',
              class: 'h-4'
            },
            {
              orientation: 'horizontal',
              size: '2xl',
              class: 'h-5'
            },
            {
              orientation: 'vertical',
              size: '2xs',
              class: 'w-px'
            },
            {
              orientation: 'vertical',
              size: 'xs',
              class: 'w-0.5'
            },
            {
              orientation: 'vertical',
              size: 'sm',
              class: 'w-1'
            },
            {
              orientation: 'vertical',
              size: 'md',
              class: 'w-2'
            },
            {
              orientation: 'vertical',
              size: 'lg',
              class: 'w-3'
            },
            {
              orientation: 'vertical',
              size: 'xl',
              class: 'w-4'
            },
            {
              orientation: 'vertical',
              size: '2xl',
              class: 'w-5'
            }
          ],
          defaultVariants: {
            color: 'primary',
            size: 'md'
          }
        }
      }
    })
  ]
})

Changelog

No recent changes