---
title: "ProgressGroup"
description: "One progress bar carrying several values at once, each drawn as its own coloured part."
canonical_url: "https://bitrix24.github.io/b24ui/docs/components/progress-group"
---
# ProgressGroup

> One progress bar carrying several values at once, each drawn as its own coloured part.

## Usage

Use the ProgressGroup component to display multiple values as segments of a single progress bar.

```vue
<script setup lang="ts">
import type { ProgressGroupItem } from '@bitrix24/b24ui-nuxt'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'System',
    value: 24,
    color: 'air-secondary'
  },
  {
    label: 'Apps',
    value: 8,
    color: 'air-primary-alert'
  },
  {
    label: 'Documents',
    value: 12,
    color: 'air-primary-warning'
  },
  {
    label: 'Multimedia',
    value: 42,
    color: 'air-primary-success'
  }
])
</script>

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

### Items

Use the `items` prop as an array of objects with the following properties:

- `label?: string`
- `icon?: IconComponent`
- `value?: number`
- `color?: "air-primary" | "air-primary-success" | "air-primary-alert" | "air-primary-copilot" | "air-primary-warning" | "air-secondary"`
- `slot?: string`
- `class?: any`
- `b24ui?: { segment?: ClassNameValue, indicator?: ClassNameValue, item?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingDot?: ClassNameValue, itemLabel?: ClassNameValue, itemTrailing?: ClassNameValue }`

```vue
<script setup lang="ts">
import type { ProgressGroupItem } from '@bitrix24/b24ui-nuxt'

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

<template>
  <B24ProgressGroup :items="items" class="w-96" />
</template>
```

> [!NOTE]
> Items without an `icon` get a coloured dot in the list instead.

### Max

Use the `max` prop to set the value all items add up to. Defaults to `100`.

```vue
<script setup lang="ts">
import type { ProgressGroupItem } from '@bitrix24/b24ui-nuxt'

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

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

> [!NOTE]
> A `max` that is not a positive number falls back to `100`, so the segments keep their proportions instead of collapsing.

### Status

Use the `status` prop to display the summed progress value.

```vue
<script setup lang="ts">
import type { ProgressGroupItem } from '@bitrix24/b24ui-nuxt'

const items = ref<ProgressGroupItem[]>([
  {
    label: 'System',
    value: 24,
    color: 'air-secondary'
  },
  {
    label: 'Apps',
    value: 8,
    color: 'air-primary-alert'
  }
])
</script>

<template>
  <B24ProgressGroup :max="128" status :items="items" class="w-96" />
</template>
```

> [!TIP]
> The status tracks the end of the bar, use `:b24ui="{ status: 'w-full' }"` to make it span the full width instead.

### Color

Use the `color` prop to set the colour every item falls back to.

```vue
<script setup lang="ts">
import type { ProgressGroupItem } from '@bitrix24/b24ui-nuxt'

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

<template>
  <B24ProgressGroup color="air-secondary" :max="128" :items="items" class="w-96" />
</template>
```

### Size

Use the `size` prop to change the thickness of the bar.

```vue
<script setup lang="ts">
import type { ProgressGroupItem } from '@bitrix24/b24ui-nuxt'

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

<template>
  <B24ProgressGroup size="lg" :max="128" :items="items" class="w-96" />
</template>
```

### Orientation

Use the `orientation` prop to change the direction of the bar. Defaults to `horizontal`.

```vue
<script setup lang="ts">
import type { ProgressGroupItem } from '@bitrix24/b24ui-nuxt'

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

<template>
  <B24ProgressGroup orientation="vertical" :max="128" :items="items" class="h-96" />
</template>
```

## Examples

### With status slot

Use the `status` slot to replace the summed value with your own content.

```vue [ProgressGroupStatusExample.vue]
<script setup lang="ts">
import type { ProgressGroupItem } from '@bitrix24/b24ui-nuxt'
import SettingsIcon from '@bitrix24/b24icons-vue/main/SettingsIcon'
import AppsIcon from '@bitrix24/b24icons-vue/outline/AppsIcon'
import FileIcon from '@bitrix24/b24icons-vue/main/FileIcon'
import PlayCircleIcon from '@bitrix24/b24icons-vue/main/PlayCircleIcon'

const max = 128

const items: ProgressGroupItem[] = [
  { label: 'System', value: 24, color: 'air-secondary', icon: SettingsIcon },
  { label: 'Apps', value: 8, color: 'air-primary-alert', icon: AppsIcon },
  { label: 'Documents', value: 12, color: 'air-primary-warning', icon: FileIcon },
  { label: 'Multimedia', value: 42, color: 'air-primary-success', icon: PlayCircleIcon }
]

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

<template>
  <B24ProgressGroup :items="items" :max="max" status class="w-96" :b24ui="{ status: 'w-full justify-between' }">
    <template #status>
      <p>{{ used }}GB used</p>
      <p class="text-description">
        {{ max - used }}GB remaining
      </p>
    </template>
  </B24ProgressGroup>
</template>
```

### With item slots

Use the `item-label` and `item-trailing` slots to change what the legend shows for every item.

```vue [ProgressGroupItemExample.vue]
<script setup lang="ts">
import type { ProgressGroupItem } from '@bitrix24/b24ui-nuxt'

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

<template>
  <B24ProgressGroup :items="items" :max="128" class="w-96">
    <template #item-label="{ item }">
      <span class="font-(--ui-font-weight-medium)">{{ item.label }}</span>
    </template>

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

## API

### Props

```ts
/**
 * Props for the ProgressGroup component
 */
interface ProgressGroupProps {
  /**
   * The element or component this component should render as.
   * @default 'div'
   */
  as?: any;
  items?: T[] | undefined;
  /**
   * The value all items add up to, used to compute each segment's share of the track.
   * @default 100
   */
  max?: number | undefined;
  /**
   * Display the summed progress value.
   */
  status?: boolean | undefined;
  /**
   * @default 'md'
   */
  size?: "xs" | "sm" | "md" | "lg" | undefined;
  /**
   * @default 'air-primary'
   */
  color?: "air-primary" | "air-primary-success" | "air-primary-alert" | "air-primary-warning" | "air-primary-copilot" | "air-secondary";
  /**
   * The orientation of the progress bar.
   * @default 'horizontal'
   */
  orientation?: "horizontal" | "vertical" | undefined;
  b24ui?: { root?: SlotClass; base?: SlotClass; segment?: SlotClass; indicator?: SlotClass; status?: SlotClass; list?: SlotClass; item?: SlotClass; itemLeadingIcon?: SlotClass; itemLeadingDot?: SlotClass; itemLabel?: SlotClass; itemTrailing?: SlotClass; } | undefined;
}
```

### Slots

```ts
/**
 * Slots for the ProgressGroup component
 */
interface ProgressGroupSlots {
  status(): any;
  item(): any;
  item-leading(): any;
  item-label(): any;
  item-trailing(): any;
}
```

## Theme

```ts [app.config.ts]
export default defineAppConfig({
  b24ui: {
    progressGroup: {
      slots: {
        root: 'gap-2',
        base: 'flex overflow-hidden rounded-(--ui-border-radius-pill) bg-(--ui-color-base-5)',
        segment: 'duration-200 ease-out motion-reduce:transition-none',
        indicator: 'size-full bg-(--b24ui-background)',
        status: 'flex justify-end text-legend 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-(--ui-border-radius-pill)',
        itemLabel: 'truncate text-label',
        itemTrailing: 'ms-auto shrink-0 text-legend'
      },
      variants: {
        color: {
          'air-primary': {
            segment: 'style-filled',
            itemLeadingIcon: 'style-filled text-(--b24ui-background)',
            itemLeadingDot: 'style-filled bg-(--b24ui-background)'
          },
          'air-primary-success': {
            segment: 'style-filled-success',
            itemLeadingIcon: 'style-filled-success text-(--b24ui-background)',
            itemLeadingDot: 'style-filled-success bg-(--b24ui-background)'
          },
          'air-primary-alert': {
            segment: 'style-filled-alert',
            itemLeadingIcon: 'style-filled-alert text-(--b24ui-background)',
            itemLeadingDot: 'style-filled-alert bg-(--b24ui-background)'
          },
          'air-primary-copilot': {
            segment: 'style-filled-copilot',
            itemLeadingIcon: 'style-filled-copilot text-(--b24ui-background)',
            itemLeadingDot: 'style-filled-copilot bg-(--b24ui-background)'
          },
          'air-primary-warning': {
            segment: 'style-filled-warning',
            itemLeadingIcon: 'style-filled-warning text-(--b24ui-background)',
            itemLeadingDot: 'style-filled-warning bg-(--b24ui-background)'
          },
          'air-secondary': {
            segment: 'style-tinted',
            itemLeadingIcon: 'style-tinted text-(--b24ui-background)',
            itemLeadingDot: 'style-tinted bg-(--b24ui-background)'
          }
        },
        size: {
          xs: {
            status: 'text-(length:--ui-font-size-xs)/(--ui-font-line-height-sm)',
            list: 'text-(length:--ui-font-size-xs)/(--ui-font-line-height-sm)',
            itemLeadingIcon: 'size-3',
            itemLeadingDot: 'size-1.5'
          },
          sm: {
            status: 'text-(length:--ui-font-size-sm)/(--ui-font-line-height-sm)',
            list: 'text-(length:--ui-font-size-sm)/(--ui-font-line-height-sm)',
            itemLeadingIcon: 'size-4',
            itemLeadingDot: 'size-2'
          },
          md: {
            status: 'text-(length:--ui-font-size-sm)/(--ui-font-line-height-sm)',
            list: 'text-(length:--ui-font-size-sm)/(--ui-font-line-height-sm)',
            itemLeadingIcon: 'size-4',
            itemLeadingDot: 'size-2'
          },
          lg: {
            status: 'text-(length:--ui-font-size-sm)/(--ui-font-line-height-sm)',
            list: 'text-(length:--ui-font-size-sm)/(--ui-font-line-height-sm)',
            itemLeadingIcon: 'size-5',
            itemLeadingDot: 'size-2.5'
          }
        },
        orientation: {
          horizontal: {
            root: 'w-full flex flex-col',
            base: 'w-full flex-row',
            status: 'flex-row w-(--percent) transition-[width]'
          },
          vertical: {
            root: 'h-full flex flex-row-reverse',
            base: 'h-full flex-col',
            status: 'flex-col min-w-[32px] h-(--percent) transition-[height]'
          }
        }
      },
      compoundVariants: [
        {
          orientation: 'horizontal',
          size: 'xs',
          class: {
            base: 'h-[2px]'
          }
        },
        {
          orientation: 'horizontal',
          size: 'sm',
          class: {
            base: 'h-[4px]'
          }
        },
        {
          orientation: 'horizontal',
          size: 'md',
          class: {
            base: 'h-2'
          }
        },
        {
          orientation: 'horizontal',
          size: 'lg',
          class: {
            base: 'h-[12px]'
          }
        },
        {
          orientation: 'vertical',
          size: 'xs',
          class: {
            base: 'w-[2px]'
          }
        },
        {
          orientation: 'vertical',
          size: 'sm',
          class: {
            base: 'w-[4px]'
          }
        },
        {
          orientation: 'vertical',
          size: 'md',
          class: {
            base: 'w-2'
          }
        },
        {
          orientation: 'vertical',
          size: 'lg',
          class: {
            base: 'w-[12px]'
          }
        }
      ],
      defaultVariants: {
        color: 'air-primary',
        size: 'md'
      }
    }
  }
})
```

## Changelog

<component-changelog>

</component-changelog>

## Sitemap

See the full [sitemap](/b24ui/sitemap.md) for all pages.
