Foundation

Portal

A portal renders a portal widget that "floats" on top of a child widget.

This widget is typically used to create other high-level widgets, e.g., popover or tooltip. You should prefer those high-level widgets unless you're creating a custom widget.

FPortal(
  spacing: const FPortalSpacing(8),
  viewInsets: const EdgeInsets.all(5),
  portalBuilder: (context, _) => Container(
    decoration: BoxDecoration(
      color: context.theme.colors.background,
      border: Border.all(color: context.theme.colors.border),
      borderRadius: BorderRadius.circular(4),
    ),
    padding: const EdgeInsets.only(left: 20, top: 14, right: 20, bottom: 10),
    child: SizedBox(
      width: 288,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('Dimensions', style: context.theme.typography.base),
          const SizedBox(height: 7),
          Text(
            'Set the dimensions for the layer.',
            style: context.theme.typography.sm.copyWith(
              color: context.theme.colors.mutedForeground,
              fontWeight: FontWeight.w300,
            ),
          ),
          const SizedBox(height: 15),
          for (final (label, value) in [('Width', '100%'), ('Max. Width', '300px')]) ...[
            Row(
              children: [
                Expanded(child: Text(label, style: context.theme.typography.sm)),
                Expanded(
                  flex: 2,
                  child: FTextField(
                    control: FTextFieldControl.managed(initial: TextEditingValue(text: value)),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 7),
          ],
        ],
      ),
    ),
  ),
  builder: (context, controller, _) => FButton(onPress: controller.toggle, child: const Text('Portal')),
);

Usage

FPortal(...)

FPortal(
  controller: OverlayPortalController(),
  constraints: const FPortalConstraints(),
  portalAnchor: Alignment.topCenter,
  childAnchor: Alignment.bottomCenter,
  spacing: FPortalSpacing.zero,
  overflow: FPortalOverflow.flip,
  offset: Offset.zero,
  viewInsets: EdgeInsets.zero,
  barrier: Container(color: Colors.blue),
  portalBuilder: (context, controller) => const Text('portal'),
  builder: (context, controller, child) => child!,
  child: const Text('child'),
);

Visualization

On this page