-
Notifications
You must be signed in to change notification settings - Fork 4
Popup modals sidepanels
Overview of the notions used in services LuModal
, LuPopup
and LuSidepanel
, so you can have a better understanding of how it was coded and how it is meant to be used
@Component(/* ... */)
export class MyComponent {
constructor(private _modal: LuModal) {}
openModal(data) {
this._modal.open(MyModal, data, config).onClose
.subscribe(result => /* ... */);
}
}
see some examples on prisme
For popup, modal or sidepanel, the signature of the open
method is as follow
open<C, D, R>(component: ComponentType<C>, data?: D, config?): ILuPopupRef<C, D, R>
and the ILuPopupRef
interface has this definition:
export interface ILuPopupRef<T, D = any, R = any> {
onOpen: Observable<D>;
onClose: Observable<R>;
open(data: D): void;
close(result: R): void;
}
so the most basic-est way to use a modal is to write
const ref = this._modal.open(Component, data);
ref.onClose.subscribe(result => ...);
and treat it as you would treat an async call through a service
const call = this._service.call(...args);
call.subscribe(result => ...);
except instead of waiting for a http.get, here you are waiting for the end user to do stuff in the modal.
If you look at how Dialogs are handled in angular material, the data you can transmit to the dialog is a member of the config, here it is a main argument of the method, allowing you to open modals with the same config but not the same data.
they all do basically the same thing and the way the method open
handles is basically the same. But while a popup has no opinions and no restriction on how to use it, a modal or a sidepanel come with some.
You can use the LuPopup
as you would use MatDialog
, there are no contraints on what component you can open in a popup
A modal, as defined by our UX team, has a title, a cross icon ton left and a footer with 2 actions. one primary, one to dismiss the modal. It is primarily used for handling async actions that could fail and as such the primary button must convey when the action is pending and if it successes or fails.
as a result if you want to open a modal, the component you inject must implement ILuModalContent
whose interface definition is
export interface ILuModalContent<T = any> extends ILuPopupContent {
title: string; // the title for the modal
submitAction?: () => Observable<T>; // the method that will be called when clicking the primary button
submitDisabled?: boolean;
submitLabel?: string; // label of the primary button - default `Ok`
cancelLabel?: string; // label of the dismiss button - default `Cancel|Annuler`
}
by just providing the primary action, it allows the modal to have a unified user experience
- while the action is performing, the primary button has the state
is-loading
- if the action succeeds, then the state
is-success
is applied .5s, before closing the modal - if the action throws, then the button becomes
is-error
2s before returning to norymal, and the error is displayed in the footer
see prisme for more infos about button states
for now a sidepanel is the same as a modal, but on the side. so the same restrictions apply
To harmonize the user experience in modals, you should use the LuModal
service as much as possible. It is a bit restrictive but thats a trade off for the added Comportment.
The LuPopup
lets you do whatever you want, but you'll have to implement the same comportment if you want an harmonious UX