feat(Slider): add new component and composable#143
Merged
johnleider merged 41 commits intomasterfrom Mar 10, 2026
Merged
Conversation
|
commit: |
- Fix infinite recursive watch by guarding model/values sync with array comparison - Forward useAttrs() in Track, Range, Thumb for inheritAttrs:false compatibility - Include onPointerdown/onKeydown in slotProps.attrs for renderless mode - Centralize drag logic in SliderRoot using useDocumentEventListener - Register track element via watchEffect instead of onMounted - Add crossover prop to allow range thumbs to pass through each other
…ling - Normalize range start/end after percent conversion for inverted mode - Use useToggleScope for drag listeners to prevent leak on unmount - Set per-thumb aria-valuemin/valuemax per WAI-ARIA multi-thumb pattern - Recycle thumb indices on unmount/remount with lowest-first allocation - Guard step=0 in snap() to prevent NaN corruption - Rename onPointerDown to onPointerdown matching DOM event convention - Add per-property JSDoc with @see and @example to barrel export
- readonly prop blocks mutations while keeping thumbs focusable (aria-readonly, data-readonly on all sub-components) - Thumb-edge drag offset prevents value jumping when grabbing near the edge of a thumb element - start/end emits replace valueCommit for drag lifecycle events
type="hidden" inputs are never rendered by the browser, making the visually-hidden CSS and inert attribute redundant.
…ts to createSelection createModel is now a single-value store with simplified select/unselect/apply. Selection-specific concepts (mandatory, multiple, seek, mandate, onboard) moved to createSelection where they belong.
apply() now detects ref-based ticket values and updates them directly instead of browse resolution. selectedValues uses toValue() for automatic reactivity tracking. Updated input example to single-ticket pattern and color palette to multi-ticket composite with createSelection.
9-task TDD plan covering composable rewrite, test updates, component changes, and validation.
Each thumb is now a model ticket with a shallowRef<number> value instead of a standalone ref<number[]>. Values are derived from ordered tickets via computed, enabling proper register/unregister lifecycle. Adds registerThumb/unregisterThumb API, pending values pattern for timing (useProxyModel fires apply before thumbs mount), and range option. BREAKING CHANGE: values is now ComputedRef<number[]> (was Ref<number[]>). Direct assignment (slider.values.value = [...]) no longer works. Use registerThumb/apply instead.
Replace direct values assignment with registerThumb/addThumb helper. Add test coverage for registerThumb, unregisterThumb, apply with pending values, and multi-thumb ordering.
Registration/unregistration now lives in createSlider via model tickets. SliderRootContext no longer declares registerThumb/unregisterThumb — they come through the SliderContext spread.
Register via root.registerThumb() which now returns a ModelTicket. Index is reactive (ticket.index), value reads from ticket.value. All index references updated to use .value since it's now a Ref.
- Rewrite slider.md: anatomy, architecture mermaid, accessibility, trimmed recipes (form integration, drag events, data attributes) - Add audio equalizer example (useEqualizer.ts + Equalizer.vue + equalizer.vue) showcasing vertical sliders and composable state - Add HSL color picker example (ColorSlider.vue + ColorPicker.vue + color-picker.vue) with reactive gradient tracks - Add single-file examples: vertical, steps, states - Update basic.vue to show both single and range modes - Add section content rules to docs.md (usage, anatomy, examples, recipes conventions for component vs composable pages)
170470d to
90166d8
Compare
- percent → fromValue - setValue → set - stepUp → up - stepDown → down - setToMin → floor - setToMax → ceil
- Media scrubber: provider/consumer pattern with waveform visualization - Theme comparison: clip-path reveal with data-theme scoping - Update API references for renamed methods - Remove old basic.vue example - Fix isDragging warning in Equalizer example
Align register() with createRegistry/createModel convention by
accepting { value: N } in addition to the number shorthand.
createSlider needs all thumbs selected simultaneously, but select() always cleared selectedIds first. Adding multiple: true lets select() and apply() accumulate IDs instead of replacing, removing the manual selectedIds.add() workaround in createSlider.
SelectionOptions extends ModelOptions and declares multiple as MaybeRefOrGetter<boolean>. The narrower boolean type caused TS2430.
johnleider
added a commit
that referenced
this pull request
Mar 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
createSlidercomposable with value math, step snapping, percent conversion, and multi-thumb supportChanges
Composable (
packages/0/src/composables/createSlider/)minStepsBetweenThumbsandcrossoveroptionsComponents (
packages/0/src/components/Slider/)SliderRoot— context provider, v-model bridge, centralized drag handling viauseDocumentEventListenerSliderTrack— click-to-position with nearest-thumb snappingSliderRange— filled region with CSS custom properties for positioningSliderThumb— keyboard nav (Arrow, Home, End, PageUp/Down), ARIA attributes, focus managementSliderHiddenInput— form integration with hidden<input>per thumbDocs (
apps/docs/)pages/components/forms/slider.mdpages/composables/forms/create-slider.mdTest plan