Overview
Purpose: tracks the opened/closed state of an element with open/close semantics, such as a Dialog, Drawer, Popup, or Toast. It allows for the possibility that the open/close operations are asynchronous.
This mixin works in the middle of the Elix render pipeline:
events → methods ➞ setState → render DOM → post-render
Expects the component to provide:
- setStatemethod, usually supplied by ReactiveMixin.
Provides the component with:
- closemethod that closes the element.
- closedproperty that is the inverse of- opened.
- closeFinishedproperty. By default, this is the same value as the- closeproperty. If- [internal.state].openCloseEffects(see above) is true, then- closeFinishedis true only after the- closeeffect has finished (reached the- afterphase). See asynchronous effects, below.
- openmethod that opens the element.
- openedproperty that reflects the internal state of- [internal.state].opened.
- openedstate member that is true if the element is open, false if closed.
- [internal.state].openCloseEffectsmember that defaults to true if this mixin is used in combination with TransitionEffectMixin.
- togglemethod that toggles the opened/closed state.
Usage
import OpenCloseMixin from "elix/src/base/OpenCloseMixin.js";
class MyElement extends OpenCloseMixin(HTMLElement) {}
You can use OpenCloseMixin to provide any component that conceptually opens and closes with a consistent open/close API. This can make things easier for developers to use your component.
Using OpenCloseMixin allows makes it easy to take advantage of related Elix mixins, including DialogModalityMixin, OverlayMixin, PopupModalityMixin, and TransitionEffectMixin. However, OpenCloseMixin can be used for components which aren't overlays, such as components that expand or open in place.
Example
An overlay is one type of component that can be opened and closed. When open, they appear on top of other elements:
This paragraph has a z-index, but should appear behind the dialog. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse sed lorem scelerisque, blandit libero vitae, dapibus nisl. Sed turpis diam, placerat a feugiat sed, maximus at velit. Ut sit amet semper sapien. Donec vitae leo ex. Duis eget quam sed metus tempor lobortis eget feugiat elit. Cras varius, arcu ac commodo tincidunt, lectus dui convallis nunc, quis maximus nisl erat ac mi. Phasellus et velit diam.
A component might also choose to interpret the semantics of opening and closing as expanding or collapsing in place, as in ExpandablePanel:
Use of OpenCloseMixin in these situations allows for a consistent open/close API.
Asynchronous open/close effects
Many components that open and close do so with asynchronous transitional effects: fading in, sliding in, etc., when opened, then fading out or sliding out when closed. Such effects can add considerable complexity to an element's state, making it hard to define exactly when a component has "opened" or "closed".
To support such effects, OpenCloseMixin interoperates with TransitionEffectMixin. When used in combination, OpenCloseMixin will:
- Assume an element is completely closed by default. The default [internal.state].effectis "close", and the default[internal.state].effectPhaseis "after".
- Define [internal.state].openCloseEffectsto be true by default — i.e., that the element wants to use transition effects for open/close operations.
- Trigger the "open" effect when the element is opened by any means (the openortogglemethods, or settingopenedto true). This sets[internal.state].effectto "open" and the phase to "before".TransitionEffectMixinwill then manage the remaining phases of the effect.
- Conversely, trigger the "close" effect when the element is closed by any means.
API
Used by classes AlertDialog, AutoCompleteComboBox, ComboBox, DateComboBox, Dialog, Drawer, DrawerWithGrip, DropdownList, ExpandablePanel, ExpandableSection, FilterComboBox, HamburgerMenuButton, ListComboBox, MenuButton, Overlay, PlainAlertDialog, PlainAutoCompleteComboBox, PlainComboBox, PlainDateComboBox, PlainDialog, PlainDrawer, PlainDrawerWithGrip, PlainDropdownList, PlainExpandablePanel, PlainExpandableSection, PlainFilterComboBox, PlainHamburgerMenuButton, PlainListComboBox, PlainMenuButton, PlainOverlay, PlainPopup, PlainPopupButton, PlainPopupSource, PlainToast, Popup, PopupButton, PopupSource, Toast, and TooltipButton.
 close(closeResult)   method    
 Close the component (if not already closed).
Some components like AlertDialog want to indicate why or
how they were closed. To support such scenarios, you can supply a value
to the optional closeResult parameter. This closeResult will be made
available in the whenClosed promise and the state.closeResult member.
       
Parameters:
-  closeResult:  object– an indication of how or why the element closed
close event
Raised when the component closes.
closed property
True if the element is currently closed.
This read-only property is provided as a convenient inverse of opened.
       
Type: boolean
 close
 True if the element has completely closed.
For components not using asynchronous open/close effects, this property
returns the same value as the closed property. For elements that have a
true value of state.openCloseEffects (e.g., elements using
TransitionEffectMixin), this property returns
true only if state.effect is "close" and state.effectPhase is
"after".
       
Type: boolean
 open()   method  
 Open the element (if not already opened).
open event
Raised when the component opens.
opened property
True if the element is currently opened.
This property can be set as a boolean attribute
Type: boolean
Default: false
openedchange event
Raised when the opened/closed state of the component changes.
 toggle(opened)   method    
 Toggle the open/close state of the element.
Parameters:
-  opened:  boolean– true if the element should be opened, false if closed.
 when)   method  
 This method can be used as an alternative to listening to the "openedchange" event, particularly in situations where you want to only handle the next time the component is closed.
 Returns:  Promise A promise that resolves when the element has
completely closed, including the completion of any asynchronous opening
effect.