Elix render pipeline

Elix components use a functional-reactive programming (FRP) architecture. To achieve high quality, reliable behaviors across a large number of components, the project breaks down component behaviors in mixins. These mixins cooperate with each other, generally handling a specific point in a rendering pipeline:

events → methods → setState → render DOM → post-render

  1. User activity generates DOM events, such as a keydown or touchstart event. User activity can also trigger application behavior that produces custom element lifecycle callbacks (e.g., attributeChangedCallback). These can also be considered events in this pipeline.
  2. Event handlers respond by invoking methods or setting properties on the component. (In very simple cases, an event handler skip this step, and directly call setState to update component state.)
  3. Component methods/properties in turn update component state. The method/property may call setState directly, or it might invoke another method/property that ultimately calls setState.
  4. The component renders the state to the page using the standard DOM API.
  5. In rare cases, the component may need to perform post-render work that can only happen after the DOM has updated, such as update keyboard focus.

Mixins that handle events (events → methods)

Some of these mixins directly update state.

  • ArrowDirectionMixin. Adds left/right buttons that map to goLeft/goRight methods.
  • AttributeMarshallingMixin. Maps attributes to properties.
  • ClickSelectionMixin. Maps clicks on items to setting selectedIndex property.
  • ComposedFocusMixin. Normalizes focus treatment for custom elements with Shadow DOM.
  • DarkModeMixin. Lets a component automatically or explicitly configure itself for dark backgrounds.
  • DelegateFocusMixin. Delegates a component's focus to its first focusable shadow element.
  • EffectMixin. Simple foundation for component with visual effects.
  • FocusVisibleMixin. Tracks whether to show a focus indicator, sets [internal.state].focusVisible.
  • HoverMixin. Maps mouseenter/mouseleave events to [internal.state].hover.
  • KeyboardMixin. Maps keydown events to keydown method.
  • LanguageDirectionMixin. If component is in the content of a right-to-left language, this sets [internal.state].rightToLeft.
  • PopupModalityMixin. Maps blur and various window/document events to close method.
  • RepeatMousedownMixin. Generates mousedown events at intervals for as long as the mouse is down.
  • ResizeMixin. Maps changes in window or component size to clientHeight/clientWidth state members.
  • SlotContentMixin. When the component's slot receives a slotchange event, this updates [internal.state].content with the new nodes assigned to the slot.
  • SlotItemsMixin. Defines a component's content as the flattened set of nodes assigned to a slot.
  • SwipeCommandsMixin. Reveals commands behind list items when the user swipes left or right.
  • TapCursorMixin. A tap/mousedown on a list item makes that item current.
  • TimerCursorMixin. Automatically updates selection on a timer.
  • TouchSwipeMixin. Maps touch swipe gestures to [internal.state].swipeFraction and swipeLeft/swipeRight methods.
  • TrackpadSwipeMixin. Maps trackpad gestures to [internal.state].swipeFraction and swipeLeft/swipeRight methods.
  • TransitionEffectMixin. Manages state changes that depend upon completion of CSS transitions.

Mixins that map methods to other methods

These mixins generally map from a low-level abstraction (e.g., a specific type of key has been pressed) to a higher-level abstraction (something should be selected).

Mixins that update state (methods → setState)

  • CalendarElementMixin. Adds locale-dependent date support to an element in a calendar.
  • CursorSelectMixin. Keeps the current item and selected item in sync.
  • MultiSelectAPIMixin. Exposes a public API for multiple selection on a list-like element.
  • ItemsMultiSelectMixin. Tracks multiple selection state for a list-like element.
  • ItemsCursorMixin. Tracks and navigates the current item in a set of items
  • OpenCloseMixin. Tracks the opened/closed state, providing open/close methods that set a [internal.state].opened member.
  • SelectedTextAPIMixin. Supplies a public selectedText property that gets/sets the item specified by a selectedIndex property.
  • SelectedValueAPIMixin. Supplies a public value property that gets/sets the item specified by a selected item's value attribute.
  • SingleSelectAPIMixin. Provides a public API for setting and retrieving the selected item.
  • SelectableMixin. Tracks whether the element is currently selected.

Mixins that render state (setState → render DOM)

  • AriaListMixin. Renders [internal.state].selectedIndex as various ARIA attributes like aria-activedescendant.
  • AriaMenuMixin. Renders [internal.state].selectedIndex as various ARIA attributes like aria-checked.
  • AriaRoleMixin. Lets a component define its ARIA role through a role state member.
  • ArrowDirectionMixin. Renders left/right arrow buttons.
  • ContentItemsMixin. Defines an items property based on [internal.state].content, filtering out auxiliary invisible elements.
  • DelegateInputLabelMixin. Delegates its ARIA label property to an inner input-type element.
  • DelegateInputSelectionMixin. Delegates text selection methods and properties to an inner input-type element.
  • DelegateItemsMixin. Lets the items of a shadow element serve as the items of the component itself.
  • DialogModalityMixin. Renders a default ARIA role.
  • DisabledMixin. Tracks the disabled state of a component that can be disabled.
  • FormElementMixin. Allows a component to participate in HTML form submission.
  • OverlayMixin. Renders an open state as changes to display and z-index to make an element appear on top.
  • SlotItemsMixin. Defines a component's content as the flattened set of nodes assigned to a slot.

Mixins that perform work after render

In rare cases, a mixin may need to perform work after a component has been rendered in the DOM.

  • CursorInViewMixin. When [internal.state].selectedIndex changes, ensure that the selected item is scrolled into view.

Core mixins for reactive elements

For convenience, the following core mixins are provided in a base class called ReactiveElement.

All Elix components derive from ReactiveElement. However, when creating your own components, you don't have to use that base class; you can use the mixins above directly.

Other resources

More information and background about the Elix project can be found at the following: