diff --git a/src/ui.progress/composables/attrs.composable.js b/src/ui.progress/composables/attrs.composable.js
new file mode 100644
index 00000000..0e54f5df
--- /dev/null
+++ b/src/ui.progress/composables/attrs.composable.js
@@ -0,0 +1,32 @@
+import useUI from "../../composable.ui";
+import { cva } from "../../service.ui";
+
+import defaultConfig from "../configs/default.config";
+import { computed } from "vue";
+
+export function useAttrs(props) {
+ const { config, getAttrs, setColor } = useUI(defaultConfig, () => props.config);
+ const { progress } = config.value;
+
+ const cvaProgress = cva({
+ base: progress.base,
+ variants: progress.variants,
+ compoundVariants: progress.compoundVariants,
+ });
+
+ const progressClasses = computed(() =>
+ setColor(
+ cvaProgress({
+ size: props.size,
+ color: props.color,
+ }),
+ props.color,
+ ),
+ );
+
+ const progressAttrs = getAttrs("progress", { classes: progressClasses });
+
+ return {
+ progressAttrs,
+ };
+}
diff --git a/src/ui.progress/configs/default.config.js b/src/ui.progress/configs/default.config.js
new file mode 100644
index 00000000..d345b0b9
--- /dev/null
+++ b/src/ui.progress/configs/default.config.js
@@ -0,0 +1,34 @@
+export default /*tw*/ {
+ progress: {
+ base: `
+ block appearance-none border-none overflow-hidden w-full
+ [&::-webkit-progress-bar]:w-full h-2 rounded-full [&::-webkit-progress-bar]:rounded-full
+ [&::-webkit-progress-bar]:bg-{color}-200 [@supports(selector(&::-moz-progress-bar))]:bg-{color}-200
+ [&::-webkit-progress-value]:rounded-full [&::-webkit-progress-value]:transition-all
+ [&::-webkit-progress-value]:ease-in-out [&::-moz-progress-bar]:rounded-full text-{color}-500
+ [&::-webkit-progress-value]:bg-current [&::-moz-progress-bar]:bg-current indeterminate:relative
+ indeterminate:after:rounded-full [&:indeterminate::-webkit-progress-value]:rounded-full
+ [&:indeterminate::-moz-progress-bar]:rounded-full
+ `,
+ variants: {
+ color: {
+ white: "bg-white",
+ grayscale: "bg-gray-900",
+ },
+ size: {
+ "2xs": "h-px",
+ xs: "h-0.5",
+ sm: "h-1",
+ md: "h-2",
+ lg: "h-3",
+ xl: "h-4",
+ "2xl": "h-5",
+ },
+ },
+ },
+ defaultVariants: {
+ color: "green",
+ size: "md",
+ },
+ safelist: (colors) => [{ pattern: `bg-(${colors})-200` }, { pattern: `text-(${colors})-500` }],
+};
diff --git a/src/ui.progress/constants/index.js b/src/ui.progress/constants/index.js
new file mode 100644
index 00000000..fc216dd7
--- /dev/null
+++ b/src/ui.progress/constants/index.js
@@ -0,0 +1,5 @@
+/*
+ This const is needed to prevent the issue in script setup:
+ `defineProps` is referencing locally declared variables. (vue/valid-define-props)
+ */
+export const UProgress = "UProgress";
diff --git a/src/ui.progress/index.stories.js b/src/ui.progress/index.stories.js
new file mode 100644
index 00000000..085419bb
--- /dev/null
+++ b/src/ui.progress/index.stories.js
@@ -0,0 +1,42 @@
+import UProgress from "./index.vue";
+import UButton from "../ui.button/index.vue";
+
+import { getArgTypes } from "../service.storybook";
+
+export default {
+ id: "9015",
+ title: "Other / Progress",
+ component: UProgress,
+ argTypes: {
+ ...getArgTypes(UProgress.name),
+ },
+};
+
+const DefaultTemplate = (args) => ({
+ components: { UProgress, UButton },
+ setup() {
+ return { args };
+ },
+ data() {
+ return {
+ progress: 10,
+ };
+ },
+ methods: {
+ updateProgress() {
+ this.progress += 10;
+
+ if (this.progress > 100) {
+ this.progress = 0;
+ }
+ },
+ },
+ template: `
+
+
+ Update Progress
+ `,
+});
+
+export const Default = DefaultTemplate.bind({});
+Default.args = {};
diff --git a/src/ui.progress/index.vue b/src/ui.progress/index.vue
new file mode 100644
index 00000000..7a59be3b
--- /dev/null
+++ b/src/ui.progress/index.vue
@@ -0,0 +1,36 @@
+
+
+
+
+