| name | add-dual-list |
|---|---|
| description | Add a ThemedDualListInput to a layrz Flutter form or tab. Use when wiring a new list field from any layrz Input class (e.g. LocatorInput, AssetInput) into any widget — a tab, a form view, or any stateful/stateless widget. |
Wire a new list field into any widget in a layrz Flutter package using ThemedDualListInput.
The user must tell you:
- The Input class and the field name (e.g.
LocatorInput.poisIds) - The item model whose list will be displayed (e.g.
Poi) - The target widget where the dual list should appear (a tab file, a form view, or any other widget)
- The parent that owns the Input object and must pass the item list down (if different from the target widget)
If any of these are unclear, ask before proceeding.
- Read
pubspec.lockin the project root and find the resolved version of the package that contains the Input class (e.g.layrz_models: 3.6.24). - Locate the pub cache:
- Default on Linux/macOS:
~/.pub-cache/hosted/pub.dev/<package>-<version>/ - Default on Windows:
%LOCALAPPDATA%\Pub\Cache\hosted\pub.dev/<package>-<version>/ - If the versioned directory is not found at either default path, ask the user for the pub cache location before continuing.
- Default on Linux/macOS:
- Confirm the directory name exactly matches the resolved version from
pubspec.lock— do not read a different version.
Inside the resolved package directory, locate the Input class source file and confirm:
- The exact field name (e.g.
poisIds) - Its type (
List<String>)
Check the item model (e.g. Poi) for the properties used in the selector — typically id and name.
In the target widget class, add:
final List<ModelType> items; // e.g. final List<Poi> poisAdd it to the constructor as required.
Place it at the appropriate position, preceded by const SizedBox(height: 10) if other widgets are already present:
const SizedBox(height: 10),
ThemedDualListInput(
labelText: context.i18n.t('<i18n.key>'),
value: object.<fieldName>,
items: items.map((item) => ThemedSelectItem(value: item.id, label: item.name)).toList(),
errors: context.getErrors(key: '<fieldName>'),
onChanged: (values) {
object.<fieldName> = values.map((e) => e.value).nonNulls.toList();
if (context.mounted) onChanged.call();
},
),For each widget in the chain between the data source and the target widget:
- Args class (e.g.
LocatorsFormArgs) — addfinal List<ModelType> itemsand the constructor parameter if it isn't already there. - Stateful parent — add
late final List<ModelType> items, assign it from args ininitState, and pass it down to the child widget. - If the target is a tab — pass it in the
ThemedTabchild constructor call. - If the target is the form view itself — use it directly from the state.
flutter analyze <changed files>No issues = done.
- Use
nonNullsto filter nulls:values.map((e) => e.value).nonNulls.toList() - Always guard
onChangedwithif (context.mounted) - i18n key typically follows
<entity>.<fieldName>(e.g.locators.poisIds) - Line width limit is 120 characters
- Never use raw Material widgets — always use
layrz_themecomponents - Always derive the package version from
pubspec.lock, never guess or use the latest available directory in the cache