Published 2025-11-21
A small, framework‑agnostic library to compose file names from ordered parts. It ships the core model (this package) and can be used by Flutter or other UI layers to build editors and widgets.

Consistent file names make automation and searching much easier. Instead of hand‑crafting strings across your app, use a single, test‑covered model that:
HHFilenameComposerPartType defines all parts that can appear in a filename. Each value exposes canEdit and canRemove flags.HHFilenameComposerPartData couples a part type with its data (string) and active state.HHFilenameComposerSeed provides initial data values (e.g. sheet size, sides). It has defaultSeed and zeroSeed helpers.HHFilenameComposer is the stateful model which holds a list of HHFilenameComposerPartData and produces the final filename.The default active parts are defined by HHFilenameComposer.defaultActive and include the non‑removable parts such as prefix_hard, sheet_size, sides, page_size, common_marker, sequence, duplication.
import 'package:pkg_filename_composer/pkg_filename_composer.dart';
void main() {
// Start with default active parts and empty data
final composer = HHFilenameComposer();
// Provide data for some parts (you can also supply a Seed at construction time)
composer.setItemData(
composer.getItemData(HHFilenameComposerPartType.prefix_hard).copyWith(data: 'IMPO'),
);
composer.setItemData(
composer.getItemData(HHFilenameComposerPartType.sheet_size).copyWith(data: '210x297'),
);
composer.setItemData(
composer.getItemData(HHFilenameComposerPartType.sides).copyWith(data: 'DZ'),
);
composer.setItemData(
composer.getItemData(HHFilenameComposerPartType.page_size).copyWith(data: '80x60'),
);
composer.setItemData(
composer.getItemData(HHFilenameComposerPartType.sequence).copyWith(data: '001'),
);
composer.setItemData(
composer.getItemData(HHFilenameComposerPartType.duplication).copyWith(data: '1x printen'),
);
final filename = composer.getFilename(extension: 'pdf');
print(filename); // e.g. IMPO_210x297_DZ_80x60_001_1x printen.pdf
}
final seed = HHFilenameComposerSeed(
prefix_hard: 'IMPO',
sheet_size: '210x297',
sides: 'DZ',
page_size: '80x60',
common_marker: 'Algemeen pakket',
sequence: '001',
duplication: '1x printen',
);
final composer = HHFilenameComposer(seed: seed);
final name = composer.getFilename();
final composer = HHFilenameComposer(seed: HHFilenameComposerSeed.zeroSeed);
// Activate an optional part
composer.addItem(HHFilenameComposerPartType.prefix);
composer.setItemData(
composer.getItemData(HHFilenameComposerPartType.prefix).copyWith(data: 'STACK'),
);
// Remove a part (only if canRemove is true for that part type)
composer.removeItem(HHFilenameComposerPartType.prefix);
// Reorder by index
composer.reorderItem(0, 2);
// Or swap by item
final item = composer.getItemData(HHFilenameComposerPartType.page_size);
composer.swapItem(item, 1);
final json = composer.toJson();
final jsonString = composer.stringify();
final composer1 = HHFilenameComposer.fromJson(json);
final composer2 = HHFilenameComposer.fromString(jsonString);
final target = HHFilenameComposer();
final other = HHFilenameComposer.fromJson(json);
target.merge(other);
A minimal example of the serialized structure (pretty‑printed for readability):
{
"data": [
{ "partType": "prefix_hard", "data": "IMPO", "active": true },
{ "partType": "sheet_size", "data": "210x297", "active": true },
{ "partType": "sides", "data": "DZ", "active": true },
{ "partType": "page_size", "data": "80x60", "active": true },
{ "partType": "common_marker","data": "Algemeen pakket", "active": true },
{ "partType": "sequence", "data": "001", "active": true },
{ "partType": "duplication", "data": "1x printen", "active": true }
]
}
Note: The enum value document_subject used to be named subject. The deserializer keeps backward compatibility for old data.
HHFilenameComposer
HHFilenameComposer({seed, defaultActive}), fromJson(...), fromJsonObject(...), fromString(...)selectedPartTypes, unselectedPartTypesaddItem(partType), removeItem(partType), reorderItem(oldIndex, newIndex), swapItem(item, targetIndex), setItemData(data), merge(other), clear()getFilename({values, extension, defaultValue}), toJson(), stringify()HHFilenameComposerSeed
defaultSeed, zeroSeedfromPartData(...), merge(...), set(...), toJson(), etc.HHFilenameComposerPartType
canEdit and canRemove flagsHHFilenameComposerPartData
partType, data, active and helpers like copyWith, fromJson, toJsonConsult the source files in lib/src/common/... for full details.
Run the package tests:
dart test
The test suite includes end‑to‑end examples of composing, (de)serializing and merging.
See the LICENSE file. Copyright © HuigHaverlag BV.