패키지, 저장소 및 앱 카테고리 검색

interact 표지
패키지 상세v2.2.0

interact

사용자 정의 가능한 상호작용형 명령줄 구성 요소 모음.

macOSWindowsLinux
30일 다운로드
37만
좋아요
95
Pub 점수
140

패키지 설치

flutter pub add interact

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

Interact는 풍부하고 사용자 친화적인 CLI 애플리케이션을 구축하기 위해 사용자 정의 가능한 상호작용형 명령줄 컴포넌트 세트를 제공하는 Flutter/Dart 패키지입니다. 검증, 기본값, 실시간 피드백과 같은 기능을 지원하며 개발자가 프롬프트, 메뉴 및 입력 폼을 쉽게 만들 수 있도록 도와줍니다. macOS, Windows, Linux에서 크로스플랫폼으로 사용할 수 있도록 설계되었으며, Dart 기반 CLI 도구에 원활하게 통합됩니다. 저수준 터미널 처리 없이도 상호작용형 터미널 경험을 쉽게 생성할 수 있어 개발자의 생산성을 높여줍니다.

사용 사례

  • 인터랙티브 CLI 도구 만들기
  • 설정 워즈드 생성
  • 명령줄 구성 유틸리티 개발
  • 사용자 입력 워크플로우 자동화
  • 동적 프롬프트를 통한 CLI 사용자 경험 향상
  • 다단계 터미널 상호작용 지원

주요 기능

  • 사용자 정의 가능한 프롬프트 구성 요소
  • 입력 검증 및 오류 처리
  • 크로스 플랫폼 호환성
  • 실시간 사용자 피드백
  • 기본값 및 제안 값 지원
  • Flutter/Dart CLI 앱과의 간편한 통합

적합한 대상

  • CLI 도구 개발자
  • DevOps 자동화 스크립트
  • 인터랙티브 설정 프로세스
  • Dart 기반 명령줄 애플리케이션
  • 직관적인 터미널 인터페이스를 원하는 사용자

고려 사항

  • 터미널 환경이 필요합니다
  • 콘솔 기반 상호작용에 제한됨
  • GUI 애플리케이션에 적합하지 않음
  • 플랫폼별 터미널 동작에 의존
  • 복잡한 레이아웃을 위해 추가 스타일링이 필요할 수 있습니다

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

Interact

A collection of customizable interactive command-line components.


Table of Contents


Overview

The library contains a bunch of command-line components that are easy to use and customizable, including text and password inputs, radio or select inputs, checkbox or multiple select inputs, spinners, and progress bars. Examples for all the available components can be found in the example folder, and the API Documentation section will cover all about them.

As an overview, you can make a Select component like this.

final languages = ['Rust', 'Dart', 'TypeScript'];
final selection = Select(
  prompt: 'Your favorite programming language',
  options: languages,
).interact();

print('${languages[selection]}');

It will result in something like this,


Installation

Install the latest version of interact as a dependency as shown in pub.dev.


API Documentation

Components

These are the snippets of components with their properties and arguments. Check the pub documentation to get to know more about them in detail.


Confirm Component

A confirm component asks the user for a simple yes or no and will return a boolean accordingly.

final answer = Confirm(
  prompt: 'Does it work?',
  defaultValue: true, // this is optional
  waitForNewLine: true, // optional and will be false by default
).interact();

If waitForNewLine is true, the prompt will wait for an Enter key from the user regardless of the answer.


Input Component

An input component asks the user for a string that could be validated.

final email = Input(
  prompt: 'Your email',
  defaultValue: '', // optional, will provide the user as a hint
  initialText: '', // optional, will be autofilled in the input
  validator: (String x) { // optional
    if (x.contains('@')) {
      return true;
    } else {
      throw ValidationError('Not a valid email');
    }
  },
).interact();

The message passed in the ValidationError exception will be shown as an error until the validator returns true.


Password Component

A password component behaves pretty much the same as an input component, but the user input will be hidden and by default, it has a repeat password validator that checks if two password inputs are the same or not.

final password = Password(
  prompt: 'Password',
  confirmation: true, // optional and will be false by default
  confirmPrompt: 'Repeat password', // optional
  confirmError: 'Passwords do not match' // optional
).interact();

Select Component

A select component asks the user to choose between the options supplied and the index of the chosen option will be returned.

final languages = ['Rust', 'Dart', 'TypeScript'];

final selection = Select(
  prompt: 'Your favorite programming language',
  options: languages,
  initialIndex: 2, // optional, will be 0 by default
).interact();

MultiSelect Component

A multi-select component asks the user for multiple options check by using the SpaceBar. Similarly, the multi-select component will return a list of selected indexes.

final answers = MultiSelect(
  prompt: 'Let me know your answers',
  options: ['A', 'B', 'C'],
  defaults: [false, true, false], // optional, will be all false by default
).interact();

Sort Component

A sort component asks the user to sort the given list of options and returns the list ordered by the user.

final sorted = Sort(
  prompt: 'Sort Tesla models from favorite to least',
  options: ['S', '3', 'X', 'Y'],
  showOutput: false, // optional, will be false by default
).interact();

Sometimes the list given can be massive, so setting the showOutput to false makes the list not be shown in the success prompt.


Spinner and MultiSpinner Components

A spinner will show a spinning indicator until the user calls it's done method. When it's done, it shows the icon given in place of the spinner.

final gift = Spinner(
  icon: '🏆',
  leftPrompt: (done) => '', // prompts are optional
  rightPrompt: (done) => done
      ? 'here is a trophy for being patient'
      : 'searching a thing for you',
).interact();

await Future.delayed(const Duration(seconds: 5));
gift.done();

Using multiple spinners at once is a common practice, but because of the way the library renders things, it's not possible to have multiple them normally. It will break the rendering process of all components.

final spinners = MultiSpinner();

final horse = spinners.add(Spinner(
  icon: '🐴',
  rightPrompt: (done) => done ? 'finished' : 'waiting',
)); // notice how you don't need to call the `.interact()` function

await Future.delayed(const Duration(seconds: 5));
horse.done();

Now you can have multiple of them without breaking things.


Progress and MultiProgress Components

A progress component shows a progress bar.

final progress = Progress(
  length: 1000, // required, the length of the progress to use
  size: 0.5, // optional, will be 1 by default
  rightPrompt: (current) => ' ${current.toString().padLeft(3)}/$length',
).interact();

for (var i = 0; i < 500; i++) {
  await Future.delayed(const Duration(milliseconds: 5));
  progress.increase(2);
}

progress.done();

The size is the multiplier for the rendered progress bar and it will be 1 by default. 0.5 means the rendered progress bar will be half the width of the terminal.

A MultiProgress does pretty much the same as what MultiSpinner did for spinners.

final bars = MultiProgress();

final p1 = bars.add(Progress(
  length: 100,
  rightPrompt: (current) => ' ${current.toString().padLeft(3)}/$length',
)); // notice how you don't need to call the `.interact()` function

for (var i = 0; i < 500; i++) {
  await Future.delayed(const Duration(milliseconds: 5));
  p1.increase(2);
}

p1.done();

Customizing Themes

Because most of the visually rendered parts come from the theme object which is available for all components, you can customize a lot of them by changing the theme. Changing a theme for a component can be done by using the withTheme constructor.

final progress = Progress.withTheme(
  theme: Theme(),
  length: length,
  rightPrompt: (current) => ' ${current.toString().padLeft(3)}/$length',
).interact();

The components used the Theme.defaultTheme as the theme by default. The Theme object has two premade themes,

  • Theme.colorfulTheme which is made with colorful ASCII/emojis
  • Theme.basicTheme which is mostly text characters and without colors

and the Theme.defaultTheme is the colorful theme by default.

Because constructing a theme from scrap requires you to write a lot of properties, it might be easier to extend existing themes to create a new one which can be done using the copyWith method.

import 'package:tint/tint.dart'; // for extension methods
// ...
Theme customTheme = Theme.colorfulTheme.copyWith(
  activeItemPrefix: '👉'
  activeItemStyle: (x) => x.yellow().underline(),
);

Technically, you can also override Theme.defaultTheme as a shortcut.

Handling Exceptions

If your program throw exceptions and exit midway, interact's components won't be able to finish their tasks and gracefully quit therefore causing certain problems like cursors not showing up, terminal colors got modified etc. To fix these problems you should always try to catch exceptions and reset to terminal defaults using reset function.

try {
  Spinner(icon: '🚨').interact();
  throw Exception(); // spinner couldn't finished
} catch (e) {
  reset(); // Reset everything to terminal defaults
  rethrow;
}

Acknowledgement

This library is mostly inspired by dialouger library from Rust. The lack of a properly maintained library for Dart with a well-made API is what pushed me into making this library.

카테고리

의존성

의존성 목록 3 개

소스 저장소

이 패키지를 사용하는 프로젝트