mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-30 02:10:12 -06:00
feat: progress component + storybook setup for surveys package
This commit is contained in:
49
packages/surveys/src/components/v5/progress/index.tsx
Normal file
49
packages/surveys/src/components/v5/progress/index.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import type { JSX } from "preact";
|
||||
|
||||
interface ProgressProps {
|
||||
value?: number;
|
||||
max?: number;
|
||||
containerStyling?: JSX.CSSProperties;
|
||||
indicatorStyling?: JSX.CSSProperties;
|
||||
"aria-label"?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Progress component displays an indicator showing the completion progress of a task.
|
||||
* Typically displayed as a progress bar.
|
||||
*
|
||||
* @param value - Current progress value (0-100 by default)
|
||||
* @param max - Maximum value (default: 100)
|
||||
* @param containerStyling - Custom styling object for the container
|
||||
* @param indicatorStyling - Custom styling object for the indicator
|
||||
* @param aria-label - Accessible label for the progress bar
|
||||
*/
|
||||
export function Progress({
|
||||
value = 0,
|
||||
max = 100,
|
||||
containerStyling = {},
|
||||
indicatorStyling = {},
|
||||
"aria-label": ariaLabel = "Progress",
|
||||
}: ProgressProps) {
|
||||
// Calculate percentage, ensuring it stays within 0-100 range
|
||||
const percentage = Math.min(Math.max((value / max) * 100, 0), 100);
|
||||
|
||||
return (
|
||||
<div
|
||||
role="progressbar"
|
||||
aria-valuemin={0}
|
||||
aria-valuemax={max}
|
||||
aria-valuenow={value}
|
||||
aria-label={ariaLabel}
|
||||
className="fb-relative fb-h-2 fb-w-full fb-overflow-hidden fb-rounded-full fb-bg-accent-bg"
|
||||
style={containerStyling}>
|
||||
<div
|
||||
className="fb-h-full fb-w-full fb-flex-1 fb-bg-brand fb-transition-all fb-duration-500 fb-ease-in-out"
|
||||
style={{
|
||||
transform: `translateX(-${100 - percentage}%)`,
|
||||
...indicatorStyling,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
106
packages/surveys/src/components/v5/progress/progress.stories.tsx
Normal file
106
packages/surveys/src/components/v5/progress/progress.stories.tsx
Normal file
@@ -0,0 +1,106 @@
|
||||
import type { Meta, StoryObj } from "@storybook/preact-vite";
|
||||
import type { ComponentProps } from "preact";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import "../../../styles/global.css";
|
||||
import { Progress } from "./index";
|
||||
|
||||
type ProgressProps = ComponentProps<typeof Progress>;
|
||||
|
||||
const meta: Meta<ProgressProps> = {
|
||||
title: "v5/Progress",
|
||||
component: Progress,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.",
|
||||
},
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
decorators: [
|
||||
(Story: any) => (
|
||||
<div id="fbjs" style={{ width: "400px", padding: "20px" }}>
|
||||
<Story />
|
||||
</div>
|
||||
),
|
||||
],
|
||||
argTypes: {
|
||||
value: {
|
||||
control: { type: "range", min: 0, max: 100, step: 1 },
|
||||
description: "Current progress value",
|
||||
table: {
|
||||
type: { summary: "number" },
|
||||
defaultValue: { summary: "0" },
|
||||
},
|
||||
},
|
||||
max: {
|
||||
control: { type: "number" },
|
||||
description: "Maximum value",
|
||||
table: {
|
||||
type: { summary: "number" },
|
||||
defaultValue: { summary: "100" },
|
||||
},
|
||||
},
|
||||
containerStyling: {
|
||||
control: "object",
|
||||
description: "Custom styling object for the container",
|
||||
table: {
|
||||
type: { summary: "CSSProperties" },
|
||||
defaultValue: { summary: "{}" },
|
||||
},
|
||||
},
|
||||
indicatorStyling: {
|
||||
control: "object",
|
||||
description: "Custom styling object for the indicator",
|
||||
table: {
|
||||
type: { summary: "CSSProperties" },
|
||||
defaultValue: { summary: "{}" },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<ProgressProps>;
|
||||
|
||||
/**
|
||||
* Default progress bar with 50% completion
|
||||
*/
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
value: 50,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Progress bar with no progress (0%)
|
||||
*/
|
||||
export const Empty: Story = {
|
||||
args: {
|
||||
value: 0,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Progress bar with full progress (100%)
|
||||
*/
|
||||
export const Complete: Story = {
|
||||
args: {
|
||||
value: 100,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Progress bar with gradient indicator
|
||||
*/
|
||||
export const customStyling: Story = {
|
||||
args: {
|
||||
value: 70,
|
||||
indicatorStyling: {
|
||||
background: "linear-gradient(90deg, #3b82f6 0%, #8b5cf6 100%)",
|
||||
height: "2rem",
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -6,6 +6,7 @@
|
||||
"isolatedModules": true,
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "preact",
|
||||
"moduleResolution": "bundler",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user