Implement a modal system

I decided to create my own and not to use a community package, because
1. it's straightforward
2. it's better integrated with our others libs such as EscapeActions
3. monitoring third-party packages evolutions (eg, CSS changes) is a
   lot of work.

This is basically the same rationale than for our other generic UI
components such as the Popup/Popover.

This commit also slightly modify the general layout to remove
unnecessary wrapper DOM nodes.
This commit is contained in:
Maxime Quandalle 2015-08-25 23:39:00 +02:00
parent 46a5e08aa7
commit 9faaf07e02
7 changed files with 79 additions and 10 deletions

View file

@ -76,6 +76,7 @@
"Filter": true,
"Filter": true,
"Mixins": true,
"Modal": true,
"MultiSelection": true,
"Popup": true,
"Sidebar": true,

View file

@ -30,7 +30,7 @@ BlazeComponent.extendComponent({
$cards.sortable({
connectWith: '.js-minicards',
tolerance: 'pointer',
appendTo: '#surface',
appendTo: 'body',
helper: function(evt, item) {
var helper = item.clone();
if (MultiSelection.isActive()) {

View file

@ -11,10 +11,16 @@ template(name="userFormsLayout")
+Template.dynamic(template=content)
template(name="defaultLayout")
#surface
+header
#content
+Template.dynamic(template=content)
+header
#content
+Template.dynamic(template=content)
if (Modal.isOpen)
#modal
.overlay
.modal-content
a.modal-close-btn.js-close-modal
i.fa.fa-times-thin
+Template.dynamic(template=Modal.getTemplateName)
template(name="notFound")
+message(label='page-not-found')

View file

@ -1,5 +1,13 @@
Meteor.subscribe('boards');
Meteor.subscribe('boards')
BlazeLayout.setRoot('body')
Template.userFormsLayout.onRendered(function() {
EscapeActions.executeAll();
});
EscapeActions.executeAll()
})
Template.defaultLayout.events({
'click .js-close-modal': () => {
Modal.close()
}
})

View file

@ -19,8 +19,6 @@ body
position: relative
z-index: 0
overflow-y: auto
#surface
display: flex
flex-direction: column
min-height: 100vh
@ -30,6 +28,30 @@ body
position: relative
flex: 1
#modal
position: absolute
top: 0
bottom: 0
left: 0
right: 0
background: rgba(0, 0, 0, 0.6)
z-index: 100
overflow-y: auto
.modal-content
width: 660px
min-height: 160px
margin: 42px auto
border-radius: 4px
background: darken(white, 13%)
z-index: 110
.modal-close-btn
display: block
float: right
margin: 12px
font-size: 24px
h1
font-size: 22px
line-height: 1.2em

View file

@ -13,6 +13,7 @@ EscapeActions = {
'popup-close',
'inlinedForm',
'detailsPane',
'modalWindow',
'multiselection',
'sidebarView'
],

31
client/lib/modal.js Normal file
View file

@ -0,0 +1,31 @@
const closedValue = null
Modal = new class {
constructor() {
this._currentModal = new ReactiveVar(closedValue)
}
getTemplateName() {
return this._currentModal.get()
}
isOpen() {
return this.getTemplateName() !== closedValue
}
close() {
this._currentModal.set(closedValue)
}
open(modalName) {
this._currentModal.set(modalName)
}
};
Blaze.registerHelper('Modal', Modal)
EscapeActions.register('modalWindow',
() => Modal.close(),
() => Modal.isOpen(),
{ noClickEscapeOn: '.modal-content' }
);