flutter_folderview 0.12.0
flutter_folderview: ^0.12.0 copied to clipboard
A customizable Flutter widget for displaying hierarchical data in tree and folder views with rich theming support.
0.12.0 #
- feat: a mouse-wheel notch over the view animates to its target instead of jumping (#100). The main vertical and horizontal scroll controllers are now
SmoothScrollControllers fromflutter_smooth_wheel_scroll, moving asWheelMotion.spring(): 400 ms, no bounce. The scrollbars follow the list on every frame of a motion. Trackpad scrolling, dragging, the scrollbar and programmatic jumps behave as before.- What a consumer sees differently. After a wheel notch, the scroll offset reaches its target over several frames, not at once. A widget test that wheel-scrolls and reads the offset after a single
pumpnow has to pump until the motion settles. - The Scale Modifier + wheel anywhere over the view still proposes a Scale and, while
blockModifierScrollis in effect, does not scroll.
- What a consumer sees differently. After a wheel notch, the scroll offset reaches its target over several frames, not at once. A widget test that wheel-scrolls and reads the offset after a single
- feat:
FolderView.wheelMotionchooses how the wheel moves the view (#101). The default isWheelMotion.spring(). Other options areWheelMotion.spring(duration:, bounce:),WheelMotion.curve(duration:, curve:)with anyCurve, andWheelMotion.lerp(timeConstant:).nullmoves the view at once on every notch, as before 0.12.0.- It can change at runtime. The next notch uses the new motion, and the scroll position is kept.
WheelMotionis re-exported, so no import offlutter_smooth_wheel_scrollis needed. How far a notch travels is app-wide, throughSmoothWheelBindingin that package, and this one does not install it.
- fix: after horizontal scrolling, a row takes taps and hovers across its whole visible width (#136). The rows were painted shifted, but hit testing stopped at the first viewport-width of the row. Past that point a tap fired no
onNodeTapand selected nothing, and a hover raised no row card. Scrolled to the end, the visible part of every row was dead. Reproduced in a 400 px view scrolled by 300: a tap at x 320 inside the row worked, and at 500 it did nothing.- Also fixed: a row's widget state is no longer rebuilt each time the horizontal offset leaves or returns to 0. Before, a stateful node icon was created again on every such crossing.
- What a consumer sees differently. Taps, double taps, secondary taps, hovers and tooltips now reach the rows wherever they are visible after a horizontal scroll. Painting and layout are unchanged.
- fix: while the modifier scroll is blocked, Ctrl/Cmd+wheel over a scrollbar no longer scrolls (#114). Reproduced in a 400 px view with
onScaleChangedset: one 300 px Ctrl+wheel notch over the vertical scrollbar proposed a Scale and scrolled the view by 300. A sideways notch over the horizontal scrollbar scrolled it too. Now the notch proposes the Scale and moves nothing, as it already did over the rows.- What a consumer sees differently. Ctrl/Cmd+wheel zooms only, wherever the pointer is over the view. A wheel over a scrollbar without the modifier still scrolls at once. Dragging a thumb works with or without the modifier held. With
blockModifierScroll: false, nothing changes.
- What a consumer sees differently. Ctrl/Cmd+wheel zooms only, wherever the pointer is over the view. A wheel over a scrollbar without the modifier still scrolls at once. Dragging a thumb works with or without the modifier held. With
- fix: with
rowSpacingabove 0, the connector line meets the row at its content's centre (#118). The horizontal stub, and a last child's vertical end, were drawn atrowHeight / 2, but each row isrowHeight + rowSpacingtall with its content centred in it. AtrowHeight40 androwSpacing10, the stub sat at y 20 against a label centred at y 25. It is now at 25. WithrowSpacing0 nothing changes.rowSpacing's documentation now says what it is: extra height added to every row, not an empty gap between rows.
- fix:
ExpandIconTheme.colorandexpandedColortake effect onlight()anddark()(#120). Both factories gave the chevronIconits own grey, and anIconwith its owncolorignores the ambientIconThemethe two fields are applied through. Probed withcolorred andexpandedColorgreen onlight(): every chevron stayed0xFF616161. Now collapsed rows are red and expanded rows green.- What a consumer sees differently. The default look is the same:
light()'s chevron is stillColors.grey.shade700,dark()'sColors.grey.shade400. But the grey moved:expandIconTheme.widgetis nowIcon(Icons.chevron_right, size: 20)with no colour, andexpandIconTheme.coloris the grey rather thannull. Code that reads either value sees the new one.expandedColoris stillnull, so expanded rows takecolor. - A custom
widgetwith its own colour keeps it, as before. The two fields' documentation now says they colour only a widget without a colour of its own.
- What a consumer sees differently. The default look is the same:
- fix: a label from a
labelResolveris measured. Content width was measured fromnode.labelwhile the row drew the resolved label, so a resolved label longer than the raw one was cut with an ellipsis where the view should have scrolled horizontally. Measurement and rendering now read the label from one place (RowMetrics.label), the way they already shared the text style. - fix: content width is re-measured when the theme reaches the view from an ancestor
FolderViewTheme, or when the ambientbodyMediumchanges. Only a newtheme:argument used to trigger it, so a font change from either source left rows ellipsized at the old width. - fix:
onSecondaryNodeTapfires on Folder and Parent rows, not only on Child rows. ADR-0003 names it as the way to track a focused container, which are not selectable.onDoubleNodeTapremains Child-only, and both callbacks now say which tiers they fire on. - fix: without
onDoubleNodeTap, every tap on a Child row firesonNodeTap(#95). A Child row used to keep a double-tap window with nothing behind it, so a second tap withinChildNodeTheme.clickInterval(300 ms by default) fired nothing. Reproduced at 50 ms and at 250 ms, an ordinary pace for tapping a Child off and on again. WithonDoubleNodeTapset, nothing changes: a double tap still firesonNodeTapon the first tap andonDoubleNodeTapon the second. - BREAKING:
NodeTooltipTheme.controlleris replaced bycontrollerResolver, aJustTooltipController? Function(Node<T>)(#133). A Tier'stooltipThemereaches every Node of the Tier, so one controller was attached to every built label'sJustTooltip. just_tooltip lets a controller drive one tooltip: with two Nodes in the Tier, debug failedThis JustTooltipController is already attached to a tooltip, and release drove whichever label was built last. The resolver gives each Node its own controller.- What a consumer sees differently. Code that sets
controllerno longer compiles. Migratecontroller: ctocontrollerResolver: (node) => node.id == 'x' ? c : null, or to a map,(node) => controllers.putIfAbsent(node.id, JustTooltipController.new). Return the same controller for a Node on every call, and never one controller for two Nodes. A controller drives its label while the row is built; ashow()made before that is applied once it is. As before, just_tooltip shows one tooltip at a time.
- What a consumer sees differently. Code that sets
- fix: a style returned by
textStyleResolveris scaled, on all three tiers, and so is one returned byChildNodeTheme.selectedTextStyleResolver(#127). Each tier'sscalemultiplied itstextStylebut passed the resolvers through as functions, so a resolved style kept its own size. At Scale 2, a Folder withtextStyle: TextStyle(fontSize: 16)drew 32 px, and one whose resolver returned the same style drew 16 px. Now both draw 32 px. A resolved style follows the rule of the field it stands in for:textStyle's (an unset size starts from the ambientbodyMedium) orselectedTextStyle's (an unset size stays unset).- What a consumer sees differently. At any Scale other than 1, labels styled by a resolver grow and shrink with the rest of the row, and are measured at that size. A resolver that returns
nullstill falls back to the scaled field. At Scale 1 nothing changes, andscale(1.0)still returns the theme itself.
- What a consumer sees differently. At any Scale other than 1, labels styled by a resolver grow and shrink with the rest of the row, and are measured at that size. A resolver that returns
- feat: in debug builds, a
FolderViewThemeof the wrong type is reported (#124).FolderViewTheme.of<T>andmaybeOf<T>look upFolderViewTheme<T>by exact type. So an untypedFolderViewTheme(data: FlutterFolderViewTheme.dark()), which is aFolderViewTheme<dynamic>, is not found by aFolderView<String>, and the view silently fell back tolight(). Now, when the lookup misses and aFolderViewThemeof another type is above, adebugPrintnames both types and the fix, once perT.- What a consumer sees differently. Nothing in release builds, and nothing for a correctly typed tree. The lookup and its fallback are unchanged.
FolderViewTheme.debugResetTypeMismatchWarnings()(@visibleForTesting) clears the once-guard. The class dartdoc and the README now show the typed form.
- What a consumer sees differently. Nothing in release builds, and nothing for a correctly typed tree. The lookup and its fallback are unchanged.
- fix: a scrollbar thumb stays inside its track box whatever
thicknesssays (#122). Withthickness: 20andtrackWidth: 8, the vertical thumb was painted from x = −12 (Android) or −14 (desktop) in the 8 px bar, so 12 to 14 px of it lay over the rows. The thumb is now painted at what fits:trackWidthless Material's cross-axis margin, which is 0 on Android and 2 elsewhere.- What a consumer sees differently. Only a
thicknessthat did not fit changes. The theme keeps the value it was given. With the defaults (thickness12,trackWidth16), nothing changes.
- What a consumer sees differently. Only a
- BREAKING:
FolderViewScrollbarTheme.trackVisibilityis removed (#122). It turned on the MaterialScrollbar's own track, painted inside the bar's box in Material's faint colour, never intrackColor. So a bar had two different tracks under one name. The box styled bytrackColor,trackWidthandtrackRadiusis now the only track.- What a consumer sees differently. Code that sets the field, in the constructor or in
copyWith, no longer compiles: delete the argument. With the defaultfalse, nothing changes at runtime. Withtrue, the faint inner track is gone. The theme's==,hashCodeandtoStringno longer include it.
- What a consumer sees differently. Code that sets the field, in the constructor or in
- BREAKING:
FlutterFolderViewTheme.animationDurationis removed (#116). Nothing has read it since the switch to a virtualized flat list, and expand and collapse are not animated. The tooltip themes' ownanimationDurationfields are unaffected.- What a consumer sees differently. Code that sets the field, in the constructor or in
copyWith, no longer compiles: delete the argument. Nothing changes at runtime, and the theme's==,hashCodeandtoStringno longer include it.
- What a consumer sees differently. Code that sets the field, in the constructor or in
- BREAKING:
NodeTooltipTheme.hideOnEmptyMessageis removed (#131). It never had an effect throughFolderView. A label tooltip with no builder and an empty ornullmessage is not built at all, sofalsecould not bring up an empty tooltip. With a builder, there is always content.- What a consumer sees differently. Code that sets the field, in the constructor or in
copyWith, no longer compiles: delete the argument. Nothing changes at runtime.
- What a consumer sees differently. Code that sets the field, in the constructor or in
- BREAKING: minimum Flutter is now
3.32.0(Dart3.8.0), up from3.13.0(Dart3.1.0) (#100).- What a consumer sees differently. On Flutter 3.13–3.31 this version does not resolve, and
pubstays on the previous version. No class, method or field changed because of the floor. - Why. This package now depends on
flutter_smooth_wheel_scroll^0.1.3, which declares Flutter>=3.32.0/ Dart^3.8.0. It usesSpringDescription.withDurationAndBounce(flutter#164411), and 3.32.0 is the first stable release to carry it. The floor is the max of what the dependencies demand:max(3.13, 3.32). - The source was reformatted, with no behaviour change.
dart formatpicks its style from the package's language version, and from Dart 3.7 that is the tall style. That reformat is a separate, mechanical commit.
- What a consumer sees differently. On Flutter 3.13–3.31 this version does not resolve, and
- deps:
just_tooltip^0.5.1, up from^0.4.4. It declares the same Flutter3.32.0/ Dart3.8.0floor this package already has, so the floor does not move.NodeTooltipTheme.enableTapis unchanged.JustTooltip's ownenableTapis deprecated upstream, so the label tooltip now passestap: TooltipTap.claimfortrueandTooltipTap.noneforfalse, which upstream documents as identical.- What a consumer sees differently. These come from just_tooltip, and both tooltips get them unless noted:
- A screen reader reads a label tooltip's
messagealong with the label. AtooltipBuilderlabel tooltip and the row card are not read. - Escape closes the tooltip that was shown most recently.
- A tooltip draws with the
Theme,Directionality,DefaultTextStyleandMediaQueryaround theFolderView, not the app-level ones. - A label tooltip is
interactive: falseby default, and its body now lets the pointer through. A tap on it reaches the row underneath, and anything clickable in its content can no longer be clicked. Setinteractive: truefor content that should be reachable.
- A screen reader reads a label tooltip's
- A tap on the label with
enableTapstill opens the tooltip and still takes the tap from the row. just_tooltip's newTooltipTap.observemode, which would let the row receive the tap too, is not used (#134).
- What a consumer sees differently. These come from just_tooltip, and both tooltips get them unless noted:
- docs: the row card's fixed pointer anchor is explained by what it actually prevents (#138). The
rowTooltipBuilderandRowTooltipThemedartdocs and the README said anchoring to the row's rect would aim off screen once the view scrolls horizontally. Since just_tooltip 0.4.2, a rect anchor aims at the visible part of the rect, so a wide row's card would open at the view's centre: on screen, but not where the user is looking. That is the reason now given. The anchor is unchanged and still not configurable. No behaviour change. - docs:
blockModifierScroll: falsealso turns zoom-by-wheel off (#112).onScaleChangedis called only while the modifier scroll is blocked, so withfalseCtrl/Cmd+wheel scrolls and proposes no Scale. TheonScaleChanged,scaleStepandblockModifierScrolldartdocs, the README andGLOSSARY.mdnow say so, and the README gives all six cases. The README's default was also wrong: it isnull, followingonScaleChanged, nottrue. Its custom-zoom recipe withisScaleModifierPressed()now passesblockModifierScroll: true. Without it, the same wheel event zoomed and also scrolled the view. No behaviour change. - docs:
onNodeTapandonDoubleNodeTapstate that a Ctrl+tap is always a single tap.
0.11.2 #
- deps:
just_tooltip^0.4.4(#71). Unlike0.11.1's bump, this one is not documentation of intent: raising the floor is what carries the fix to a project that already depends on us.pubdoes not re-resolve a lockfile that still satisfies its constraint, so^0.4.3left an installed0.4.3exactly where it was — measured, by pinning this repo's own lock to the floor:pub getmoved it to0.4.4under^0.4.4and not at all under^0.4.3. No new SDK bound; the Flutter3.13.0floor is still0.4.2's. - docs:
just_tooltip0.4.4narrowed its nesting-suppression rule — the innermost tooltip under the pointer that has something to draw now wins, where before having nothing to draw was enough to take an ancestor's place. Two places stated the old rule as a fact about the package:FolderView's internal row-card dartdoc, which ships to the API docs, and the characterisation-test header that pins the behaviour. Both now state the rule that 0.4.4 actually implements.- No behaviour changes here, and none is claimed.
flutter_folderviewnever builds an empty tooltip — a Node with no label tooltip content is not wrapped, and nor is a row whoserowTooltipBuilderreturnsnull— so the new qualifier can never bite, and the existing tests pass against0.4.4untouched. The README's account of the two tooltips describes those guarded tooltips rather than the package's rule, and remains correct as written.
- No behaviour changes here, and none is claimed.
0.11.1 #
- fix: a row card no longer dies when the cursor returns to the row from the card itself (via
just_tooltip 0.4.3). Leaving the card armed a 100 ms hover bridge that re-entering the row never cancelled: it fired unseen, faded the card out, and a pointer already inside the row sends no further enter event to revive it. The card vanished about 250 ms after the cursor came home — a quarter second removed from its cause, and easy to trigger, since an interactive card anchored at the pointer is drawn right beside it. Reproduced against0.4.2before the bump: the card was gone 450 ms after the round trip and never returned. - deps:
just_tooltip^0.4.3. Changes no API and no SDK bound —0.11.0's^0.4.2constraint already resolved it, so this documents intent. The Flutter3.13.0floor is0.4.2's and unchanged. - docs: the README now states the minimum Flutter version beside the install snippet. It never did, while
0.11.0raised it from3.10.0.
0.11.0 #
- feat:
FolderView.rowTooltipBuilder(#44) — a card shown while the pointer is anywhere over a Node's rendered row. Returnnullfor a Node that should not have one. It is declared once on theFolderView, not per Tier, because it explains the Node, where the existingNodeTooltipThemetooltip attaches to the icon-and-label content and explains the label. Both can be enabled at once.- The card is anchored at the pointer, and this is not configurable. A row is laid out at the tree's content width, not the viewport's, so anchoring to the row's rect would aim at a centre that leaves the screen as soon as the view scrolls horizontally.
- feat:
FolderView.rowTooltipTheme— aRowTooltipThemecovering the card's presentation and behaviour:interactive,waitDuration,showDuration,enableHover,direction,alignment,offset,crossAxisOffset,screenMargin, the animation fields,onShow/onHide, andsurface. Without it the card was frozen atjust_tooltip's defaults — shown the instant a pointer crossed a row, with no way to delay it or to stop it holding the cursor.surfacedefaults toJustTooltipTheme.bare(), so the tooltip draws no chrome around a card that draws its own. Give it a realJustTooltipThemewhen the builder returns unadorned content.interactivedefaults totrue. The card is anchored at the pointer, so it is drawn beside the cursor and a small movement enters it; and its contents are the kind a user may want to reach. The label tooltip's default is the opposite, and deliberately so — it explains text you read, then leave.- The anchor is the one knob the theme does not expose. See above.
- The two divide the row. Only one tooltip is ever visible — the innermost under the pointer — and a label tooltip claims exactly the glyphs it explains. The row card takes everything else: the indent, the icon, the expand chevron, the space beside a short label. Enable both.
- The label tooltip now wraps the label's
Textrather than the icon-and-labelRow. It previously covered the icon, and — becauseFlexiblegrows a label to fill its row, and a row is as wide as the tree's longest label — on the widest row it covered the entire row, leaving that Node's card unreachable. Matchesflutter_table_plus, where a cell's text tooltip wraps the bareText: a text tooltip belongs to the glyphs. TooltipAnchor.childtherefore now centres a label tooltip on the glyphs rather than on the icon-plus-glyphs box, moving it right by half the icon's width.
- The label tooltip now wraps the label's
- feat:
NodeTooltipTheme.anchor(#42). A node's tooltip attaches to its icon-and-label content, and a long label fills its row — so a tooltip anchored to that rect appears at the row's centre, which can be far from where the user is actually pointing, and outside the view entirely once the tree scrolls horizontally.anchor: TooltipAnchor.pointerkeeps the same hover region but places the tooltip at the cursor.TooltipAnchoris now re-exported. Defaults toTooltipAnchor.child, the behaviour shipped in0.10.2, so existing tooltips are unchanged.- The anchor is captured when the tooltip is shown and does not follow the pointer, so
interactivetooltips stay reachable. Tap-triggered tooltips anchor at the tap; acontroller-driven show with no pointer present falls back to the label's rect. - Against a point there are no target edges to align to, so under
TooltipAnchor.pointerthealignmentfield selects which of the tooltip's own edges lands on the pointer. anchordoes not widen the hover region — a short label leaves the space to its right raising no tooltip under either anchor. For that, userowTooltipBuilderabove.
- The anchor is captured when the tooltip is shown and does not follow the pointer, so
- note:
TooltipRegistry(added injust_tooltip 0.3.0) is deliberately not re-exported.rowTooltipBuilderis the first place this package nests one tooltip inside another, and it needed no registry:just_tooltip 0.4.0suppresses an ancestor whenever a descendant holds the pointer, regardless of registry. Exposing it would grow the public surface for a use case — isolating aFolderView's tooltip group from the host app — that has not yet appeared. - deps:
just_tooltip^0.4.2, which raises the minimum Flutter to3.13.0(Dart3.1.0), up from3.10.0. Its ancestor clip walk readsRenderObject.parent, which wasAbstractNode?— a type with nodescribeApproximatePaintClip— until Flutter 3.13.flutter_folderviewdeclared>=3.10.0while its^0.4.0constraint already resolved0.4.2, so that floor had become a promise it could not keep. - fix: a label tooltip is no longer painted outside the
FolderView(#47). When a tree scrolls horizontally, a long label's rect extends past the view, andTooltipAnchor.childaimed at its centre — a point nobody could see.screenMarginnever objected: it confines the tooltip to the enclosingOverlay, usually the whole app.just_tooltip 0.4.2now targets the visible part of a clipped child, so the tooltip lands inside the view. Pre-existing; every version with tooltips had it.- Two further
just_tooltipfixes come along: a visible tooltip now re-aims when its child moves (scroll, resize, insertion above it) and hides once the child is clipped away entirely; and the target rect now follows the child's paint transform, so aTransform.scalebetween a node and theOverlayno longer mis-sizes it.
- Two further
0.10.2 #
- deps: Bump
just_tooltipto^0.4.0. Not breaking forflutter_folderview: nothing was removed fromjust_tooltip's API, the re-exportedJustTooltipControlleris unchanged, and its one behaviour change — a nested tooltip now suppresses its ancestors — cannot be reached from here, sinceFolderViewwraps exactly oneJustTooltipper node label and never nests them. Node tooltips gainjust_tooltip's fix for tooltips laid out in anOverlaythat does not fill the window from its origin: under a nestedNavigator, an insetOverlay, or an embedded Flutter view, a node's tooltip was displaced by the Overlay's offset and had its auto-flip andscreenMarginclamping measured against the wrong bounds. Placing aFolderViewinside such a host now positions its tooltips correctly. Noflutter_folderviewAPI changed. - note:
just_tooltip 0.4.0addsTooltipAnchor, which anchors a tooltip at the pointer instead of the child's rect. It is deliberately not re-exported yet:NodeTooltipThemehas noanchorfield, so the enum would be visible but unusable. Exposing it is aflutter_folderviewfeature decision, tracked in #42 along withTooltipRegistry, whichjust_tooltip 0.3.0added and which is likewise not re-exported.
0.10.1 #
- perf: Remove the per-row
Materialfrom node rows.CustomInkWellno longer wraps each row in its ownMaterial > Ink > InkWell; insteadFolderViewContentprovides a single transparentMaterialonce above the row list, and every row's ink (splash / highlight) paints onto that shared surface. Profiling a large tree under fling scroll showed the per-row Material crossed the 16 ms frame budget noticeably more often than the shared-Material variant. Ripple, hover, highlight, and selection are visually unchanged; the publicFolderViewAPI is unchanged (CustomInkWellis an internal row primitive and now requires an ancestorMaterialby design).
0.10.0 #
- BREAKING: Bump
just_tooltipto^0.3.0. ItsJustTooltipController— re-exported here and usable viaNodeTooltipTheme.controller— is no longer aChangeNotifier:shouldShowandaddListener/removeListener/disposeare removed. Drive it withshow()/hide()/toggle()and observe visibility via the tooltip'sonShow/onHidecallbacks.just_tooltipalso narrowed its exports (JustTooltipPositionDelegate,TooltipShapePainter,JustTooltipOverlayare now internal). Noflutter_folderviewAPI changed. - perf: Pack a
FlatNode's ancestor tree-line flags into anintbitmask instead of a per-nodeList<bool>, removing a heap allocation for every flattened node (the flags are read only for painted rows). Flatten is ~3× faster and the flat-list heap footprint roughly halves on large trees. Tree-line rendering is unchanged; tree depth is capped at 63. - perf: Apply incremental expand/collapse in place on the cached flat list instead of copying the whole list on every single-node toggle — ~1.7× faster toggles on large trees. Visible rows and scroll anchoring are unchanged.
- perf: In
RowMetrics.maxWidth, merge the effective text style once per tier instead of once per node, removing the per-nodeTextStyleallocation on every data / scale / theme change (~5.5× faster on the warm measurement path). The returned width is unchanged, so horizontal scroll extent and clipping are identical. - test / ci: Add widget tests for the
FolderViewinteraction, selection, view-mode, and modifier+wheel scale-gesture contracts; add anintegration_testharness driving the example app end-to-end (boot, expand, select, zoom, view-mode switch); add a GitHub Actions analyze + test workflow; addbenchmark/microbenchmarks and heap-footprint measurements for the flatten / projection / maxWidth hot paths.
0.9.0 #
- refactor: Decentralize content scaling — each theme class now exposes its own
scale()method, replacing the prior centralized_applyScaleimplementation. Existing usage (FolderView(scale: ...)) is unaffected. - feat: Add
FlutterFolderViewTheme.scale({required factor, required defaultFontSize})andFlutterFolderViewTheme.scaledForContext(BuildContext, double)for callers who want a scaled theme outsideFolderView(custom previews, integration tests, etc.). - docs: Add
CONTEXT.md(domain glossary) and ADRs0001(scrollbars excluded from scale),0002(caller owns interaction state),0003(selection tier-bound to child),0004(tooltips excluded from scale). - test: Add 31 unit tests covering the new scale API (identity short-circuit, positivity assertion, chrome exclusion for scrollbars/tooltips, null
fontSizeresolution againstdefaultFontSize).
0.8.1 #
- fix: Explicitly set
SystemMouseCursors.clickas the defaultmouseCursoron nodeInkWell— newer Flutter versions no longer auto-apply the click cursor on hover
0.8.0 #
- BREAKING: Rename
blockCtrlScroll→blockModifierScrollto accurately reflect platform-aware behavior (Ctrl on Windows/Linux, Cmd on macOS) - BREAKING:
blockModifierScrollis nowbool?(defaultnull) — automatically followsonScaleChangedwhen unset - feat: Add
onScaleChangedcallback andscaleStepparameter for built-in modifier+scroll zoom handling - feat: Export
isScaleModifierPressed()helper for library consumers implementing custom zoom logic - fix: Use platform-aware modifier key check to prevent Windows key from permanently triggering zoom mode
0.7.1 #
- feat: Add
blockCtrlScrollparameter toFolderView(default:true) — optionally disable Ctrl/Cmd + scroll blocking for users who don't need zoom-by-scroll
0.7.0 #
- feat: Add
scaleparameter toFolderViewfor content zoom (default:1.0) - feat: Scale all layout dimensions proportionally — row height, icon sizes, text size, spacing, line width, indentation, content padding, border radius
- feat: Scrollbar appearance (thickness, track width, colors) is NOT affected by scale
- feat: Preserve visible node on scale change with automatic scroll position adjustment
- feat: Ignore scroll events when Ctrl/Cmd is pressed to support zoom-by-scroll without unintended scrolling
- fix: Defer scroll position adjustment to post-frame callback to prevent
setState() called during builderror - fix: Scale content width clamp limit (
3x viewport * scale) to prevent text ellipsis at high scale values - example: Add scale slider to Layout controls and Ctrl/Cmd + mouse wheel zoom support
0.6.9 #
- fix: Pre-compute content width from all nodes (including collapsed) to prevent layout jumps on expand/collapse
- fix: Include
letterSpacingin text width calculation for accurate horizontal scroll sizing - feat: Add
calculateMaxContentWidthmethod toSizeServicefor upfront width calculation - example: Add long name test options (Folder/Parent/Child) to data generator for horizontal scroll testing
0.6.8 #
- feat: Bump just_tooltip to 0.2.5
- feat: Add
hideOnEmptyMessageoption toNodeTooltipTheme— suppress tooltip when message is empty (default:true) - feat: Support
TooltipAlignment.startTargetCenterandendTargetCenteralignments — arrow dynamically points to the center of the target widget
0.6.7 #
- fix: Bump just_tooltip to 0.2.3 — fix
borderColornot visible whenshowArrow: false
0.6.6 #
- fix: Tighten
just_tooltipconstraint to^0.2.2to fix pub.dev lower bounds compatibility check
0.6.5 #
- feat: Bump just_tooltip to 0.2.1
- feat: Add
animation(TooltipAnimation) option toNodeTooltipTheme— supportsnone,fade,scale,slide,fadeScale,fadeSlide,rotation - feat: Add
animationCurve,fadeBegin,scaleBegin,slideOffset,rotationBeginoptions toNodeTooltipTheme - feat: Export
TooltipAnimationfrom barrel file
0.6.4 #
- feat: Bump just_tooltip to 0.2.0
- feat: Add
showArrow,arrowBaseWidth,arrowLength,arrowPositionRatiooptions toNodeTooltipTheme - feat: Add
borderColor,borderWidthoptions toNodeTooltipTheme - feat: Add
screenMarginoption toNodeTooltipTheme - feat: Export
JustTooltipThemefrom barrel file
0.6.3 #
- fix: Bump just_tooltip to 0.1.5 (bugfix)
0.6.2 #
- feat: Add
interactive,waitDuration,showDuration,boxShadowoptions toNodeTooltipTheme(just_tooltip 0.1.4)
0.6.1 #
- fix: Tooltip hover area now limited to icon+label only, no longer triggers on empty row space
0.6.0 #
- BREAKING CHANGE: Migrate tooltip from Flutter
Tooltiptojust_tooltippackage - BREAKING CHANGE: Remove
TooltipPositionenum — replaced byTooltipDirection(top/bottom/left/right) - BREAKING CHANGE: Remove
margin,verticalOffset,waitDuration,boxShadowfromNodeTooltipTheme - BREAKING CHANGE: Remove
richMessage/richMessageResolver— replaced bytooltipBuilder/tooltipBuilderResolver(WidgetBuilder) - feat: Add
direction(4-directional),alignment(start/center/end),offset,crossAxisOffsetproperties toNodeTooltipTheme - feat: Add
elevation,borderRadius,paddingproperties toNodeTooltipTheme - feat: Add
controller(JustTooltipController) for programmatic tooltip show/hide - feat: Add
enableTap,enableHoverproperties for tooltip trigger control - feat: Add
animationDuration,onShow,onHideproperties toNodeTooltipTheme - feat: Tooltip now wraps both node icon and label instead of label only
- feat: Export
TooltipDirection,TooltipAlignment,JustTooltipControllerfrom barrel file
0.5.3 #
- fix: Recursively collect parent nodes from nested folders in tree mode
0.5.2 #
- perf: Replace
setStatewithValueNotifierfor horizontal scroll offset and hover state to prevent full widget tree rebuilds - perf: Eliminate recursive list spreading in
FlattenService.flatten()by reusing a single mutable list with add/removeLast pattern
0.5.1 #
- fix: Show full text on horizontal scroll instead of ellipsis-truncated text using
OverflowBox
0.5.0 #
- BREAKING CHANGE: Remove
isExpandedproperty fromNode<T>model - nodes are now immutable - BREAKING CHANGE: Add
expandedNodeIdsparameter toFolderView,FolderViewContent, andNodeWidgetfor external expansion state management - BREAKING CHANGE: Update
SizeServicemethods to acceptexpandedNodeIdsparameter - perf: Add incremental expand/collapse with
expandNode()andcollapseNode()methods inFlattenService - perf: Implement text width caching via
_textWidthCacheto reduce expensiveTextPainterlayout calls - perf: Add lazy content width measurement - calculate as nodes render instead of upfront O(N) traversal
- perf: Optimize scroll performance for 20k+ nodes with
Transform.translateanditemExtentonListView.builder - fix: Clamp scroll offset to valid range instead of skipping sync when out of range
- fix: Preserve scroll position on bulk expand/collapse (expandAll/collapseAll) using viewport anchor node
0.4.0 #
- feat: Add
labelResolvertoFolderNodeTheme,ParentNodeTheme,ChildNodeThemefor dynamic label resolution based onnode.data - fix: Update animation controller duration in
didUpdateWidgetwhen themeanimationDurationchanges at runtime
0.2.4 #
- feat: Add
labelResolverto all node themes for dynamic label display
0.2.3 #
- feat: Add
colorandexpandedColorproperties toExpandIconThemefor expand icon color theming
0.2.2 #
- refactor: Unified expand icon logic to ensure consistent node layout alignment
- refactor: Add
isChildparameter to_buildExpandIconfor proper child node spacing
0.2.1 #
- feat: Add
hoverColor,splashColor, andhighlightColorproperties to all node themes for interaction color theming - feat: Add comprehensive tooltip support with
NodeTooltipThemeclass for all node types - feat: Add
rowHeightproperty toFlutterFolderViewThemefor configurable row height - feat: Add
rowSpacingproperty toFlutterFolderViewThemefor vertical spacing between rows - refactor: Remove
iconToTextSpacingproperty from all node themes - now controlled via iconmargin.right
0.2.0 #
- BREAKING CHANGE: Migrate from unified
FolderViewTextThemeandFolderViewIconThemeto node-type specific themes (FolderNodeTheme,ParentNodeTheme,ChildNodeTheme,ExpandIconTheme) - feat: Add custom
Widget?support for each node type instead of hardcodedIconwidgets - feat: Add
openWidgetproperty for folder nodes (displayed when expanded) - feat: Add
paddingandmarginproperties for each widget type - feat: Add
clickIntervalproperty toChildNodeThemefor configurable double-click detection (default: 300ms) - feat: Add
animationDurationproperty toFlutterFolderViewThemefor configurable expand/collapse animation speed - feat: Add theme resolver functions (
widgetResolver,textStyleResolver,selectedTextStyleResolver,openWidgetResolver) for dynamic styling based on node data - feat: Add generic type support
<T>to all theme classes for type-safe access tonode.data
0.1.2 #
- fix: Fixed scroll position being reset when expanding/collapsing nodes by removing contentHeight from SyncedScrollControllers key
0.1.1 #
- fix: Fixed scroll position calculation when switching between view modes or expanding/collapsing nodes
0.1.0 #
- feat: Add dual view modes (Tree and Folder)
- feat: Add three node types (Folder, Parent, Child) for flexible hierarchy representation
- feat: Add multiple line styles (Connector, Scope, None) for visual tree structure
- feat: Add comprehensive theming system (icon, text, line, scrollbar, spacing, node style)
- feat: Add interactive features (selection, tap handlers, expand/collapse animations)
- feat: Add synchronized horizontal and vertical scrolling with custom scrollbars
- feat: Add depth-based indentation for nested nodes
- fix: Correct indent and line positioning for nested nodes based on depth level