Skip to content

Conversation

@nerdyman
Copy link
Owner

@nerdyman nerdyman commented Dec 18, 2025

#180

  • Remove useReactCompareSliderRef
  • Export individual components so people can build their own sliders
  • Export useReactCompareSlider hook to return all the props and logic needed by the components
  • Export useReactCompareSliderContext hook for components within the context provider to access props
  • Get doc tables generating again
  • Document individual components
  • Get existing stories working with new set up
  • Do new beta release

@nerdyman nerdyman self-assigned this Dec 18, 2025
@vercel
Copy link

vercel bot commented Dec 18, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
react-compare-slider Ready Ready Preview Jan 23, 2026 11:38pm

@nerdyman nerdyman added the enhancement New feature or request label Dec 18, 2025
…fset` logic from `setPositionFromBounds` since keyboard events don't use it now
@github-actions
Copy link

github-actions bot commented Jan 21, 2026

Size Change: +2.48 kB (+37.75%) 🚨

Total Size: 9.07 kB

Filename Size Change
dist/components/index.cjs 146 B +146 B (new file) 🆕
dist/components/index.mjs 152 B +152 B (new file) 🆕
dist/hooks-ChgvAofo.cjs 1.04 kB +1.04 kB (new file) 🆕
dist/hooks-DdMEDIH0.mjs 1.02 kB +1.02 kB (new file) 🆕
dist/hooks.cjs 103 B +103 B (new file) 🆕
dist/hooks.mjs 104 B +104 B (new file) 🆕
dist/index.cjs 475 B -3.02 kB (-86.41%) 🏆
dist/index.mjs 497 B -2.59 kB (-83.91%) 🏆
dist/internal-hooks-CFtUHzSH.cjs 495 B +495 B (new file) 🆕
dist/internal-hooks-Co_RKZsl.mjs 445 B +445 B (new file) 🆕
dist/root-D7EwXp6v.cjs 2.31 kB +2.31 kB (new file) 🆕
dist/root-DN8zKO-H.mjs 2.25 kB +2.25 kB (new file) 🆕
dist/types.cjs 20 B +20 B (new file) 🆕
dist/types.mjs 20 B +20 B (new file) 🆕

compressed-size-action

…storybook can generate prop tables properly
@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 21, 2026

commit: 1973ff1

…wn` to `onHandleRootKeyDown` add custom slider and contxt tests
@sonarqubecloud
Copy link

@nerdyman nerdyman marked this pull request as ready for review January 23, 2026 23:45
@nerdyman nerdyman requested a review from Copilot January 23, 2026 23:49
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements a major architectural change to introduce composable components for the react-compare-slider library, addressing issue #180. The changes allow developers to build custom sliders using individual exported components and hooks, while maintaining backward compatibility with the existing monolithic ReactCompareSlider component.

Changes:

  • Introduced composable component architecture with individual exports for Provider, Root, Item, HandleRoot, Handle, and Image components
  • Added useReactCompareSlider hook to manage slider state and event handlers, and useReactCompareSliderContext for accessing slider context
  • Renamed position prop to defaultPosition and changed clip values from 'both' to 'all' for consistency
  • Migrated build tooling from tsup to tsdown with enhanced package validation via attw and publint
  • Removed deprecated useReactCompareSliderRef hook in favor of the new composable API
  • Updated all documentation, tests, and examples to reflect the new API

Reviewed changes

Copilot reviewed 70 out of 71 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
lib/src/types.ts Renamed types and restructured props for composable architecture
lib/src/consts.ts Updated clip option naming and added new CSS variables
lib/src/hooks.ts New hook providing complete slider control with state and event handlers
lib/src/components/* New composable component implementations (Provider, Root, Item, HandleRoot, Handle, Image, internal-hooks)
lib/src/react-compare-slider.tsx Refactored main component to use new composable components internally
lib/src/index.ts Updated exports to expose new components and hooks
lib/tsdown.config.ts New build configuration replacing tsup
lib/package.json Updated exports for multi-entry point support and dependency versions
docs/storybook/content/stories/* Updated all stories and tests for new API
docs/example/src/App.tsx Demonstrates both traditional and composable API usage
package.json Updated dependency versions and pnpm configuration

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +130 to +132
const isIncrement = portrait
? ev.key === KeyboardEventKeys.ARROW_LEFT || ev.key === KeyboardEventKeys.ARROW_DOWN
: ev.key === KeyboardEventKeys.ARROW_RIGHT || ev.key === KeyboardEventKeys.ARROW_UP;
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The keyboard navigation logic appears inverted for portrait mode. In portrait mode, ARROW_LEFT and ARROW_DOWN should move the handle down (increase position), but ARROW_DOWN typically means "move down" which should increase the position. However, the current logic treats ARROW_DOWN as an increment, which may be counterintuitive. Consider if ARROW_UP should increase position (move divider up) and ARROW_DOWN should decrease position (move divider down) in portrait mode for better UX.

Copilot uses AI. Check for mistakes.
const context = useContext(Context);

if (!context) {
throw new Error('useReactCompareSliderContext must be used within the Context component');
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message says "must be used within the Context component" but it should say "must be used within the Provider component" to match the actual component name that developers will use. The test at docs/storybook/content/stories/99-tests/context.test.stories.tsx:44 also expects the old error message and will need to be updated accordingly.

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +75
return () => {
containerRef.removeEventListener('pointermove', onPointerMove);
containerRef.removeEventListener('pointerleave', handlePointerLeave);
};
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the cleanup function, rootRef.current might be null when the component unmounts, but the code doesn't check for this before calling removeEventListener. Although removeEventListener on undefined/null may not throw, it's safer to add a null check: if (containerRef) { containerRef.removeEventListener(...) }.

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +30
/** Optional styles for handle the button. */
buttonStyle?: CSSProperties;
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a typo in the JSDoc comment: "Optional styles for handle the button" should be "Optional styles for the handle button" (remove the duplicate "the").

Copilot uses AI. Check for mistakes.
/**
* @NOTE These must reflect the default values defined in the `types.ts`.
*/
export const args: ReactCompareSliderProps = {
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The args object uses ReactCompareSliderProps as its type, which marks itemOne and itemTwo as required (non-optional) properties according to lib/src/types.ts. However, this object sets them to undefined which will cause a TypeScript error. Consider using Partial<ReactCompareSliderProps> for the type annotation or handling these required props differently.

Copilot uses AI. Check for mistakes.
Comment on lines +11 to 12
export type { ReactCompareSliderDetailedProps, ReactCompareSliderProps } from './types';
export { styleFitContainer } from './utils';
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ReactCompareSliderPosition type is defined in types.ts but is not exported from the main index.ts. If this type is intended to be part of the public API (as it was previously with ReactCompareSliderPropPosition), it should be exported. Otherwise, consumers who want to type position values will need to use number directly.

Copilot uses AI. Check for mistakes.
Comment on lines +100 to +108
const onPointerUp = useCallback((ev: PointerEvent) => {
setIsDragging(false);
setCanTransition(true);
}, []);

const onTouchEnd = useCallback((ev: TouchEvent) => {
setIsDragging(false);
setCanTransition(true);
}, []);
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The onPointerUp and onTouchEnd event handlers receive an event parameter but don't use it. Consider adding _ prefix to the parameter name to indicate it's intentionally unused: (ev: PointerEvent)(_ev: PointerEvent) or remove the parameter entirely if not needed.

Copilot uses AI. Check for mistakes.
}, [onPointerMove, onPointerUp, isDragging, browsingContext, hasBrowsingContextBinding]);

return (
<div ref={rootRef} style={appliedStyle} data-rcs="root" data-rcs-clip={clip} data-testaroo {...props} />
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a leftover test attribute data-testaroo in the production code. This should be removed as it appears to be a testing artifact.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,56 @@
import type { Meta, StoryFn } from '@storybook/react-vite';
import { type ReactCompareSlider, useReactCompareSliderContext } from 'react-compare-slider';
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import useReactCompareSliderContext.

Suggested change
import { type ReactCompareSlider, useReactCompareSliderContext } from 'react-compare-slider';
import { type ReactCompareSlider } from 'react-compare-slider';

Copilot uses AI. Check for mistakes.
}
ref={reactCompareSliderRef}
browsingContext={browsingContext}
browsingContext={browsingContext || undefined}
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This use of variable 'browsingContext' always evaluates to true.

Suggested change
browsingContext={browsingContext || undefined}
browsingContext={browsingContext}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request publish-preview Publish a preview package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants