Zaidan

Command Palette

Search for a command to run...

GitHub43

Progress

Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.

Installation

CLI

Manual

Copy and paste the following code into your project.

import type { PolymorphicProps } from "@kobalte/core/polymorphic";
import {
Fill,
Label,
type ProgressFillProps,
type ProgressLabelProps,
type ProgressRootProps,
type ProgressTrackProps,
type ProgressValueLabelProps,
Root,
Track,
ValueLabel,
} from "@kobalte/core/progress";
import { type ComponentProps, splitProps, type ValidComponent } from "solid-js";
import { cn } from "~/lib/utils";
type ProgressProps<T extends ValidComponent = "div"> = PolymorphicProps<T, ProgressRootProps<T>> &
Pick<ComponentProps<T>, "class" | "children">;
const Progress = <T extends ValidComponent = "div">(props: ProgressProps<T>) => {
const [local, others] = splitProps(props as ProgressProps, ["class", "children"]);
return (
<Root
data-slot="progress"
class={cn("z-progress-root flex flex-wrap gap-3", local.class)}
{...others}
>
{local.children}
<ProgressTrack>
<ProgressIndicator />
</ProgressTrack>
</Root>
);
};
type ProgressTrackComponentProps<T extends ValidComponent = "div"> = PolymorphicProps<
T,
ProgressTrackProps<T>
> &
Pick<ComponentProps<T>, "class">;
const ProgressTrack = <T extends ValidComponent = "div">(props: ProgressTrackComponentProps<T>) => {
const [local, others] = splitProps(props as ProgressTrackComponentProps, ["class"]);
return (
<Track
data-slot="progress-track"
class={cn(
"relative z-progress-track flex w-full items-center overflow-x-hidden",
local.class,
)}
{...others}
/>
);
};
type ProgressIndicatorProps<T extends ValidComponent = "div"> = PolymorphicProps<
T,
ProgressFillProps<T>
> &
Pick<ComponentProps<T>, "class">;
const ProgressIndicator = <T extends ValidComponent = "div">(props: ProgressIndicatorProps<T>) => {
const [local, others] = splitProps(props as ProgressIndicatorProps, ["class"]);
return (
<Fill
data-slot="progress-indicator"
class={cn(
"z-progress-indicator h-full w-(--kb-progress-fill-width) transition-all",
local.class,
)}
{...others}
/>
);
};
type ProgressLabelComponentProps<T extends ValidComponent = "span"> = PolymorphicProps<
T,
ProgressLabelProps<T>
> &
Pick<ComponentProps<T>, "class">;
const ProgressLabel = <T extends ValidComponent = "span">(
props: ProgressLabelComponentProps<T>,
) => {
const [local, others] = splitProps(props as ProgressLabelComponentProps, ["class"]);
return (
<Label data-slot="progress-label" class={cn("z-progress-label", local.class)} {...others} />
);
};
type ProgressValueProps<T extends ValidComponent = "div"> = PolymorphicProps<
T,
ProgressValueLabelProps<T>
> &
Pick<ComponentProps<T>, "class">;
const ProgressValue = <T extends ValidComponent = "div">(props: ProgressValueProps<T>) => {
const [local, others] = splitProps(props as ProgressValueProps, ["class"]);
return (
<ValueLabel
data-slot="progress-value"
class={cn("z-progress-value", local.class)}
{...others}
/>
);
};
export { Progress, ProgressTrack, ProgressIndicator, ProgressLabel, ProgressValue };

With Label

import {
Progress,
ProgressLabel,
ProgressValue,
} from "~/components/ui/progress";
<Progress value={75}>
<div class="flex w-full justify-between">
<ProgressLabel>Loading...</ProgressLabel>
<ProgressValue />
</div>
</Progress>

Indeterminate

Use the indeterminate prop to show an indeterminate progress state.

<Progress indeterminate>
<ProgressLabel>Processing...</ProgressLabel>
</Progress>

Custom Value Range

Use minValue and maxValue to set custom value ranges.

<Progress value={5} minValue={0} maxValue={10}>
<div class="flex w-full justify-between">
<ProgressLabel>5 of 10 tasks completed</ProgressLabel>
<ProgressValue />
</div>
</Progress>

Examples

Here are the source code of all the examples from the preview page:

Progress Bar

import { Progress } from "~/components/ui/progress";
function ProgressValues() {
return (
<Example title="Progress Bar">
<div class="flex w-full flex-col gap-4">
<Progress value={0} />
<Progress value={25} class="w-full" />
<Progress value={50} />
<Progress value={75} />
<Progress value={100} />
</div>
</Example>
);
}

With Label

import { Progress, ProgressLabel, ProgressValue } from "~/components/ui/progress";
function ProgressWithLabel() {
return (
<Example title="With Label">
<Progress value={56}>
<ProgressLabel>Upload progress</ProgressLabel>
<ProgressValue />
</Progress>
</Example>
);
}

Controlled

import { createSignal } from "solid-js";
import { Progress } from "~/components/ui/progress";
import { Slider } from "~/components/ui/slider";
function ProgressControlled() {
const [value, setValue] = createSignal(50);
return (
<Example title="Controlled">
<div class="flex w-full flex-col gap-4">
<Progress value={value()} class="w-full" />
<Slider
value={[value()]}
onChange={(values) => setValue(values[0])}
minValue={0}
maxValue={100}
step={1}
/>
</div>
</Example>
);
}

File Upload List

import { FileIcon } from "lucide-solid";
import { For } from "solid-js";
import {
Item,
ItemActions,
ItemContent,
ItemGroup,
ItemMedia,
ItemTitle,
} from "~/components/ui/item";
import { Progress } from "~/components/ui/progress";
function FileUploadList() {
const files = [
{
id: "1",
name: "document.pdf",
progress: 45,
timeRemaining: "2m 30s",
},
{
id: "2",
name: "presentation.pptx",
progress: 78,
timeRemaining: "45s",
},
{
id: "3",
name: "spreadsheet.xlsx",
progress: 12,
timeRemaining: "5m 12s",
},
{
id: "4",
name: "image.jpg",
progress: 100,
timeRemaining: "Complete",
},
];
return (
<Example title="File Upload List">
<ItemGroup>
<For each={files}>
{(file) => (
<Item size="xs" class="px-0">
<ItemMedia variant="icon">
<FileIcon class="size-5" />
</ItemMedia>
<ItemContent class="inline-block truncate">
<ItemTitle class="inline">{file.name}</ItemTitle>
</ItemContent>
<ItemContent>
<Progress value={file.progress} class="w-32" />
</ItemContent>
<ItemActions class="w-16 justify-end">
<span class="text-muted-foreground text-sm">{file.timeRemaining}</span>
</ItemActions>
</Item>
)}
</For>
</ItemGroup>
</Example>
);
}