Skip to content

Add typed React components and automatic carousel setup - #9

Merged
marlonmarcello merged 11 commits into
mainfrom
copilot/better-react-support-and-management
Nov 4, 2026
Merged

marlonmarcello merged 11 commits into
mainfrom
copilot/better-react-support-and-management

Conversation

Copilot AI commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

React support

What this PR adds

This PR adds a React entry point to Gordito. Consumers can compose a carousel with typed components instead of wiring the DOM contract and core lifecycle themselves.

Infinite navigation is still a core feature. The React adapter renders its own slide copies so their handlers and content work correctly. Vanilla consumers keep the existing DOM-cloning path and do not need to install React.

The scope includes:

  • Components: Carousel, structural helpers, previous/next buttons, and pagination components. The items API generates the list and track, with semantic list-item roots by default.
  • State and controls: useCarousel() exposes the core instance, current slide, setPosition(), and directional swipe(). The root accepts before/after change callbacks.
  • Packaging: a typed @wethegit/gordito-carousel/react export, a 'use client' entry point, an optional React peer dependency, and structural CSS.
  • Examples and docs: a dedicated React page with four live examples, copyable JSX, updated homepage guidance, and an updated README.

Suggested review order

  1. Public API and lifecycle — React adapter. Review component props, semantic defaults, context, callbacks, and effect cleanup. Check both items mode and manually authored structure.
  2. Core integration — carousel core. Start with buildOut(), commitRenderPlan(), and destroy(). Then check the pending-plan interaction guards and restrictions on imperative DOM mutation.
  3. Distribution — package exports, React styles, and CSS copying. Confirm the React entry includes its types and required CSS without making React mandatory for vanilla usage.
  4. Live usage — React page and example components. The examples use local source in Strict Mode.
  5. Consumer guidance — README and homepage docs. These describe setup and usage.

How the rendering integration works

  1. React renders the source originals inside the list and track.
  2. Core calculates a render plan describing the originals and copies it needs.
  3. React renders that plan using the latest source items.
  4. After the DOM commits, the adapter acknowledges the plan. Core validates the result before measuring, positioning, and completing initialization or refresh.

Core owns navigation, measurements, and runtime state. React owns the slide nodes and component lifetimes. Navigation and drag initiation are ignored while a plan is pending, rather than running against incomplete DOM.

Originals are keyed by source item identity. Copies also include their rendered position in the key. Matching occurrences can retain their component state when the list changes. Removed occurrences unmount normally. The rendered copy set stays bounded during navigation.

Behavior and trade-offs to review

  • Copies are separate instances. Local state and effects are not shared. Shared state belongs above the slides. Avoid repeated fixed DOM IDs.
  • Item updates refresh core. Replace the array when content changes, and use stable keys. This preserves the current numeric slide index where possible, but does not follow an item key after reordering. Content-only array replacements also trigger a refresh.
  • Options can recreate core. Keep the object stable unless configuration changes. Reinitialization starts from initialSlide, which defaults to zero. Selector changes must rediscover excluded originals without unnecessarily remounting surviving copies.
  • React owns structural changes in items mode. addSlide(), removeSlide(), filterSlides(), and unfilterSlides() throw before mutation. Teardown removes core-owned state without restoring stale styles over current React props.
  • Authored structure remains available. Without items, infinite copies use DOM cloning and do not acquire React handlers. Review the distinction so consumers are not led toward the wrong mode for interactive slides.
  • Embedded controls keep native pointer interaction. Browser testing caught list pointer capture swallowing button clicks. Core now skips drag initiation on interactive controls, while ordinary card content remains draggable. This change applies to vanilla usage too.

Automated coverage

Tests Main review cases
Basic React integration Appending items, empty sources, semantic markup, and custom structure
React regressions Selector expansion, simultaneous item/options updates, retained copy state, and pending-plan swipes
Core render plans Commit readiness, interaction guards, mutation rejection, and style cleanup
Embedded controls Controls do not start drags or interrupt moves, while card dragging still works
Live site examples Shared state, current handlers, editable items, selectors, and inline styles

The tests use JSDOM. They do not establish that real layout, transitions, or pointer gestures work correctly in a browser.

How to test this PR

Run the checks

Use the Node version in .nvmrc. From the repository root:

npm i
npm run test
npm run check
npm run build
npm run site:build

Try the live examples

Run npm run dev, open the URL printed by Vite, and follow React. Each demo has its source and suggested interactions.

  • /react/#featured — viewport-wide photo fan. Loop in both directions, rapidly change targets, drag freely, select neighboring photos, and resize across the desktop/mobile breakpoint. Watch both viewport edges for gaps or visible corrections. This is a visual stress case, not a timed performance benchmark.
  • /react/#interactive — handlers and shared state. Save a card, loop through its copies, then edit its caption and save again. Counts should stay synchronized and the saved message should use the latest text. Check the hook button and before/after event readout too.
  • /react/#editable — source updates. Rename and reorder cards. Remove the selected last card, clear everything, then add items again. Look for lost state, invalid selection, or DOM errors.
  • /react/#selectors — filtering and style updates. Turn off “Featured only” and confirm A returns. Toggle “Infinite + blue accent” to change an option and inline styles together. Originals and copies should keep the new appearance. Inspect the ordered track for direct li children.

Validation recorded so far

  • All 68 tests, formatting, lint, typechecks, and the library/site builds passed during implementation.
  • Headless Firefox checks covered looping, rapid selection, pagination, free dragging, click-to-select, shared handlers, source updates, and resizing. The featured fan retained 40 slide elements with its current configuration throughout those checks.
  • The full-width layout was checked at 1440px, 1920px, and a narrow 390px viewport. A scrollbar-related breakout overflow was found and fixed.

Important

These were exploratory browser checks, not a committed end-to-end suite. A narrow desktop viewport is not a real touch-device test.

@changeset-bot

changeset-bot Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3a6c5fa

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@wethegit/gordito-carousel Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copilot AI linked an issue Oct 28, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Add React components for better support and management Add typed React components and automatic carousel setup Oct 28, 2026
Copilot AI requested a review from marlonmarcello October 28, 2026 18:24

@marlonmarcello marlonmarcello left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot the should make sure that we support React 19+ and we should tag the component with use client.

We should also support the beforeChange event, not just the afterChange.

Lets also add a few methods to the context so that we can pragmatically call both setPosition and swipe.

Co-authored-by: marlonmarcello <1956448+marlonmarcello@users.noreply.github.com>

Copilot AI commented Oct 28, 2026

Copy link
Copy Markdown
Contributor Author

@copilot the should make sure that we support React 19+ and we should tag the component with use client.

We should also support the beforeChange event, not just the afterChange....

Added React 19 validation and the use client directive, onBeforeChange, and setPosition()/directional swipe() context methods. Checks and builds pass; commit d81b1a9.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved issues leave React slide structure and state out of sync, mishandle nested carousel events, break React behavior in cloned slides, and impose React on vanilla consumers.

5 open issues
What changed in this PR

Adds a typed React entry point around the existing carousel core, reducing manual DOM setup, lifecycle management, and stylesheet handling.

Changes:

  • Introduces structural components, controls, and a context hook for carousel state.
  • Automatically initializes and destroys the core and imports animation-suppression styles.
  • Adds package exports, TypeScript support, and React usage documentation.
File Description
tsconfig.json Enables React JSX and includes TSX sources.
src/​react/​style.css Imports core styles and suppresses transitions during dragging and instant moves.
src/​react/​index.tsx Adds typed components, lifecycle handling, and the context hook.
src/​react/​css.d.ts Declares CSS imports for TypeScript.
scripts/​copy-css.js Copies React styles into the distribution.
README.md Documents React components and usage.
package.json Exports the React entry point and adds React dependency metadata.
package-lock.json Records updated package and dependency metadata.

Review effort: Balanced

Comment thread package.json Resolved
Comment thread src/react/index.tsx Resolved
Comment thread src/react/index.tsx Resolved
Comment thread src/react/index.tsx Resolved
Comment thread src/react/index.tsx Resolved
@marlonmarcello

Copy link
Copy Markdown
Member

@copilot let's make sure we add a changeset, update the dependencies and node versions to the latest. Let's also make sure we update the docs in the site/.

Co-authored-by: marlonmarcello <1956448+marlonmarcello@users.noreply.github.com>
Co-authored-by: marlonmarcello <1956448+marlonmarcello@users.noreply.github.com>

Copilot AI commented Oct 29, 2026

Copy link
Copy Markdown
Contributor Author

@marlonmarcello I've opened a new pull request, #10, to work on those changes. Once the pull request is ready, I'll request review from you.

Add the React items API and a core render-plan commit handshake while preserving vanilla DOM cloning. Preserve keyed copies across item and selector updates, enforce valid list markup, and protect React-owned DOM and styles during lifecycle changes. Guard interactions until render plans commit and add regression coverage.
@marlonmarcello
marlonmarcello marked this pull request as ready for review October 30, 2026 00:16
NicholasLancey
NicholasLancey previously approved these changes Nov 3, 2026

@NicholasLancey NicholasLancey left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I've tested this locally using the existing demos, and created a few of my own, and everything is working as expected.

I've also reviewed both react/index.tsx and src/index.ts as that's where the majority of the work is, and everything seems OK to me.

Would be great to get some more eyes on this one as it's a big'un!

Updated the version of '@wethegit/gordito-carousel' from minor to major
@marlonmarcello
marlonmarcello merged commit 5c11565 into main Nov 4, 2026
2 checks passed
@marlonmarcello
marlonmarcello deleted the copilot/better-react-support-and-management branch November 4, 2026 20:12
@github-actions github-actions Bot mentioned this pull request Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Better React support and simpler management

4 participants