artisanal_widgets 0.4.2
artisanal_widgets: ^0.4.2 copied to clipboard
Widget system for composable TUI components, built on top of the artisanal terminal toolkit.
Changelog #
0.4.2 #
- Require Dart SDK 3.13.0 or newer.
Added #
- Added
BoxConstraints.enforceto compose child size requests within authoritative parent bounds without inverted constraint intervals. - Added opt-in production UV renderer capture to
WidgetTesterviaenableRenderer: true, exposing raw ANSI output throughrendererOutput. UsealtScreen: truefor full-viewport capture instead of inline rendering. The default renderer-disabled test behavior is unchanged. - Added opt-in
enableNativeFrameCaptureandlatestNativeFramefor structured final UV cell snapshots.artisanal_captureuses this throughWidgetCaptureMode.renderedFrame; drawable payloads are not represented. - Added a model-backed interactive
TreeView.modelsurface for Artisanal's sharedTreeModel, including focus-aware keyboard navigation, pointer expansion and activation, custom row builders, bounded scrolling, and scrollbars. The originalTreeView(nodes: ...)API remains compatible. - Added
ResizableSplitView, a reusable horizontal or vertical split with a pointer-draggable separator and minimum pane extents. - Added controlled extents and zero-width/zero-height hidden separators to
ResizableSplitView, allowing panes such as integrated terminals to retain mounted state while being resized or collapsed.
Changed #
Stacknow reuses clean child layout and paint output during subtree-only repaints, reducing work for scrollbars and other frequently updated overlays.- Stream eligible full-size styled container content directly into its target canvas, avoiding a temporary cell grid and copy. Reusable background and gradient fill templates now update destination cells without cloning.
- Added idempotent
WidgetApp.dispose()teardown for mounted element trees.WidgetTesterandrunWidgetAppnow explicitly release widget state and inherited dependencies without coupling the coreProgrammodel contract to arbitrary model disposal. LayoutBuildernow builds from incoming parent layout constraints rather thanMediaQueryviewport dimensions. UseMediaQuerydirectly for viewport-based decisions; unbounded parent axes remain unbounded.Stacknow rejects unsupportedOverflow.visibleinstead of silently clipping. Use an ancestorOverlayfor content outside a component's bounds.- Explicit
Container,SizedBox, and flex extents now respect parent minimum and maximum constraints before laying out children. A small application-root widget should use anAlign/Centerhost to loosen the viewport's minimums. ConstrainedBoxmaximum bounds now limit a child's natural size rather than forcing it to fill the maximum. Use minimum or tight constraints for expansion.- Added
showChrometoTextEditorandCodeEditorso workbenches that already provide tabs and status bars can use an unboxed editor surface. - Added
showDiagnosticBannerso unchromed editors retain reusable diagnostic feedback by default while application workbenches can provide their own. - Updated OpenCode theme selected-row colors to retain readable text contrast instead of using the active border color as a row background.
Fixed #
- Reuse document layout and the allocated scrollbar gutter during offset-only scrolling, avoiding repeated width reflow while preserving paint-wrapper updates, resize handling, and content invalidation.
- Prevent layout-example failures on unbounded constraints, provide a narrow-pane hint for effect scenes, and bound the vertical split-view showcase inside its scrollable page. Add startup, keyboard, and resize smoke coverage for examples.
- Preserve layout-built child state across inherited-data updates and initialize children mounted during a frame through the normal runtime command loop.
- Align offsets and painting with measured child allocations, resolve explicit
bounds before child layout, and retain mounted geometry in legacy
view(). - Resolve Stack sizes before positioned stretches, preserve signed negative
insets, and implement
StackFit.passthroughconstraint forwarding. - Allocate all available integer cells among tight flex children deterministically, reserving loose children's share caps. Reuse measured child sizes for offsets and paint instead of independently redistributing space in each phase.
- Resolve container dimensions before deflating padding, borders, and margins; clamp excessive margin painting to the allocated outer box.
- Keep offstage navigator entries invisible and excluded from pointer hit testing even under tight viewport constraints, while preserving their mounted state.
- Count list separators by additional rendered rows: a single newline joins items without adding a phantom row to content extents and hit-test offsets.
- Dispose the previous
WidgetTesterprogram before remounting and reset terminal capture offsets for the new mount. - Preserve the caller's
ThemeScopewhen opening dialogs throughNavigatorState.showDialog, and keep the default modal barrier transparent as documented instead of painting over the application. - Catch render failures in the diagnostic error screen, preserving Copy and Dismiss/retry behavior. If recovery fails too, report both errors in a bounded fallback with a handled Ctrl+C quit path.
- Unregister inherited-widget dependents on unmount, preventing providers from retaining removed modal/input subtrees or re-dirtying them on later updates.
- Dispose temporary container, stack, and scrollbar composition canvases, releasing owned cell references without waiting for garbage collection.
0.4.1 #
Added #
- Added
DiffReviewControllerandDiffReviewViewportover the core TEA review model, with one composed code/comment scroll extent, lazy expanded thread widgets, sparse height indexing, source-anchored selection, and shared split-panel geometry. Measured thread size changes preserve the visible content anchor. The legacyGitDiffViewerremains available unchanged. - Added
DiffReviewController.firstVisibleSourcefor source lookup in composed viewport coordinates without treating comment rows as diff rows.
Fixed #
- Size
DiffReviewViewportfrom actual parent layout constraints, keeping wrapping, scroll metrics, and source hit testing aligned in nested panes. - Keep implicit
TextFieldandTextAreafocus IDs stable across parent rebuilds, preserving autofocus and keyboard input in newly opened modals. - Preserve terminal graphics escape sequences when clipping rich diff-review cards. Avatar payloads no longer become visible text or consume neighboring author text and diff output.
- Keep scrollbar content geometry stable while dragging, then apply the latest measured extent on release. Growing inline comments no longer trigger a drag assertion, and collapsing comments after release can shrink the scroll extent. Extent-only changes on release now notify listeners even without an offset change.
0.4.0 #
Added #
- Added
example/text_style, a runnable catalog covering immutable updates,Stylecomposition, span inheritance and resets, selectable text, decorations, and the separate ASCII-art font model.
Changed #
- Moved command-palette item and scored-match primitives plus deterministic
matching, selection, and visible-window calculation into
artisanal; the widget keeps compatibility aliases, mouse/focus/theme chrome, and delegates ranking plus scrolling to the shared controller. - Forwarded
RenderMetricsInjectorcustom entries to Artisanal's universal program developer tools overlay while preserving the existing widget-local metrics stream. - Removed
WidgetApp's separate built-in metrics overlay and F12 handler. Widget hosts now enable program diagnostics by default; configure visibility, position, and shortcuts withProgramDiagnosticsOptions. - Routed framework internals through Artisanal's narrow runtime entrypoint so widget app imports do not load unrelated native Markdown dependencies.
- Kept both
app.dartand the completewidgets.dartpublic surface JavaScript-compilable, including Markdown text rendering with browser image placeholders. - Reduced the published package archive by excluding repository-hosted demo media and generated GitHub CLI web artifacts.
- Moved
runWidgetApp,serveWidgetApp,Transport, and widget-oriented program defaults into the package-ownedapp.dartentrypoint. - Moved the lower-level chart-painter grid demo into this package because its application shell uses the widget framework.
- Switched the observer primitives (
Listenable,ValueListenable,ChangeNotifier,ValueNotifier,VoidCallback) topackage:listen(listen: ^1.0.1).src/widgets/animation/listenable.dartis now a scoped compatibility re-export of those types; new code should importpackage:listen/listen.dartdirectly. Public API viapackage:artisanal_widgets/widgets.dartkeeps the same names. - Aligned
ChangeNotifiersemantics withpackage:listen/Flutter:hasListenersandnotifyListenersare@protected(notifyListenersremains@visibleForTesting). Subclasses calling them internally are unaffected; only direct external callers must route through a subclass wrapper. Listener exceptions route throughListenable.onError, anddispose()during notification is rejected bypackage:listen(asserts in debug).
Removed #
- Removed the unused slot registry, plugin mounting, mixed slot region, and remote plugin surface widget APIs and examples.
Fixed #
- Fixed a startup panic (
Unsupported operation: Infinity or NaN toInt) when a scroll viewport had unbounded height:RenderSingleChildViewportnow shrink-wraps to its content height instead of reporting an infinite size, and thescrollbarexample bounds itsScrollbarwith an explicit height like thescrollexample does. - Fixed a reentrant-publish crash (
Bad state: Cannot fire new event) inRenderMetricsInjector: publishes made from inside dispatch (e.g. the metrics listener synchronously triggering another render) are deferred one microtask instead of throwing. - Ensured
ReloadFileWatcher.watchwaits for native watcher installation before returning, so immediate file changes are not missed. - Preserved
TextStyledecoration colors through text rendering copies. - Preserved
TextStylepresentation across soft-wrapped continuation lines and made plain and richTextwrap content before resizingStyleborders and padding. - Made the text-style ASCII-font comparison compact and responsive.
- Kept dividers as single-row structural elements when their requested width exceeds the available layout width.
0.3.0 #
Added #
- Added optional immutable
textStyleoverlays toText,TextSpan,SelectableText, andSelectableRichText, with nested inheritance and explicit attribute disabling while retaining the completeStyleAPI. - Added
MonthlyCalendarwith selected, today, adjacent-month, and marker styling. - Added
Shadowpresets andCellFilterfor applying UV buffer effects to a widget subtree. - Added structured
DataTableCellcontent with column spans, alignment, and per-cell styles throughDataTable.cells. - Added
example/widget_featuresdemonstrating fixed viewports, shadows, calendars, table spans, filters, and canvas shapes together. - Added
example/uv_effectsdemonstrating single and composed UV effects on ordinary widget subtrees throughCellFilter. - Added
example/inline_build_monitor, a responsive bottom-pinned build dashboard with staged progress, streaming logs, native scrollback, and interactive pause, rebuild, and failure controls.
Changed #
- Updated the feature examples and package constraints for
artisanal0.5.x and the new UV rendering surface.
0.2.2 #
Changed #
- Refactored library exports across all widget modules to simplify import paths and reduce the public API surface to stable, documented types.
- Reorganized
git_diff.dartwith streamlined imports and cleaner comment-anchor rendering. - Cleaned up unused imports, trailing whitespace, and formatting across the entire widget library (176 files touched).
Fixed #
- Fixed various lint warnings and type annotations across layout utilities, gesture handling, and animation tests.
0.2.1 #
Added #
- Added a widget-based
flutter_cli_portexample that ports the Rustflutter-clidashboard onto Artisanal Widgets and the Artisanal command runner. - Added an inline widget dashboard example for bottom-pinned non-alt-screen status panels with streaming logs.
- Added review-comment mapping support for the GitHub CLI diff pane so inline review comments can be highlighted beside rendered diffs.
Changed #
- Moved terminal image decoding off the main TUI isolate and cached rendered image output to reduce scroll-time stalls in image-heavy views.
- Improved large scroll/list rendering by preserving scrollbars beside OSC 8 and terminal-graphics content and avoiding unnecessary render-tree hit-test descents.
- Updated workspace dependency constraints for the current
artisanalrelease.
Fixed #
- Kept non-overlay scrollbars visible when content includes Kitty graphics or OSC 8 hyperlinks.
- Preserved styled foreground spaces in canvas/layout rendering instead of treating every space as transparent.
- Reset virtual-list measurement caches correctly after invalidation so scroll metrics do not collapse after resize or content changes.
- Updated the flutter-cli port to delegate unknown commands through
CommandRunner.unknownCommandFallback, keeping built-in completion automatic while still forwarding non-dashboard Flutter commands. - Disabled mouse capture in the flutter-cli port inline dashboard so native terminal scrollback remains available by default.
0.2.0 #
Added #
- Added a stable
package:artisanal_widgets/widgets.dartentrypoint for the high-level widget framework surface. - Added stable
package:artisanal_widgets/charting.dartandpackage:artisanal_widgets/selection.dartentrypoints for the supported charting and text-selection surfaces. - Added
ImageAutoMode.sessionCapabilitiessoImage(renderMode: auto)can follow terminal version and device-attribute reports from the active session instead of only using the local process environment. - Added a dedicated
example/tooltip_tracedemo withTuiTraceinstrumentation and built-in replay/trace conversion flags so tooltip hover behavior can be recorded, converted, and replayed during debugging. - Added external diagnostics sources and listenable diagnostics bindings for editor widgets, so demos and downstream apps can drive diagnostics without custom text-pattern glue.
- Added per-widget selection highlight overrides for the shared read-only selection surfaces, so mixed documents can use different selection palettes within one
SelectionArea. - Added span-level selection highlight overrides for
SelectableRichText, so one shared rich-text selection can mix palettes within a single widget.
Changed #
- Fixed
FadeModalBarrierso content-backed barriers dim the child in place instead of painting an opaque black layer over the full view, while keeping the standalone overlay fallback for empty-child route barriers. - Improved
Tintblending soFadeTintand content-backedFadeModalBarrierwidgets fade proportionally toward the target color instead of snapping between no effect and a full tint. - Updated
AnimatedTintto use the sharedblendColor()helper so animated widget tinting follows the same color interpolation path as the rest of the style system. - Fixed
Drawerbackdrops so open drawers dim the background content in place instead of blacking out the full terminal view. - Made
ModalandDrawerhonorbackdropColorthrough the shared tint path instead of ignoring the configured color while dimming the background. - Clarified the package guidance so
artisanal_widgetsremains the primary widget dependency, while thepackage:artisanal/...widget entrypoints are documented as optional umbrella convenience re-exports. - Hosted browser/socket runner helpers now default
Image(renderMode: auto)toImageAutoMode.sessionCapabilitiesinstead of forcing the portable fallback, so remote terminals can upgrade image rendering from live session capability reports. - Added hosted-runner regression coverage for session-capability image probing by default and for portable-fallback mode suppressing those extra image capability requests.
- Improved shared read-only selection in scrollable mixed views, including upward and downward edge auto-scroll, mouse-wheel scrolling during drag selection, and row-wide drag starts from surrounding whitespace.
- Kept
package:artisanal_widgets/artisanal_widgets.dartas the broader experimental compatibility surface while stabilizing the primary widget/app/layout/input/navigation APIs. - Updated the widget docs to prefer the stable
package:artisanal_widgets/widgets.dartimport path. - Updated the package README and focused examples to prefer the stable top-level entrypoints over the broad compatibility import.
- Updated the remaining widget examples and tooling to import the stable
package:artisanal_widgets/widgets.dartentrypoint instead of the broad compatibility surface. - Made
Tooltipfloat from anOverlayancestor instead of reflowing surrounding layout, and updated the gallery example to host its overlay demos through a root overlay so hover tooltips behave like anchored popups. - Made floating
Tooltipfall back to the latest hover pointer position when anchor geometry is not ready yet, avoiding delayed tooltip popups in live sessions. - Made floating
Tooltiprequest an immediate repaint on hover enter and exit so overlay tooltips appear and disappear without waiting for a later event. - Made floating
Tooltiphit-test transparent so it no longer blocks later mouse hover and click interaction underneath. - Fixed
GestureDetectorhover handling so commands returned fromonEnterandonExitare dispatched through the widget pipeline, allowing overlay-backed hover widgets likeTooltipto repaint immediately in live sessions. - Fixed
Stackhit-testing so positioned children use their painted offsets during hit testing, which restores immediate hover interaction for anchored overlays likeTooltip. - Updated the flagship widget app examples to use the stable umbrella imports from
package:artisanal/app.dartandpackage:artisanal/widgets.dart. - Updated the editor showcase examples to use the stable umbrella imports from
package:artisanal/app.dart,package:artisanal/editors.dart, andpackage:artisanal/widgets.dart. - Updated the shared text input test suites to use the stable
package:artisanal/widgets.dartandpackage:artisanal/testing.dartentrypoints. - Updated the flagship component and showcase tests to use the stable
package:artisanal/widgets.dart,package:artisanal/testing.dart, andpackage:artisanal/app.dartentrypoints. - Updated the editor showcase and HelpView regression tests to use the stable
package:artisanal/testing.dartandpackage:artisanal/widgets.dartentrypoints. - Updated the app-shell, reload, and core HelpView tests to use the stable
package:artisanal/app.dart,package:artisanal/widgets.dart, andpackage:artisanal/testing.dartentrypoints. - Updated the status, progress, metric, and key-hint component tests to use the stable
package:artisanal/widgets.dartandpackage:artisanal/testing.dartentrypoints. - Updated the button, toggle, slider, dropdown, and popup-menu component tests to use the stable
package:artisanal/widgets.dartandpackage:artisanal/testing.dartentrypoints. - Updated the tree, tab, split-view, scroll-area, and list-navigation component tests to use the stable
package:artisanal/widgets.dartandpackage:artisanal/testing.dartentrypoints. - Updated the accent-panel, chip, tooltip, accordion, expansion-tile, and hyperlink component tests to use the stable
package:artisanal/widgets.dartandpackage:artisanal/testing.dartentrypoints. - Updated the data-table, list-tile control, and select/pagination component tests to use the stable
package:artisanal/widgets.dartandpackage:artisanal/testing.dartentrypoints. - Updated the command palette, modal/drawer, and git-diff component tests to use the stable
package:artisanal/widgets.dartandpackage:artisanal/testing.dartentrypoints. - Updated the frame border regressions and the OpenCode home layout showcase test to use the stable
package:artisanal/widgets.dartandpackage:artisanal/testing.dartentrypoints. - Updated the remaining card/panel/frame regression test to use the stable
package:artisanal/widgets.dartandpackage:artisanal/testing.dartentrypoints, and to accept stabilized truecolor card-surface rendering. - Updated the foundational widget and basic layout tests to use the stable
package:artisanal/widgets.dartandpackage:artisanal/testing.dartentrypoints. - Updated the main widget gallery example to enable passive all-motion mouse tracking so hover-driven overlays like the tooltip preview work in real terminals.
- Clarified the widget docs and tooltip API docs so passive hover behavior explicitly points callers to
MouseMode.allMotionand the widget runners that already default to it. - Updated the widget-friendly runner defaults to disable core startup probes so early hover-driven UI feedback, such as tooltips in the gallery example, is not delayed behind terminal capability probing.
- Added shared
Tooltiplifecycle trace events for hover transitions, overlay insert/remove, and overlay visible/hidden timing so tooltip traces can measure when the popup is actually requested and rendered. - Fixed hit-test motion bubbling so nested hover handlers all see the first in-bounds mouse move, which restores immediate
Tooltipshow timing when the tooltip target contains its ownMouseRegion. - Stopped floating
Tooltipfrom invalidating its overlay entry during every build while hovered, which eliminates repaint churn that could delay later mouse motion and hide updates. - Stopped
Tooltip.didUpdateWidget()from resyncing the floating overlay on unrelated parent rebuilds, so hovered tooltips no longer trigger periodic overlay rebuilds from app-shell updates.
0.1.0+1 #
- Documentation + assets
0.1.0 #
Added #
- Initial release of
artisanal_widgets. - Flutter-style terminal widget system built on top of
artisanal. - Core widget framework, layout primitives, focus/gesture/input systems, and component library.
- Charting widgets, scroll/selection support, and testing harnesses for TUI widget behavior.