FSAI Design System
Components

Inline Entity Manager

Compound inline choose/create/manage entity pattern built on Popover for contextual selection without leaving the current workflow.

Overview

InlineEntityManager is a compound component for choosing, searching, creating, and often editing related entities without navigating away from the current surface.

This is one of the platform's main "stay in context" interaction patterns.

It is built on top of Popover, adds shared search state, and provides a reusable panel structure for entity management UI.

There are two layers:

LayerRole
InlineEntityManager.*Low-level compound API for custom inline entity flows
InlineEntityManagerDefaultOpinionated default chooser panel for common entity-selection cases

When To Use It

Use InlineEntityManager when the user needs to:

  • choose a related entity in context
  • search through available entities
  • create a missing entity without leaving the current flow
  • manage lightweight entity metadata or actions inline

Prefer it over a normal Select when the entity has richer identity, search/create flows, or management actions that do not fit a simple dropdown.

Compound API

PartPurpose
InlineEntityManager.RootRoot wrapper. Handles popover state, search state, and placement.
InlineEntityManager.TriggerTrigger button/anchor for opening the manager.
InlineEntityManager.PanelFloating panel surface.
InlineEntityManager.PanelHeaderStandard panel header with icon and title.
InlineEntityManager.SearchInputSearch field wired to shared manager state.
InlineEntityManager.ListScrollable list container.
InlineEntityManager.ItemSelectable entity row with checkbox-style selection.
InlineEntityManager.HelperTextSmall helper/empty-state text.
InlineEntityManager.FooterFooter area for create-new or extra actions.
InlineEntityManager.BadgeCompact selected-entity badge, also usable outside the panel.
useInlineEntityManagerAccesses shared manager state (searchValue, setSearchValue, open, close).

Default Pattern

For most standard inline entity pickers, start with InlineEntityManagerDefault.

<InlineEntityManager.Root>
  <InlineEntityManager.Trigger>
    <InlineEntityManager.Badge
      color={getDealStatusColor(selected)}
      iconId={getDealStatusIcon(selected)}
      label={getDealStatusLabel(selected)}
    />
  </InlineEntityManager.Trigger>

  <InlineEntityManagerDefault
    headerIcon="CircleHalfFill"
    headerTitle="Change Status"
    entities={statusEntities}
    selectedIds={[selected]}
    onToggleEntity={(status) => onSelect(status.id)}
    withSearch={false}
    helperText="Select a status"
  />
</InlineEntityManager.Root>

This is the production pattern used for inline status management in Deals.components.tsx.

Custom Composition

Drop down to the compound primitives when the panel needs more than the default chooser.

<InlineEntityManager.Root className="w-full">
  <InlineEntityManager.Trigger className="flex w-full items-center justify-between rounded-md border border-strong bg-gray-bg-surface px-3 py-2 text-left">
    <span className="text-sm text-dim">Select category</span>
    <Icon name="ChevronBottom" className="h-4 w-4 text-dim" />
  </InlineEntityManager.Trigger>

  <InlineEntityManager.Panel className="w-[380px]">
    <InlineEntityManager.PanelHeader icon="Folders" title="Category" />
    <div className="px-3">
      <InlineEntityManager.SearchInput placeholder="Search categories..." />
    </div>
    <InlineEntityManager.List>
      {/* custom item rendering */}
    </InlineEntityManager.List>
    <InlineEntityManager.Footer className="px-3">
      <button type="button">Create Category</button>
    </InlineEntityManager.Footer>
  </InlineEntityManager.Panel>
</InlineEntityManager.Root>

This is the real pattern used in LmsCategoryEditor.tsx.

Search State

InlineEntityManager.SearchInput and useInlineEntityManager() share the same local search state.

That means custom list components can filter based on the manager's searchValue instead of re-creating local search state.

const { searchValue } = useInlineEntityManager();

This is one of the reasons InlineEntityManager works well as a reusable interaction pattern rather than just a styled popover.

Root Props

PropTypeDefaultDescription
childrenReactNodeRequired. Trigger and panel content.
classNamestringAdditional root wrapper classes.
initialSearchValuestringInitial search text.
resetSearchOnClosebooleantrueResets search text when the manager closes.
placementPlacementPopover placement.

Default Props

InlineEntityManagerDefault

PropTypeDefaultDescription
withSearchbooleantrueShows the built-in search input.
headerIconIconNameRequired header icon.
headerTitlestringRequired header title.
entitiesEntity[][]Available entities.
selectedIdsstring[][]Selected entity ids.
onToggleEntity(entity) => void | Promise<void>Called when an entity is toggled.
searchPlaceholderstring'Search'Search placeholder text.
helperTextstring'Select an option'Helper text above the list.
emptyTextstring'Nothing yet.'Empty-state text.
loadingStateReactNodeCustom loading-state content.
isLoadingbooleanShows loading state.
footerConfig{ text, onClick, icon? }Optional footer action for create-new or related actions.
contextMenuItems(entity) => ContextMenuItem[]Optional per-entity context actions.
panelClassNamestringAdditional panel classes.
renderItemContent(entity) => ReactNodeCustom item content override.

Brand Dashboard Usage

Representative usages:

PatternPathNotes
Inline deal status managerfsai/apps/brand-dashboard/src/pages/Deals/Deals.components.tsxBest simple example of InlineEntityManagerDefault.
LMS category selectorfsai/apps/brand-dashboard/src/pages/Learning/components/LmsCategorySelector.tsxSearchable chooser pattern with custom list wiring.
LMS category choose/create/edit flowfsai/apps/brand-dashboard/src/pages/Learning/components/LmsCategoryEditor.tsxBest example of richer custom composition with create and edit states.
Helpdesk category editorfsai/apps/brand-dashboard/src/pages/AdminPanel/Helpdesk/HelpdeskCategoryEditor.tsxAnother strong create/manage-in-place example.
Badge-only status displayfsai/apps/brand-dashboard/src/pages/Leads/Leads.components.tsxShows InlineEntityManager.Badge used outside the manager itself.

Important Conventions

  • InlineEntityManager is fundamentally a contextual management pattern, not just a fancy dropdown.
  • InlineEntityManager.Root stops click and mouse-down propagation because it is often embedded inside clickable rows or dense surfaces.
  • InlineEntityManager.Item uses checkbox-style selection UI, which makes it feel different from a normal Menu or Select item.
  • InlineEntityManagerDefault is the right starting point when the panel is mostly a searchable selectable list.
  • If the flow needs create/edit/delete states or richer panel content, switch to the compound primitives instead of overloading the default wrapper.

Relationship To Other Components

  • Use Select for normal choose-from-list fields.
  • Use AutocompleteSelect when search-first form selection is the primary need, especially if add-new behavior can still keep the user in context.
  • Use InlineEntityManager when entity selection also needs inline creation, management, or richer contextual identity than a field-style selector normally provides.
  • Use GuidedFlow or Panel when the inline task grows into a larger staged workflow.

Guidelines

  • Do use InlineEntityManager for related-entity choose/create/manage flows that should stay in context
  • Do start with InlineEntityManagerDefault for ordinary searchable choosers
  • Do switch to the compound primitives when the panel needs custom flows or editing states
  • Don't use it for simple form dropdowns that Select already handles well
  • Don't navigate users away for small related-entity tasks that fit comfortably inline

On this page