v2.12.0

ProgressGroup New

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.

  • System19%
  • Apps6%
  • Documents9%
  • Multimedia33%
<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>
<script setup lang="ts">
import { ref } from 'vue'
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 }
  • Compute42%
  • Storage18%
  • Bandwidth9%
<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>
<script setup lang="ts">
import { ref } from 'vue'
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>
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.

  • System19%
  • Apps6%
<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>
<script setup lang="ts">
import { ref } from 'vue'
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>
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.

25%
  • System19%
  • Apps6%
<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>
<script setup lang="ts">
import { ref } from 'vue'
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>
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.

  • System19%
  • Apps6%
<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>
<script setup lang="ts">
import { ref } from 'vue'
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.

  • System19%
  • Apps6%
<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>
<script setup lang="ts">
import { ref } from 'vue'
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.

  • System19%
  • Apps6%
<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>
<script setup lang="ts">
import { ref } from 'vue'
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.

86GB used

42GB remaining

  • System19%
  • Apps6%
  • Documents9%
  • Multimedia33%
<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.

  • System24GB
  • Apps8GB
  • Documents12GB
  • Multimedia42GB
<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

Prop Default Type
as'div'any

The element or component this component should render as.

items T[]
max100 number

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

statusboolean

Display the summed progress value.

size'md' "xs" | "sm" | "md" | "lg"
color'air-primary'"air-primary" | "air-primary-success" | "air-primary-alert" | "air-primary-warning" | "air-primary-copilot" | "air-secondary"
orientation'horizontal' "horizontal" | "vertical"

The orientation of the progress bar.

b24ui { 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; }

Theme

https://github.com/bitrix24/b24ui/tree/main/src/theme/progress-group.ts
export default {
  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