artisanal_widgets 0.2.0 copy "artisanal_widgets: ^0.2.0" to clipboard
artisanal_widgets: ^0.2.0 copied to clipboard

Widget system for composable TUI components, built on top of the artisanal terminal toolkit.

artisanal_widgets #

Flutter-inspired widget framework for terminal UIs, built on top of artisanal.

This is the primary package for widget-first apps. Use the umbrella package:artisanal/... widget entrypoints only when you intentionally want the broader Artisanal toolkit from a single dependency.

Table of Contents #

Installation #

dependencies:
  artisanal_widgets: ^0.1.0

Import #

import 'package:artisanal_widgets/app.dart';
import 'package:artisanal_widgets/widgets.dart';

Use the focused stable entrypoints when you need those modules:

  • package:artisanal_widgets/app.dart for app shells, runners, reload helpers, and hosted wrappers
  • package:artisanal_widgets/charting.dart for chart widgets
  • package:artisanal_widgets/editors.dart for TextField, TextArea, TextEditor, CodeEditor, MarkdownEditor, and the stable TextInputKeyMap / TextAreaKeyMap customization surface
  • package:artisanal_widgets/selection.dart for SelectableText and SelectionArea
  • package:artisanal_widgets/testing.dart for WidgetTester

The main package:artisanal_widgets/widgets.dart barrel also re-exports KeyMap and KeyBinding, so component-level shortcut UIs such as HelpView and zone-hit messages such as ZoneInBoundsMsg, so shortcut and pointer-aware widgets do not need an extra package:artisanal/tui.dart import.

Keep package:artisanal_widgets/artisanal_widgets.dart only when you explicitly want the broader experimental compatibility surface.

Both the local runner helpers and the hosted browser/socket helpers accept an imageAutoMode override. Hosted browser/socket runners now default Image(renderMode: auto) to session-driven capability detection, while WidgetTester keeps the portable half-block fallback for deterministic tests.

Quick start #

import 'package:artisanal_widgets/app.dart';
import 'package:artisanal_widgets/widgets.dart';

class HelloApp extends StatelessWidget {
  HelloApp({super.key});

  @override
  Widget build(BuildContext context) {
    final theme = ThemeScope.of(context);
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text('Hello widgets', style: theme.titleLarge),
        Text('Press q to quit', style: theme.bodyMedium),
      ],
    );
  }
}

void main() async {
  await runArtisanalApp(
    ArtisanalApp(
      title: 'Hello widgets',
      home: HelloApp(),
    ),
  );
}

runWidgetApp() and runArtisanalApp() default to MouseMode.allMotion, so hover-driven widgets such as Tooltip, MouseRegion, and hover-aware scrollbars work without extra setup. If you call runtime.runProgram() directly, set mouseMode: runtime.MouseMode.allMotion for passive hover behavior; mouse: true alone only enables MouseMode.cellMotion.

Flutter-style component ports #

  • Chips: Chip, ActionChip, ChoiceChip, FilterChip, InputChip
  • Menus: DropdownButton, DropdownMenuItem, PopupMenuButton, PopupMenuItem, CheckedPopupMenuItem, PopupMenuDivider
  • Sliders: Slider, RangeSlider, RangeValues
  • Indicators: LinearProgressIndicator, CircularProgressIndicator
  • Charts: SparklineChart, LineChart, BarChart, HeatmapChart, PieChart, RibbonChart with optional in-chart legends

Charts The OpenCode example is self-contained under example/opencode (including local data models and theme assets).

OpenCode Clone OpenCode Clone 2 Panel Box

Program Instrumentation #

The core TUI runtime (Program) supports general instrumentation and automation for any app (not OpenCode-specific):

  • ProgramInterceptor for message interception/timing hooks.
  • ProgramReplay for deterministic event playback.
import 'package:artisanal/runtime.dart' as runtime;
import 'package:artisanal_widgets/app.dart';

final replay = runtime.ProgramReplay.script([
  runtime.ProgramReplayStep(
    after: Duration(milliseconds: 120),
    msg: runtime.KeyMsg(
      runtime.Key(runtime.KeyType.runes, runes: [0x61]),
    ),
  ),
  runtime.ProgramReplayStep(
    after: Duration(milliseconds: 16),
    msg: runtime.QuitMsg(),
  ),
]);

await runtime.runProgram(
  WidgetApp(MyApp()),
  options: runtime.ProgramOptions(replay: replay),
);

See the package:artisanal/runtime.dart API docs for full interceptor/replay details.

Tests #

Component tests are split by widget under test/components/*_test.dart.

Useful commands:

dart test test/components
dart test
dart analyze

Command execution note #

When combining commands that include runtime-managed commands (EveryCmd, StreamCmd, or helpers like every(...)), use ParallelCmd so those commands are started by Program.

Use Cmd.batch(...) for finite commands that only need execute().

0
likes
160
points
464
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Widget system for composable TUI components, built on top of the artisanal terminal toolkit.

Repository (GitHub)
View/report issues

Topics

#cli #tui #terminal #widget

Funding

Consider supporting this project:

www.buymeacoffee.com

License

MIT (license)

Dependencies

artisanal, image, meta

More

Packages that depend on artisanal_widgets