Skip to content

feat(split): responsive + percentage snap points, snapFrom, onSnap callback#43

Merged
gfazioli merged 4 commits intomasterfrom
feat/snap-points-enhancements
Apr 17, 2026
Merged

feat(split): responsive + percentage snap points, snapFrom, onSnap callback#43
gfazioli merged 4 commits intomasterfrom
feat/snap-points-enhancements

Conversation

@gfazioli
Copy link
Copy Markdown
Owner

Summary

Builds on top of #37 (merged) with the four enhancements we agreed on:

Enhancement Prop / API Closes
Percentages + responsive sets snapPoints now accepts Array<number | string> and ResponsiveValue<...> #39
Snap relative to the "after" pane snapFrom?: 'before' | 'after' (default 'before') #40
onSnap callback onSnap?: (point: number | null) => void on Split.Resizer #41
Visual hook data-snapping attribute on the resizer root while in a snap zone

Plus:

  • normalizeSnapPoints now rejects negative values and malformed percentage strings, and trims whitespace from valid ones.
  • useResponsiveValue treats arrays as plain values (previously it would have tried to match an array as a breakpoint map).
  • New documentation section + dedicated demo (snapAdvanced).

onSnap callback semantics

  • Fired once when the resizer enters a snap zone, with the resolved pixel value of the snap point (expressed in the snapFrom reference — so for snapFrom="after" you get back the target size of the right/bottom pane, matching what the user passed into snapPoints).
  • Fired once when it leaves, with null.
  • Not fired on every pointer tick.

API shape decisions

  • onSnap lives only on Split.Resizer (not cascaded via context). Rationale: with multiple resizers, a single callback on Split would receive events from all of them without a way to distinguish. Keeps v1 simple. A cascaded-with-meta variant can come later.
  • snapFrom is a single prop (not per-point). User preference: keep the simple case simple; the mixed case is rare enough to defer.

Test plan

  • yarn test — 27/27 jest tests (17 snap helpers + 10 Split integration), 0 oxlint warnings, typecheck + format clean.
  • yarn clean && yarn build && yarn docgen && yarn docs:build — all OK.
  • Visual check at http://localhost:9281 (responsive sets, percentage resolution, onSnap reactivity, data-snapping attribute).

Follow-up

After merge, release as minor (4.0.7 → 4.1.0). Changelog will credit @woutervanerp for the original snap points feature (already merged via #37) and cover these enhancements.

…llback

Extends the snap points feature introduced in #37 with:

- Percentage snap points (e.g. `'50%'`), resolved against the combined size
  of the two adjacent panes.
- Responsive snap sets via Mantine breakpoint maps
  (e.g. `{ base: [200], md: [300, 500] }`). Closes #39.
- `snapFrom?: 'before' | 'after'` prop on `Split` and `Split.Resizer` to
  interpret each snap point as the target size of the pane after the
  resizer instead of the pane before. Closes #40.
- `onSnap?: (point: number | null) => void` callback on `Split.Resizer`,
  fired once on snap enter (with the resolved pixel value in the
  `snapFrom` reference) and once on exit (with `null`). Not fired on
  every pointer tick — state-based by design. Closes #41.
- `data-snapping` attribute on the resizer root while inside a snap
  zone, for CSS-driven visual feedback.
- Stricter `normalizeSnapPoints`: rejects negative values and malformed
  percentage strings; trims whitespace from valid percentage strings.

Also extends `useResponsiveValue` to treat arrays as plain values so
that `ResponsiveValue<T[]>` works correctly for array props.
Copilot AI review requested due to automatic review settings April 17, 2026 13:35
Copy link
Copy Markdown
Contributor

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

Extends Split/Resizer snap functionality to support percentage and responsive snap point sets, add snapFrom to snap relative to the after pane, and introduce an onSnap callback + data-snapping attribute for UI feedback.

Changes:

  • Expand snapPoints to accept number | string (percentages) and responsive breakpoint maps; add snapFrom support.
  • Add onSnap(point | null) eventing and data-snapping state while in a snap zone.
  • Update tests and docs with new behaviors and an “advanced snapping” demo.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
package/src/hooks/use-responsive-value.ts Treat arrays as scalar values so responsive resolution doesn’t mis-handle snapPoints arrays.
package/src/Split.tsx Plumbs snapFrom through Split → context so resizers can inherit it.
package/src/Split.test.tsx Adds integration tests for percentage snapping, snapFrom="after", onSnap, and data-snapping.
package/src/Resizer/snap.ts Adds snap point parsing/validation, percentage resolution, snapFrom, and reporting of snappedPoint.
package/src/Resizer/snap.test.ts Adds/updates helper tests for new snap point types and snappedPoint reporting.
package/src/Resizer/SplitResizer.tsx Resolves responsive snap sets, tracks snapping state, emits onSnap, and exposes data-snapping.
docs/docs.mdx Documents percentage/responsive snap sets, snapFrom, onSnap, and data-snapping; adds advanced demo section.
docs/demos/index.ts Exports the new snapAdvanced demo.
docs/demos/Split.demo.snapAdvanced.tsx Adds a new demo showcasing percentages, snapFrom="after", responsive sets, and onSnap.

Comment thread docs/demos/Split.demo.snapAdvanced.tsx Outdated
Comment thread docs/demos/Split.demo.snapAdvanced.tsx
Comment thread docs/demos/Split.demo.snapAdvanced.tsx
Comment thread docs/docs.mdx
Comment thread docs/docs.mdx Outdated
Comment thread docs/demos/Split.demo.snapAdvanced.tsx Outdated
Introduces a 4th docs tab (Upgrade guide) for documenting breaking changes
and step-by-step migration instructions per major version, keeping them
out of the main Documentation flow.

- DocsTabs: new optional `migrations` prop. When truthy, renders a tab
  next to Documentation / Props / Styles API using IconArrowBarUp.
  When omitted the tab is not rendered — default behavior for repos that
  do not need it.
- migrations.mdx: collects v3 → v2 upgrade instructions previously
  occupying the top ~160 lines of docs.mdx. Content is the same,
  reorganized under a ## Upgrade guide title and reverse-chronological
  ## v3 / ## v2 sections so the TOC laterale acts as navigation.
- docs.mdx: replaces the in-page migration sections with a single
  callout linking to /?t=migrations.
- DocsTabs.module.css:
  - Add padding-top to .main so docs/migrations panels match the
    vertical spacing of data-secondary panels (Props / Styles API).
  - Neutralize margin-top of the first MdxTitle in .main to avoid
    double spacing above the first heading.
  - For the migrations panel only, drop the parent max-width and apply
    flex: 1 / min-width: 0 on .main so the text-only content fills the
    available width consistently with Documentation.
- pages/index.tsx: imports migrations.mdx and passes it to DocsTabs.
@gfazioli gfazioli merged commit dd242df into master Apr 17, 2026
1 check passed
@gfazioli gfazioli deleted the feat/snap-points-enhancements branch April 17, 2026 15:40
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.

2 participants