import React, { useEffect, useState } from "react"; import { View } from "react-native"; import type { ComponentProps } from "react"; import type { Meta, StoryObj } from "@storybook/react-native-web-vite"; import { ProgressIndicator } from "@jobber/components-native"; import { ProgressIndicatorBasic, ProgressIndicatorPending } from "./docs"; type ProgressIndicatorStoryArgs = Partial< Pick< ComponentProps, | "value" | "max" | "pendingValue" | "variation" | "size" | "accessibilityLabel" > >; const meta = { title: "Components/Status and Feedback/ProgressIndicator", component: ProgressIndicator, parameters: { viewport: { defaultViewport: "mobile1" }, showNativeOnWebDisclaimer: true, }, argTypes: { variation: { control: { type: "radio" }, options: ["continuous", "stepped"], }, size: { control: { type: "radio" }, options: ["smaller", "small", "base"], }, }, } satisfies Meta; export default meta; type Story = StoryObj; /** * The default continuous bar, filled to `value` out of `max`. */ export const Basic: Story = { render: ProgressIndicatorBasic, args: { value: 75, size: "base", }, }; /** * The three sizes stacked so the heights (4 / 8 / 16px) are visually * comparable. */ export const Sizes: Story = { render: args => ( ), args: { value: 50, }, }; /** * The stepped variation renders one segment per step and fills the first * `value` of `max`. */ export const Stepped: Story = { render: ProgressIndicatorBasic, args: { value: 2, max: 5, variation: "stepped", size: "base", }, }; /** * Mobile-only pending overlay: `value` of `max` completed plus an additional * `pendingValue` of `max` in flight. */ export const Pending: Story = { render: ProgressIndicatorPending, args: { value: 2, max: 10, pendingValue: 3, }, }; /** * The stepped variation with a pending overlay: the first `value` segments are * filled and the next `pendingValue` segments are shown as in flight. */ export const SteppedPending: Story = { render: ProgressIndicatorPending, args: { value: 3, max: 6, pendingValue: 2, variation: "stepped", }, }; /** * Demonstrates the default `"{value}%"` accessibility label when `max` is * omitted or equal to 100. */ export const Percentage: Story = { render: ProgressIndicatorBasic, args: { value: 42, }, }; /** * Demonstrates the default `"{value} / {max}"` accessibility label when * `max !== 100`. */ export const Ratio: Story = { render: ProgressIndicatorBasic, args: { value: 3, max: 4, }, }; /** * Drives `value` over time so the determinate width transition is visible. The * transition is intentionally preserved under a reduce-motion preference * because it conveys functional progress (WCAG 2.3.3). */ export const WithState: Story = { render: function WithStateStory() { const [value, setValue] = useState(0); useEffect(() => { const interval = setInterval(() => { setValue(current => (current >= 100 ? 0 : current + 10)); }, 1000); return () => clearInterval(interval); }, []); return ; }, };