scientific_input
A Flutter package for parsing, validating, formatting, and displaying
scientific notation such as 1.2e-3 and 1.2 × 10⁻³.
Why this package?
scientific_input gives you a clean scientific-notation workflow without
having to stitch together parsing, controller state, validation, formatting,
and display widgets yourself.
- Accept standard scientific input like
1.2e-3 - Accept pasted readable input like
1.2 × 10⁻³ - Keep written input or format on edit completion
- Show readable
× 10previews with optional tooltips - Reuse the same formatting logic in editable and display-only widgets
This is particularly useful for applications that rely on precise magnitude handling, such as Life Cycle Assessment tools, sustainability platforms, environmental impact models, laboratory systems, and scientific dashboards, where values often span many orders of magnitude and must remain both readable and mathematically reliable.
What it accepts
- Standard scientific notation like
1.2e-3or1.2E-3 - Readable scientific notation like
1.2 × 10⁻³ - Plain decimals like
12whenallowPlainDecimalis enabled
Installation
dependencies:
scientific_input: ^1.0.0
Quick start
import 'package:scientific_input/scientific_input.dart';
final controller = ScientificNumberController(text: '1.2e-3');
ScientificNumberInputField(
controller: controller,
labelText: 'Value',
hintText: 'e.g. -3.5e6',
previewTooltipBuilder: (data) => data.value.toString(),
onChanged: (value) {
debugPrint('Parsed value: $value');
},
);
Choose a setup
Use a controller when you need state
This is the best fit when you want parsed values, validation errors, or both the raw and readable forms of the input.
final controller = ScientificNumberController(text: '1.2e-3');
ScientificNumberInputField(
controller: controller,
);
Let the field manage its own controller
This keeps simple forms lightweight. Pass validation and parsing options directly to the widget.
ScientificNumberInputField(
labelText: 'Scientific value',
minExponent: -12,
maxExponent: 12,
);
Input modes
Keep written input
This is the default behavior. The field keeps the user's typed scientific text and shows a readable preview underneath.
ScientificNumberInputField(
controller: ScientificNumberController(text: '1.2e-3'),
labelText: 'Scientific value',
);
Format on finish
Opt in when you want the field itself to switch to the readable × 10 form
after blur or submit.
final controller = ScientificNumberController(
text: '3.4e5',
formatOnEditingComplete: true,
);
ScientificNumberInputField(
controller: controller,
formatOnEditingComplete: true,
showFormattedPreview: false,
);
Display-only text
Use ScientificNumberText anywhere you want formatted output without a text
field.
ScientificNumberText(
'1.2e4',
selectable: true,
tooltipBuilder: (data) => data.value.toString(),
);
Tooltips and full-value display
Both the input preview and the display-only widget support optional tooltips.
ScientificNumberInputField(
previewTooltipBuilder: (data) => data.value.toString(),
);
ScientificNumberText(
'5e6',
tooltipBuilder: (data) => data.value.toString(),
);
Controller state
ScientificNumberController keeps the typed text, parsed value, normalized
scientific string, and validation state together.
final controller = ScientificNumberController(
text: '1.2 × 10⁻³',
minExponent: -12,
maxExponent: 12,
);
final double? value = controller.doubleValue; // 0.0012
final String? error = controller.errorText; // null when valid
final String? raw = controller.rawScientificText; // 1.2e-3
final String? pretty = controller.readableText; // 1.2 × 10⁻³
Validation and constraints
Validation can live on the controller or be passed directly to
ScientificNumberInputField when it creates its own internal controller.
If you supply your own ScientificNumberController, put the validation options
on the controller itself. If you do not supply a controller, pass them directly
to ScientificNumberInputField.
ScientificNumberInputField(
allowPlainDecimal: false,
minValue: 1e-6,
maxValue: 1e6,
minExponent: -12,
maxExponent: 12,
validator: (details) {
if (details.scientificText == '0e0') {
return 'Zero is not allowed.';
}
return null;
},
);
Preview customization
Use the preview hooks to change rendering, tooltips, semantics, or spacing.
ScientificNumberInputField(
previewSpacing: 12,
previewTooltipBuilder: (data) => data.value.toString(),
previewSemanticsLabelBuilder: (data) => 'Parsed value ${data.value}',
previewBuilder: (context, data) {
return Text('Preview: ${data.formattedText}');
},
);
Utilities
final strict = ScientificNumberParser.parse('1.2e-3'); // 0.0012
final permissive = ScientificNumberParser.tryParse('1.2 × 10⁻³'); // 0.0012
final components = ScientificNumberParser.tryParseComponents('-3.5e6');
final normalized = ScientificNumberParser.normalizeScientificString('1.2 × 10⁻³'); // 1.2e-3
final formatted = ScientificNumberFormatter.format('5e6'); // 5 × 10⁶
final readable = ScientificNumberFormatter.formatReadable('12'); // 12
Example app
The bundled example app includes dedicated demos for:
- keeping written input
- text-only display
- tooltip and full-value display
Run it with:
cd example
flutter run
Or launch it on the web with:
cd example
flutter run -d chrome
Preview: