Skip to content

feat(Progress): add new component/composable#180

Merged
johnleider merged 49 commits intomasterfrom
feat/progress
Apr 6, 2026
Merged

feat(Progress): add new component/composable#180
johnleider merged 49 commits intomasterfrom
feat/progress

Conversation

@johnleider
Copy link
Copy Markdown
Member

@johnleider johnleider commented Apr 4, 2026

Summary

  • Add createProgress composable — registry-based segment tracking with value-driven indeterminate mode, total/percent computation, and trinity pattern for DI
  • Add Progress headless component tree: Root, Track, Fill, Buffer, Value, Label, HiddenInput
  • Full ARIA role="progressbar" compliance (determinate + indeterminate modes)

Components

Component Purpose
Progress.Root Creates context, bridges v-model (number | number[]), provides ARIA attrs
Progress.Track Container for fills (the "rail")
Progress.Fill Auto-registers segment on mount, exposes value/percent/index
Progress.Buffer Independent buffered indicator (not part of total)
Progress.Value Displays ${percent}% by default, overridable via scoped slot
Progress.Label Descriptive text, auto-wires aria-labelledby to Root
Progress.HiddenInput Form submission, auto-rendered when name prop set

Key features

  • Multi-segment: Multiple Fill children auto-register, each with independent value/percent
  • Value-driven indeterminate: No value + no segments = indeterminate. Set a value → determinate.
  • Buffer: Independent of registry, computes own percent from min/max
  • Circular support: No shape-specific components — use slot props with SVG/CSS

Spec & Plan

  • Spec: docs/superpowers/specs/2026-04-03-progress-design.md
  • Plan: docs/superpowers/plans/2026-04-03-progress.md

Test plan

  • pnpm build:0 — passes
  • pnpm typecheck — passes
  • pnpm lint:fix — clean
  • pnpm test:run — 4469 tests passing
  • pnpm repo:check (knip + sherif) — no issues
  • Manual testing with dev app examples
  • Docs page and examples (follow-up)

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 4, 2026

Open in StackBlitz

commit: 0a9bdf7

@johnleider johnleider self-assigned this Apr 4, 2026
…eProps

- Rewrite createProgress to use createRegistry with reactive option
  instead of manual Map + triggerRef management
- Replace ProgressSegment type with ProgressTicket extending RegistryTicket
- Use mergeProps(attrs, slotProps.attrs) in all component templates
- Use style array [attrs.style, slotProps.attrs.style] for Fill/Buffer
- Make ProgressLabel id a prop with useId() default
- Remove unused useProxyModel import from ProgressRoot
- Remove onBeforeUnmount cleanup from Root (registry handles disposal)
- Remove inline section comments from ProgressRoot
Replace manual segment management in ProgressRoot with the established
createModel + useProxyModel pattern used by Slider. The composable now
extends createModel with multiple:true and events:true, overriding
register/apply/selectedValues. ProgressRoot is significantly simpler —
just creates the composable, normalizes v-model, and calls useProxyModel.
…ster conventions

- Remove percent from ProgressTicket — add fromValue() to context instead (matches Slider)
- Add id prop to ProgressRoot with useId() default (matches SliderRoot, DialogRoot)
- Derive labelId from root id (matches Dialog titleId/descriptionId pattern)
- Match Slider's register signature: isObject(input) ? input.value : input
- Re-declare value on ProgressTicketInput as required (matches SliderTicketInput)
- ProgressLabel reads root.labelId directly, no mutable ShallowRef
- Remove ProgressTicket type alias, use ModelTicket<ProgressTicketInput> inline
- Remove generics from createProgress (matches Slider — not designed for extension)
- ProgressOptions is standalone (doesn't extend ModelOptions)
- Use ticket.unregister() instead of root.unregister(ticket.id)
- Remove redundant isUndefined check in scalar detection
- register uses isObject(input) matching Slider exactly
# Conflicts:
#	apps/docs/src/typed-router.d.ts
@johnleider johnleider added this to the v0.2.x milestone Apr 6, 2026
@johnleider johnleider changed the title feat(Progress): add headless Progress component and createProgress composable feat(Progress): add new component/composable Apr 6, 2026
@johnleider johnleider merged commit d8ec512 into master Apr 6, 2026
12 of 14 checks passed
@johnleider johnleider deleted the feat/progress branch April 6, 2026 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant