Progress
A progress bar used to show the completion status of an ongoing operation.
DocsLoading
65%
import { Progress, ProgressLabel, ProgressTrack, ProgressValueText } from "~/components/progress";
export default function ProgressBasicDemo() {
return (
<Progress value={65} class="space-y-2">
<ProgressLabel>Loading</ProgressLabel>
<ProgressTrack />
<ProgressValueText />
</Progress>
);
}Installation
CLI
Run the following command to add the component to your project:
npx @ark-preset/cli@latest add progressManual
Create the recipe file at src/components/recipes/progress.ts:
import { tv, type VariantProps } from "tailwind-variants";
export const progressVariants = tv({
slots: {
root: "relative w-full",
track: "h-2 w-full overflow-hidden rounded-full bg-muted",
range:
"h-full w-full flex-1 bg-primary transition-all data-[state=indeterminate]:animate-progress-indeterminate",
valueText: "text-base md:text-sm font-medium tabular-nums text-muted-foreground",
view: "",
},
});
export type ProgressVariants = VariantProps<typeof progressVariants>;Create the component directory and files.
src/components/progress/progress.base.tsx:
import { Progress as ArkProgress } from "@ark-ui/solid/progress";
import { splitProps, type Component } from "solid-js";
import { progressVariants, labelVariants } from "../recipes/progress";
const styles = progressVariants();
const Root: Component<ArkProgress.RootProps> = (props) => {
const [local, others] = splitProps(props, ["class"]);
return <ArkProgress.Root class={styles.root({ class: local.class })} {...others} />;
};
const RootProvider: Component<ArkProgress.RootProviderProps> = (props) => {
const [local, others] = splitProps(props, ["class"]);
return <ArkProgress.RootProvider class={styles.root({ class: local.class })} {...others} />;
};
const Label: Component<ArkProgress.LabelProps> = (props) => {
const [local, others] = splitProps(props, ["class"]);
return <ArkProgress.Label class={labelVariants({ class: local.class })} {...others} />;
};
const Track: Component<ArkProgress.TrackProps> = (props) => {
const [local, others] = splitProps(props, ["class"]);
return <ArkProgress.Track class={styles.track({ class: local.class })} {...others} />;
};
const Range: Component<ArkProgress.RangeProps> = (props) => {
const [local, others] = splitProps(props, ["class"]);
return <ArkProgress.Range class={styles.range({ class: local.class })} {...others} />;
};
const ValueText: Component<ArkProgress.ValueTextProps> = (props) => {
const [local, others] = splitProps(props, ["class"]);
return <ArkProgress.ValueText class={styles.valueText({ class: local.class })} {...others} />;
};
const View: Component<ArkProgress.ViewProps> = (props) => {
const [local, others] = splitProps(props, ["class"]);
return <ArkProgress.View class={styles.view({ class: local.class })} {...others} />;
};
const Circle = ArkProgress.Circle;
const CircleRange = ArkProgress.CircleRange;
const CircleTrack = ArkProgress.CircleTrack;
export const Progress = {
Root,
RootProvider,
Label,
Track,
Range,
ValueText,
View,
Circle,
CircleRange,
CircleTrack,
};src/components/progress/index.tsx:
import { splitProps, type Component } from "solid-js";
import { Progress as ProgressBase } from "./progress.base";
import { Progress as ArkProgress } from "@ark-ui/solid/progress";
const Progress = ProgressBase.Root;
const ProgressRootProvider = ProgressBase.RootProvider;
const ProgressLabel = ProgressBase.Label;
const ProgressValueText = ProgressBase.ValueText;
// Composite wrappers — auto-include sub-parts
const ProgressTrack: Component<ArkProgress.TrackProps> = (props) => {
const [local, others] = splitProps(props, ["children"]);
return (
<ProgressBase.Track {...others}>
<ProgressBase.Range />
{local.children}
</ProgressBase.Track>
);
};
export {
Progress,
ProgressRootProvider,
ProgressLabel,
ProgressTrack,
ProgressValueText,
ProgressBase,
};
export { progressVariants, type ProgressVariants } from "../recipes/progress";Note: Make sure your project has the Tailwind CSS theme variables set up (
--background,--foreground,--ring,--border, etc.) or override the utility classes to match your design system.
Usage
Basic Usage
Loading
65%
import { Progress, ProgressLabel, ProgressTrack, ProgressValueText } from "~/components/progress";
export default function ProgressBasicDemo() {
return (
<Progress value={65} class="space-y-2">
<ProgressLabel>Loading</ProgressLabel>
<ProgressTrack />
<ProgressValueText />
</Progress>
);
}Indeterminate
Omit the value prop to render an indeterminate progress bar:
Loading...
import { Progress, ProgressLabel, ProgressTrack } from "~/components/progress";
export default function ProgressIndeterminateDemo() {
return (
<Progress>
<ProgressLabel>Loading...</ProgressLabel>
<ProgressTrack />
</Progress>
);
}API Reference
See the Ark UI Progress documentation.