morph_kit 0.1.1
morph_kit: ^0.1.1 copied to clipboard
Adaptive, responsive layouts that morph between phone and desktop forms - list-detail, split panes, adaptive modals - keeping live widget state across resizes.
Changelog #
0.1.1 #
- Shortened the pubspec description to pub.dev's 60-180 character guidance (the 0.1.0 description was flagged by package analysis and cost pub points).
Commits since v0.1.0 (3)
- f7e29bf release: v0.1.1
- cc99e94 chore: promote dev to prod (0.1.1) (#4)
- 88f7b05 fix: shorten pubspec description to pub.dev's 60-180 char guidance
0.1.0 #
First release — adaptive layout widgets that morph between phone and desktop forms.
- Widgets:
ListDetailLayout(list + selected detail) andSplitLayout(two always-present panes) switch between slide-over (compact) and side-by-side (expanded) at a configurable breakpoint. - State preservation: pane widget instances survive the compact ↔ expanded morph — drafts, scroll positions, and in-flight animations carry across a window resize.
- Adaptive modal:
showAdaptiveModalpresents a real Material dialog on expanded widths and a real Material bottom sheet on compact — and swaps between the two real routes on resize with a container transform that carries the live content, preserving state and the awaited result. - Overlay mode: the compact detail can render in the Navigator's overlay, covering bottom navs and tab bars; inactive kept-alive tabs suppress their overlays automatically.
- Route mode:
CompactDetailMode.routehosts the compact detail in a real page route — the app'sPageTransitionsTheme(platform transitions, predictive back, edge swipes) applies natively, and the detail element still reparents into the side-by-side pane on resize. - Accessibility: in inline and overlay modes the open detail scopes as a route for screen readers, covered content leaves the semantics tree, and
DismissIntent(Escape) dismisses when focus is inside the detail — route parity without a route. - Crossing motion: breakpoint crossings animate in both directions — including the empty placeholder pane, which reveals and retreats at the end edge. With an open detail — into compact the detail grows out of its pane (inline/overlay) or plays the route's real entrance (route mode); into expanded the list slides in beside the full-width detail, laid out at its final width so content never reflows (
ExpandedEntryStyle.resizeopts into live reflow). Pane geometry keeps tracking window drags without motion. - Empty-pane behaviors:
ExpandedEmptyBehavior.listOnlygives the list the full expanded width until a selection reveals the detail pane from the end edge (the Material "supporting pane" shape); the default keeps the persistent placeholder pane. The auto-select-first school is documented as an app-side controller recipe. - Divider memory: a dragged divider position survives compact spells and rebuilds —
PaneConfigandPaneAnchorcompare by value, so configs constructed inline inbuildnever reset the width model.PaneWidthMemory.resetOnReentryopts into a fresh divider on every return to expanded. - Native passthroughs:
ModalConfigforwards Flutter's route parameters under Flutter's own names (barrier label, sheet constraints, max-height ratio, anchor points, focus/traversal behavior, entranceAnimationStyles); visual styling stays onDialogThemeData/BottomSheetThemeData. Pane snap-settle duration/curve and the divider hit-zone width arePaneConfigknobs. - Divider: draggable with min/max clamps, optional anchor snap points with a settle animation, and ratio or fixed-pixel resize modes;
HandleDividerandMaterialDividership as ready-made visuals. The full interaction contract rides onDividerState(dragging / settling / at-limit / collapsed / focused). - Snap-collapse: force the divider past a pane's minimum and it snaps shut (VS Code mechanics: half-minimum threshold, remembered width, spring-back short of it).
PaneCollapsibleopts in per side;collapsedSizekeeps an icon rail or hides fully; collapsed content stays laid out at its minimum inside a clip.HandleDividerparks as a pull tab. Directional API holds forSplitLayout's end-positioned primary. - Divider keyboard + screen readers: the WAI-ARIA window-splitter pattern — Tab focus, arrows resize, Enter collapses/restores, Home/End jump to the limits, double-click resets to the default width; screen readers see an adjustable element announcing the pane's share.
- Icon-rail slots:
collapsedListBuilder/collapsedDetailBuilder(andSplitLayout's primary/secondary equivalents) give a collapsed pane purpose-built content laid out at the realcollapsedSize— the VS Code activity-bar shape — while the pane parks offstage with its state alive. Both panes reparent via GlobalKey, so collapse, restore, and mode switches move the live element instead of rebuilding it. - PaneScope: descendants of either pane read the collapse state (including
collapsedSize, so a pane can tell a fully-hidden neighbor from a visible rail) and callcollapse/restore— the hamburger-in-the-surviving-pane recipe, without threading callbacks. - Controller:
ListDetailControllerwith an animation-awareisDetailVisiblefor app-shell timing; router-agnostic — the example ships full URL-sync reference wiring. - Platforms: pure Flutter, no platform code — every platform.
Commits since initial (49)
- afb71a9 release: v0.1.0
- 76aaa99 chore: promote dev to prod (0.1.0) (#3)
- ba49899 fix: sweep camelCase and display-name rename variants in iOS/macOS projects
- 7778996 fix: complete the rename sweep — platform files, deploy script, issue template
- b07cf56 Merge branch 'prod' into dev
- d6aff4b feat!: rename package to morph_kit
- 68e96ba chore: promote dev to prod (0.1.0) (#2)
- 5700879 docs: full audit — fleet README structure, fossil claims fixed, docs de-drifted
- 22173b0 docs: fix fossil README block arguing against route mode we now ship
- 725b9e6 docs: rewrite README around the three widgets
- 1d0fa69 feat!: rename AdaptiveSplit to SplitLayout
- 7d301a9 feat!: remove ThreePaneLayout — the package grows by extraction, not prediction
- c86c431 feat: parked panes arrive docked — crossings skip the collapse replay
- ebb979a fix: min-wins guard on share-percent bounds — clamp throws on inverted limits
- 806b8b0 fix: rail taps navigate without expanding; gate detail affordance; empty pane collapses into rail slot
- 4c92042 feat: collapsed icon-rail slots — rail content at real width, pane parked alive
- d078f4e feat(example): Workbench tab — ThreePaneLayout demo under Ops
- 1435d26 feat: ThreePaneLayout — role-priority pane scaffold (Compose-shaped)
- ef6c058 feat: divider keyboard/a11y (WAI-ARIA splitter) + PaneScope + double-click reset
- eab3e3d feat!: snap-collapse panes (VS Code spec) + DividerState contract
- 14c8aa0 feat: pane collapsing — edge anchors to zero + double-tap divider gesture
- bfaacde docs(example): status strip moves to MaterialApp.builder — chrome above every route
- 5a45d45 feat: native passthroughs on ModalConfig + PaneConfig settle/hit-zone knobs
- 33ce31d feat: empty placeholder pane animates its breakpoint crossings both ways
- 4b23020 fix: listOnly divider rides the revealing seam instead of popping in at settle
- 47e8d3e feat: ExpandedEmptyBehavior.listOnly — on-demand detail pane, plus the three-schools docs
- 1a4e886 fix: crossing morph seeds from the divider's fraction through the curve inverse
- cafb835 feat: PaneWidthMemory knob (persist / resetOnReentry) + crossing-logic extraction
- e2a7269 feat: reveal-style expand entry (with resize opt-in) + divider position memory
- 1b77b1b feat: crossing motion on every breakpoint crossing, both directions
- 14b4c91 feat: crossing motion on discrete breakpoint jumps — pane growth or real route entrance
- 07588f9 test: use flagsCollection over deprecated hasFlag
- 5e3d7d2 feat: a11y route parity for inline/overlay details — semantics scoping, blocked covered content, Escape dismissal
- 55927d5 docs: per-mode contracts on CompactDetailMode + README mode-picker table
- 1789a52 fix: route mode survives hidden-tab breakpoint crossings and live mode flips
- 99c6eda fix: route re-show after hidden resize — schedule the frame, trust same-frame paint
- ffb6cf4 fix: settings changes reach routed subtrees — each layout listens itself
- 7e950db feat: CompactDetailMode.route — the compact detail as a real page route
- 8fa37c5 fix: sample the natural width invisibly and retake it on retarget
- 319f5a3 fix: content follows the container both directions; add ModalConfig.backgroundColor
- c2f99d9 chore: drop leftover diagnostic captures
- 6aebdda fix: flight paints in lockstep with its lerp — no Material self-tween, no phantom shadow
- 04ac579 fix: content reflows with the morphing container instead of being cropped
- d9bfa46 feat: the flight becomes the destination — ghost routes until landing
- 11256a7 fix: land the morph on true final geometry and clip both resting forms
- 5ff4960 feat: container transform for the modal — the flight carries the live content
- ed4d13e feat: adaptive modal — real Material routes with a live dialog-sheet swap
- 705f6d7 docs: frame the package as a growing family of adaptive layouts
- 04b28fd feat: adaptive list-detail and split layouts