semantic-ui-riot
Version:
Semantic UI for Riot
516 lines (437 loc) • 15.4 kB
JavaScript
// ===================================================================================
// Lifecycle
// =========
function onBeforeUpdate(props) {
this.basic = this.root.classList.contains('basic');
if (props.modal) {
this.closable = typeof props.modal.closable === 'undefined' || props.modal.closable;
if (props.modal.header) {
this.header = props.modal.header;
this.headerClass = props.modal.header.icon ? 'icon' : '';
this.title = props.modal.header.text ? props.modal.header.text : props.modal.header;
}
if (props.modal.modeless === true) {
props.modal.modeless = {};
}
if (props.modal.modeless) {
if (typeof props.modal.modeless.minimize === 'undefined') {
props.modal.modeless.minimize = true;
}
if (typeof props.modal.modeless.resize === 'undefined') {
props.modal.modeless.resize = true;
}
}
this.buttons = props.modal.buttons;
this.buttons && this.buttons.forEach(button => {
const classes = [];
if (button.icon && button.text) classes.push('labeled');
if (button.icon) classes.push('icon');
if (this.basic) classes.push('inverted');
if (button.disabled) classes.push('disabled');
button.class = classes.join(' ');
});
}
this.modeless = isModeless(this);
this.modalClass = getModalClass(this);
this.contentClass = getContentClass(this);
this.dimmerClass = isDimmerModeless(this) ? 'modeless' : '';
if (this.modeless) {
this.minimizable = props.modal.modeless.minimize;
this.resizable = props.modal.modeless.resize;
}
if (props.show != this.lastShow) {
this.lastShow = props.show;
if (props.show) {
show(this);
} else {
hide(this);
}
}
}
// ===================================================================================
// Events
// ======
function onClickButton(item) {
this.dispatch(item.action || item.text);
if (typeof item.closable === 'undefined' || item.closable) {
hide(this);
}
}
function onClickDimmer() {
if (this.closable && !this.basic) {
hide(this);
}
}
function onClickModal(event) {
event.stopPropagation();
}
function onClickHide() {
hide(this);
}
function onToggleSize() {
this.maximized = !this.maximized;
this.update();
this.dispatch('toggleSize', this.maximized);
}
function onToggleMinimize() {
this.minimized = !this.minimized;
this.update({
transition: this.minimized ? '' : 'visible active'
});
this.update();
this.dispatch('toggleMinimize', this.minimized);
}
// ===================================================================================
// Logic
// =====
function show(tag) {
if (tag.openning || tag.closing || tag.visible) {
return
}
tag.openning = true;
tag.state.transition = 'animating fade in visible';
tag.dispatch('show');
tag.update();
setDefaultFocus(tag);
setTimeout(() => {
tag.openning = false;
tag.visible = true;
tag.update({
transition: 'visible active'
});
}, 500);
}
function hide(tag) {
if (tag.openning || tag.closing || !tag.visible) {
return
}
tag.closing = true;
tag.update({
transition: 'animating fade out visible active'
});
tag.dispatch('hide');
tag.update();
setTimeout(() => {
tag.closing = false;
tag.visible = false;
tag.update({
transition: ''
});
}, 300);
}
function setDefaultFocus(tag) {
if (!tag.buttons || tag.buttons.length == 0) {
return
}
if (tag.buttons.some(button => button.default)) {
const text = tag.buttons.filter(button => button.default)[0].text;
tag.$(`[name='button_${text}']`).focus();
}
}
function getModalClass(tag) {
if (!tag.maximized && isModeless(tag) && tag.props.modal.modeless.class) {
return tag.props.modal.modeless.class
}
return tag.props.class
}
function getContentClass(tag) {
const classes = [];
if (tag.$('img')) {
classes.push('image');
}
if (tag.root.classList.contains('scrolling') || !tag.maximized && isModeless(tag) && tag.props.modal.modeless.class) {
classes.push('scrolling');
}
return classes.join(' ')
}
function isModeless(tag) {
return !tag.closable && tag.props.modal.modeless
}
function isDimmerModeless(tag) {
return isModeless(tag) && !tag.minimized && !tag.maximized
}
var suModal = {
'css': `su-modal .ui.dimmer.visible.transition,[is="su-modal"] .ui.dimmer.visible.transition{ display: flex !important; align-items: center; justify-content: center; } su-modal .ui.modal,[is="su-modal"] .ui.modal{ top: auto; left: auto; position: relative; margin: 0 !important; } su-modal .ui.fullscreen.modal,[is="su-modal"] .ui.fullscreen.modal{ left: 0 !important; } only screen and (min-width: 768px) { su-modal .ui.modal>.close,[is="su-modal"] .ui.modal>.close{ display: none; } su-modal .ui.fullscreen.modal>.close,[is="su-modal"] .ui.fullscreen.modal>.close{ display: inline; } } su-modal .ui.dimmer.modeless.visible.transition,[is="su-modal"] .ui.dimmer.modeless.visible.transition{ visibility: hidden !important; display: block !important; } su-modal .ui.dimmer.modeless>.ui.modal,[is="su-modal"] .ui.dimmer.modeless>.ui.modal{ position: absolute; right: 0; bottom: 0; } su-modal .ui.modal>.restore,[is="su-modal"] .ui.modal>.restore,su-modal .ui.modal>.maximize,[is="su-modal"] .ui.modal>.maximize{ right: 1rem; } su-modal .ui.modal>.minimize,[is="su-modal"] .ui.modal>.minimize{ right: 4rem; } su-modal .ui.modal>.icon,[is="su-modal"] .ui.modal>.icon{ display: inline; top: 1.0535rem; color: rgba(0, 0, 0, .87); cursor: pointer; position: absolute; z-index: 1; opacity: 0.8; font-size: 1.25em; width: 2.25rem; height: 2.25rem; padding: 0.625rem 0rem 0rem 0rem; } su-modal .unminimize.label,[is="su-modal"] .unminimize.label{ position: fixed; right: 0; bottom: -6px; padding-bottom: 1rem; z-index: 1000; }`,
'exports': {
state: {
transition: '',
},
openning: false,
closing: false,
closable: true,
visible: false,
minimized: false,
maximized: true,
onBeforeUpdate,
onClickModal,
onClickButton,
onClickHide,
onClickDimmer,
onToggleSize,
onToggleMinimize
},
'template': function(template, expressionTypes, bindingTypes, getComponent) {
return template(
'<div expr66="expr66"><div expr67="expr67"><div expr68="expr68"></div><template expr70="expr70"></template><i expr74="expr74" class="close icon"></i><div expr75="expr75"><slot expr76="expr76"></slot></div><div class="actions"><button expr77="expr77" type="button"></button></div></div></div><a expr79="expr79" class="ui grey big label unminimize"></a>',
[{
'expressions': [{
'type': expressionTypes.EVENT,
'name': 'onclick',
'evaluate': function(scope) {
return scope.onClickDimmer;
}
}, {
'type': expressionTypes.ATTRIBUTE,
'name': 'id',
'evaluate': function(scope) {
return scope.su_id;
}
}, {
'type': expressionTypes.ATTRIBUTE,
'name': 'class',
'evaluate': function(scope) {
return scope.modalClass;
}
}]
}, {
'redundantAttribute': 'expr66',
'selector': '[expr66]',
'expressions': [{
'type': expressionTypes.ATTRIBUTE,
'name': 'class',
'evaluate': function(scope) {
return [
'ui dimmer modals page transition ',
scope.state.transition,
' ',
scope.dimmerClass
].join('');
}
}]
}, {
'redundantAttribute': 'expr67',
'selector': '[expr67]',
'expressions': [{
'type': expressionTypes.ATTRIBUTE,
'name': 'class',
'evaluate': function(scope) {
return ['ui modal transition visible active ', scope.modalClass].join('');
}
}, {
'type': expressionTypes.EVENT,
'name': 'onclick',
'evaluate': function(scope) {
return scope.onClickModal;
}
}]
}, {
'type': bindingTypes.IF,
'evaluate': function(scope) {
return scope.header;
},
'redundantAttribute': 'expr68',
'selector': '[expr68]',
'template': template('<i expr69="expr69"></i> ', [{
'expressions': [{
'type': expressionTypes.TEXT,
'childNodeIndex': 1,
'evaluate': function(scope) {
return [scope.title].join('');
}
}, {
'type': expressionTypes.ATTRIBUTE,
'name': 'class',
'evaluate': function(scope) {
return ['ui header ', scope.headerClass].join('');
}
}]
}, {
'type': bindingTypes.IF,
'evaluate': function(scope) {
return scope.header.icon;
},
'redundantAttribute': 'expr69',
'selector': '[expr69]',
'template': template(null, [{
'expressions': [{
'type': expressionTypes.ATTRIBUTE,
'name': 'class',
'evaluate': function(scope) {
return ['icon ', scope.header.icon].join('');
}
}]
}])
}])
}, {
'type': bindingTypes.IF,
'evaluate': function(scope) {
return scope.modeless && !scope.basic;
},
'redundantAttribute': 'expr70',
'selector': '[expr70]',
'template': template(
'<i expr71="expr71" class="window minimize icon"></i><i expr72="expr72" class="window restore icon"></i><i expr73="expr73" class="window maximize icon"></i>',
[{
'type': bindingTypes.IF,
'evaluate': function(scope) {
return scope.minimizable;
},
'redundantAttribute': 'expr71',
'selector': '[expr71]',
'template': template(null, [{
'expressions': [{
'type': expressionTypes.EVENT,
'name': 'onclick',
'evaluate': function(scope) {
return scope.onToggleMinimize;
}
}]
}])
}, {
'type': bindingTypes.IF,
'evaluate': function(scope) {
return scope.resizable && scope.maximized;
},
'redundantAttribute': 'expr72',
'selector': '[expr72]',
'template': template(null, [{
'expressions': [{
'type': expressionTypes.EVENT,
'name': 'onclick',
'evaluate': function(scope) {
return scope.onToggleSize;
}
}]
}])
}, {
'type': bindingTypes.IF,
'evaluate': function(scope) {
return scope.resizable && !scope.maximized;
},
'redundantAttribute': 'expr73',
'selector': '[expr73]',
'template': template(null, [{
'expressions': [{
'type': expressionTypes.EVENT,
'name': 'onclick',
'evaluate': function(scope) {
return scope.onToggleSize;
}
}]
}])
}]
)
}, {
'type': bindingTypes.IF,
'evaluate': function(scope) {
return scope.closable && !scope.basic;
},
'redundantAttribute': 'expr74',
'selector': '[expr74]',
'template': template(null, [{
'expressions': [{
'type': expressionTypes.EVENT,
'name': 'onclick',
'evaluate': function(scope) {
return scope.onClickHide;
}
}]
}])
}, {
'redundantAttribute': 'expr75',
'selector': '[expr75]',
'expressions': [{
'type': expressionTypes.ATTRIBUTE,
'name': 'class',
'evaluate': function(scope) {
return ['content ', scope.contentClass].join('');
}
}]
}, {
'type': bindingTypes.SLOT,
'attributes': [],
'name': 'default',
'redundantAttribute': 'expr76',
'selector': '[expr76]'
}, {
'type': bindingTypes.EACH,
'getKey': null,
'condition': null,
'template': template(' <i expr78="expr78"></i>', [{
'expressions': [{
'type': expressionTypes.TEXT,
'childNodeIndex': 0,
'evaluate': function(scope) {
return [scope.button.text].join('');
}
}, {
'type': expressionTypes.EVENT,
'name': 'onclick',
'evaluate': function(scope) {
return () => scope.onClickButton(scope.button);
}
}, {
'type': expressionTypes.ATTRIBUTE,
'name': 'name',
'evaluate': function(scope) {
return ['button_', scope.button.text].join('');
}
}, {
'type': expressionTypes.ATTRIBUTE,
'name': 'class',
'evaluate': function(scope) {
return ['ui button ', scope.button.type, ' ', scope.button.class].join('');
}
}]
}, {
'type': bindingTypes.IF,
'evaluate': function(scope) {
return scope.button.icon;
},
'redundantAttribute': 'expr78',
'selector': '[expr78]',
'template': template(null, [{
'expressions': [{
'type': expressionTypes.ATTRIBUTE,
'name': 'class',
'evaluate': function(scope) {
return ['icon ', scope.button.icon].join('');
}
}]
}])
}]),
'redundantAttribute': 'expr77',
'selector': '[expr77]',
'itemName': 'button',
'indexName': null,
'evaluate': function(scope) {
return scope.buttons;
}
}, {
'type': bindingTypes.IF,
'evaluate': function(scope) {
return scope.minimized;
},
'redundantAttribute': 'expr79',
'selector': '[expr79]',
'template': template('<i class="angle double up icon"></i> ', [{
'expressions': [{
'type': expressionTypes.TEXT,
'childNodeIndex': 1,
'evaluate': function(scope) {
return [scope.title].join('');
}
}, {
'type': expressionTypes.EVENT,
'name': 'onclick',
'evaluate': function(scope) {
return scope.onToggleMinimize;
}
}]
}])
}]
);
},
'name': 'su-modal'
};
export default suModal;