build method

  1. @override
Widget build(
  1. BuildContext context
)
override

Builds and returns the widget representation of the field wrapper.

This method retrieves the ambient ArcaneField<T> from the BuildContext using Pylon dependency injection. It then fetches the current value for the field's effective key from its ArcaneFieldProvider.

If a value is available, it constructs either:

  • A ListTile (default) incorporating the field's meta properties (icon, name, description), an animated validation check icon (fading in on valid values), and the builder-generated content.
  • A custom Pylon widget if overrideTileScaffold is true, passing the value and builder directly.

During loading (null value), it displays a "Loading..." text with a shimmer animation for smooth UX. The animation for the check icon uses fadeIn and fadeOut with specific durations and curves for subtle feedback.

No side effects occur; this is a pure rendering method relying on reactive Pylon updates for rebuilds. Returns a Widget that integrates into the form's widget tree.

Implementation

@override
Widget build(BuildContext context) {
  ArcaneField<T> field = context.pylon<ArcaneField<T>>();
  return field.provider
      .getValue(field.meta.effectiveKey)
      .buildNullable((v) => (field.provider.subject
          .buildNullable((v) => overrideTileScaffold
              ? Pylon<T>(
                  value: v ?? field.provider.defaultValue,
                  builder: builder,
                )
              : ListTile(
                  leading:
                      field.meta.icon != null ? Icon(field.meta.icon!) : null,
                  subtitleText: field.meta.description,
                  title: Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        mainAxisSize: MainAxisSize.min,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: [
                          if (field.meta.name != null) ...[
                            Flexible(child: Text(field.meta.name!).xSmall),
                            Gap(8),
                          ],
                          Icon(Icons.check, size: 12, color: Colors.green)
                              .padTop(4)
                              .animate(key: ValueKey(v))
                              .fadeIn(
                                  duration: 1.seconds,
                                  curve: Curves.easeOutCirc,
                                  begin: 0)
                              .fadeOut(
                                  delay: 1.seconds,
                                  begin: 1,
                                  duration: 3.seconds,
                                  curve: Curves.easeOutCirc)
                        ],
                      ),
                      Gap(8),
                      v == null
                          ? Text("Loading...")
                          : Builder(builder: builder),
                      Gap(4)
                    ],
                  ),
                ))
          .shimmer(loading: v == null)));
}