Commit 913bc508 authored by Camil Staps's avatar Camil Staps 🚀

Merge branch 'tabbar-as-component' into 'master'

Created a separate tab bar editor to make choices with

See merge request !306
parents ab95d506 9638959d
Pipeline #29280 passed with stage
in 5 minutes and 12 seconds
......@@ -97,6 +97,7 @@ derive class iTask UIChange, UIAttributeChange, UIChildChange
| UIChoiceList // - A mutually exclusive set of radio buttons
| UIGrid // - Grid (selecting an item in a table)
| UITree // - Tree (selecting a node in a tree structure)
| UITabBar // - A tab bar (to make a selection with)
// Data elements (implemented in itasks-core.js)
| UIData
......
......@@ -231,6 +231,7 @@ where
toString UIChoiceList = "ChoiceList"
toString UIGrid = "Grid"
toString UITree = "Tree"
toString UITabBar = "TabBar"
toString UIContainer = "Container"
toString UIPanel = "Panel"
......
......@@ -118,6 +118,12 @@ grid :: Editor (ChoiceGrid, [Int])
* Supported attributes:
*/
tree :: Editor ([ChoiceNode], [Int])
/**
* A horizontal bar with tabs to make a selection with
*/
tabBar :: Editor ([ChoiceText], [Int])
/**
* Modifies the above editors for making choices such that they use a constant set of choices.
*/
......
......@@ -77,6 +77,9 @@ checkGroup = choiceComponent (const 'DM'.newMap) id toOptionText checkBoundsText
choiceList :: Editor ([ChoiceText], [Int])
choiceList = choiceComponent (const 'DM'.newMap) id toOptionText checkBoundsText UIChoiceList
tabBar :: Editor ([ChoiceText], [Int])
tabBar = choiceComponent (const 'DM'.newMap) id toOptionText checkBoundsText UITabBar
toOptionText {ChoiceText|id,text}= JSONObject [("id",JSONInt id),("text",JSONString text)]
checkBoundsText options idx = or [id == idx \\ {ChoiceText|id} <- options]
......
......@@ -150,8 +150,9 @@ div.itasks-exception {
font-weight: normal;
overflow: auto;
flex-basis: 0;
flex-direction: column;
}
*.itasks-viewport div, *.itasks-viewport input, *.itasks-viewport td, *.itasks-viewport th, *.itasks-viewport select {
*.itasks-viewport div, *.itasks-viewport input, *.itasks-viewport td, *.itasks-viewport th, *.itasks-viewport select, *.itasks-viewport ul {
font-size: 9pt;
}
*.itasks-viewport .icon-help {
......@@ -462,7 +463,28 @@ div.itasks-exception {
.itasks-tabset > * {
align-self: stretch;
}
.itasks-tabset .itasks-tabbar {
.itasks-tabset .itasks-tabitems {
z-index: 2;
border: 1px solid #ccc;
border-top-width: 0;
background-color: #eee;
flex: 1;
display: flex;
flex-direction: column;
}
.itasks-tabset .itasks-container.itasks-tabitem, .itasks-tabset .itasks-panel.itasks-tabitem, .itasks-tabset .itasks-viewport.itasks-tabitem {
display: none;
}
.itasks-tabset .itasks-panel.itasks-tabitem.itasks-selected {
display: grid;
border-top: 0;
}
.itasks-tabset .itasks-container.itasks-tabitem.itasks-selected, .itasks-tabset .itasks-viewport.itasks-tabitem.itasks-selected {
display: flex;
border-top: 0;
}
.itasks-tabbar {
text-align: left;
list-style: none;
margin: 0;
......@@ -473,7 +495,7 @@ div.itasks-exception {
background: linear-gradient(#fdb286, #fb7322);
overflow: hidden;
}
.itasks-tabset .itasks-tabbar li {
.itasks-tabbar li {
margin: 0;
padding: 0 10px;
border: 1px solid #ccc;
......@@ -484,12 +506,12 @@ div.itasks-exception {
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.itasks-tabset .itasks-tabbar li a {
.itasks-tabbar li a {
color: #000;
text-decoration: none;
}
.itasks-tabset .itasks-tabbar li:before,
.itasks-tabset .itasks-tabbar li:after {
.itasks-tabbar li:before,
.itasks-tabbar li:after {
position: absolute;
bottom: -1px;
width: 5px;
......@@ -497,31 +519,31 @@ div.itasks-exception {
content: " ";
border: 1px solid #ccc;
}
.itasks-tabset .itasks-tabbar li:before {
.itasks-tabbar li:before {
left: -6px;
border-bottom-right-radius: 5px;
border-width: 0 1px 1px 0;
box-shadow: 2px 2px 0 #e1e1e1;
}
.itasks-tabset .itasks-tabbar li:after {
.itasks-tabbar li:after {
right: -6px;
border-bottom-left-radius: 5px;
border-width: 0 0 1px 1px;
box-shadow: -2px 2px 0 #e1e1e1;
}
.itasks-tabset .itasks-tabbar li.itasks-selected {
.itasks-tabbar li.itasks-selected {
background: #eee;
color: #000;
z-index: 2;
border-bottom-color: #eee;
}
.itasks-tabset .itasks-tabbar li.itasks-selected:before {
.itasks-tabbar li.itasks-selected:before {
box-shadow: 2px 2px 0 #eee;
}
.itasks-tabset .itasks-tabbar li.itasks-selected:after {
.itasks-tabbar li.itasks-selected:after {
box-shadow: -2px 2px 0 #eee;
}
.itasks-tabset .itasks-tabbar li a.itasks-tabclose {
.itasks-tabbar li a.itasks-tabclose {
color: #aaa;
display: inline-block;
position: relative;
......@@ -535,7 +557,8 @@ div.itasks-exception {
border-radius: 2px;
padding: 0 2px;
}
.itasks-tabset .itasks-tabbar:after {
.itasks-tabbar:after {
position: absolute;
content: "";
width: 100%;
......@@ -544,10 +567,12 @@ div.itasks-exception {
border-bottom: 1px solid #ccc;
z-index: 1;
}
.itasks-tabset .itasks-tabbar:before {
.itasks-tabbar:before {
z-index: 1;
}
.itasks-tabset .itasks-tabicon {
.itasks-tabicon {
width: 16px;
height: 16px;
display: inline-block;
......@@ -555,32 +580,14 @@ div.itasks-exception {
position: relative;
top: 3px;
}
.itasks-tabset .itasks-tab-disabled .itasks-tabicon {
.itasks-tab-disabled .itasks-tabicon {
opacity: 0.5;
}
.itasks-tabset .itasks-tab-disabled span {
.itasks-tab-disabled span {
color: #aaa;
}
.itasks-tabset .itasks-tabitems {
z-index: 2;
border: 1px solid #ccc;
border-top-width: 0;
background-color: #eee;
flex: 1;
display: flex;
flex-direction: column;
}
.itasks-tabset .itasks-container.itasks-tabitem, .itasks-tabset .itasks-panel.itasks-tabitem, .itasks-tabset .itasks-viewport.itasks-tabitem {
display: none;
}
.itasks-tabset .itasks-panel.itasks-tabitem.itasks-selected {
display: grid;
border-top: 0;
}
.itasks-tabset .itasks-container.itasks-tabitem.itasks-selected, .itasks-tabset .itasks-viewport.itasks-tabitem.itasks-selected {
display: flex;
border-top: 0;
}
.itasks-toolbar, .itasks-buttonbar {
align-self: stretch;
......
......@@ -150,8 +150,9 @@ div.itasks-exception {
font-weight: normal;
overflow: auto;
flex-basis: 0;
flex-direction: column;
}
*.itasks-viewport div, *.itasks-viewport input, *.itasks-viewport td, *.itasks-viewport th, *.itasks-viewport select {
*.itasks-viewport div, *.itasks-viewport input, *.itasks-viewport td, *.itasks-viewport th, *.itasks-viewport select, *.itasks-viewport ul {
font-size: 9pt;
}
*.itasks-viewport .icon-help {
......@@ -462,7 +463,28 @@ div.itasks-exception {
.itasks-tabset > * {
align-self: stretch;
}
.itasks-tabset .itasks-tabbar {
.itasks-tabset .itasks-tabitems {
z-index: 2;
border: 1px solid #ccc;
border-top-width: 0;
background-color: #eee;
flex: 1;
display: flex;
flex-direction: column;
}
.itasks-tabset .itasks-container.itasks-tabitem, .itasks-tabset .itasks-panel.itasks-tabitem, .itasks-tabset .itasks-viewport.itasks-tabitem {
display: none;
}
.itasks-tabset .itasks-panel.itasks-tabitem.itasks-selected {
display: grid;
border-top: 0;
}
.itasks-tabset .itasks-container.itasks-tabitem.itasks-selected, .itasks-tabset .itasks-viewport.itasks-tabitem.itasks-selected {
display: flex;
border-top: 0;
}
.itasks-tabbar {
text-align: left;
list-style: none;
margin: 0;
......@@ -473,7 +495,7 @@ div.itasks-exception {
background: linear-gradient(white, #ccc);
overflow: hidden;
}
.itasks-tabset .itasks-tabbar li {
.itasks-tabbar li {
margin: 0;
padding: 0 10px;
border: 1px solid #ccc;
......@@ -484,12 +506,12 @@ div.itasks-exception {
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.itasks-tabset .itasks-tabbar li a {
.itasks-tabbar li a {
color: #000;
text-decoration: none;
}
.itasks-tabset .itasks-tabbar li:before,
.itasks-tabset .itasks-tabbar li:after {
.itasks-tabbar li:before,
.itasks-tabbar li:after {
position: absolute;
bottom: -1px;
width: 5px;
......@@ -497,31 +519,31 @@ div.itasks-exception {
content: " ";
border: 1px solid #ccc;
}
.itasks-tabset .itasks-tabbar li:before {
.itasks-tabbar li:before {
left: -6px;
border-bottom-right-radius: 5px;
border-width: 0 1px 1px 0;
box-shadow: 2px 2px 0 #e1e1e1;
}
.itasks-tabset .itasks-tabbar li:after {
.itasks-tabbar li:after {
right: -6px;
border-bottom-left-radius: 5px;
border-width: 0 0 1px 1px;
box-shadow: -2px 2px 0 #e1e1e1;
}
.itasks-tabset .itasks-tabbar li.itasks-selected {
.itasks-tabbar li.itasks-selected {
background: #eee;
color: #000;
z-index: 2;
border-bottom-color: #eee;
}
.itasks-tabset .itasks-tabbar li.itasks-selected:before {
.itasks-tabbar li.itasks-selected:before {
box-shadow: 2px 2px 0 #eee;
}
.itasks-tabset .itasks-tabbar li.itasks-selected:after {
.itasks-tabbar li.itasks-selected:after {
box-shadow: -2px 2px 0 #eee;
}
.itasks-tabset .itasks-tabbar li a.itasks-tabclose {
.itasks-tabbar li a.itasks-tabclose {
color: #aaa;
display: inline-block;
position: relative;
......@@ -535,7 +557,8 @@ div.itasks-exception {
border-radius: 2px;
padding: 0 2px;
}
.itasks-tabset .itasks-tabbar:after {
.itasks-tabbar:after {
position: absolute;
content: "";
width: 100%;
......@@ -544,10 +567,12 @@ div.itasks-exception {
border-bottom: 1px solid #ccc;
z-index: 1;
}
.itasks-tabset .itasks-tabbar:before {
.itasks-tabbar:before {
z-index: 1;
}
.itasks-tabset .itasks-tabicon {
.itasks-tabicon {
width: 16px;
height: 16px;
display: inline-block;
......@@ -555,32 +580,14 @@ div.itasks-exception {
position: relative;
top: 3px;
}
.itasks-tabset .itasks-tab-disabled .itasks-tabicon {
.itasks-tab-disabled .itasks-tabicon {
opacity: 0.5;
}
.itasks-tabset .itasks-tab-disabled span {
.itasks-tab-disabled span {
color: #aaa;
}
.itasks-tabset .itasks-tabitems {
z-index: 2;
border: 1px solid #ccc;
border-top-width: 0;
background-color: #eee;
flex: 1;
display: flex;
flex-direction: column;
}
.itasks-tabset .itasks-container.itasks-tabitem, .itasks-tabset .itasks-panel.itasks-tabitem, .itasks-tabset .itasks-viewport.itasks-tabitem {
display: none;
}
.itasks-tabset .itasks-panel.itasks-tabitem.itasks-selected {
display: grid;
border-top: 0;
}
.itasks-tabset .itasks-container.itasks-tabitem.itasks-selected, .itasks-tabset .itasks-viewport.itasks-tabitem.itasks-selected {
display: flex;
border-top: 0;
}
.itasks-toolbar, .itasks-buttonbar {
align-self: stretch;
......
......@@ -6,7 +6,7 @@
text-align: left;
font-weight: normal;
div, input, td, th, select {
div, input, td, th, select, ul {
font-size: 9pt;
}
......@@ -15,6 +15,7 @@
overflow: auto;
flex-basis: 0;
flex-direction: column;
}
.#{$prefix}container {
......@@ -201,110 +202,6 @@
> * {
align-self: stretch;
}
.#{$prefix}tabbar {
text-align: left;
list-style: none;
margin: 0;
padding: 0 10px;
line-height: 24px;
position: relative;
min-height: 24px;
background: linear-gradient(lighten($panel-header-base-color,20%), $panel-header-base-color);
overflow: hidden;
li {
margin: 0;
padding: 0 10px;
border: 1px solid $tab-border-color;
background: darken($tab-base-color, 5%);
display: inline-block;
position: relative;
z-index: 0;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
li a {
color: $tab-text-color;
text-decoration: none;
}
li:before,
li:after {
position: absolute;
bottom: -1px;
width: 5px;
height: 5px;
content: " ";
border: 1px solid $tab-border-color;
}
li:before {
left: -6px;
border-bottom-right-radius: 5px;
border-width: 0 1px 1px 0;
box-shadow: 2px 2px 0 darken($tab-base-color,5%);
}
li:after {
right: -6px;
border-bottom-left-radius: 5px;
border-width: 0 0 1px 1px;
box-shadow: -2px 2px 0 darken($tab-base-color,5%);
}
li.#{$prefix}selected {
background: $tab-base-color;
color: $tab-text-color;
z-index: 2;
border-bottom-color: $tab-base-color;
}
li.#{$prefix}selected:before {
box-shadow: 2px 2px 0 $tab-base-color;
}
li.#{$prefix}selected:after {
box-shadow: -2px 2px 0 $tab-base-color;
}
li a.#{$prefix}tabclose {
color: #aaa;
display: inline-block;
position: relative;
top: -5px;
left: 7px;
font-weight: bold;
font-size: 8px;
line-height: 8px;
background: #eee;
border: 1px solid #ccc;
border-radius: 2px;
padding: 0 2px;
}
}
.#{$prefix}tabbar:after {
position: absolute;
content: "";
width: 100%;
bottom: 0;
left: 0;
border-bottom: 1px solid $tab-border-color;
z-index: 1;
}
.#{$prefix}tabbar:before {
z-index: 1;
}
.#{$prefix}tabicon {
width: 16px;
height: 16px;
display: inline-block;
margin: 0 3px 0 0;
position: relative;
top: 3px;
}
.#{$prefix}tab-disabled .#{$prefix}tabicon {
opacity: 0.5;
}
.#{$prefix}tab-disabled span {
color: #aaa;
}
.#{$prefix}tabitems {
z-index: 2;
border: 1px solid $tab-border-color;
......@@ -327,6 +224,110 @@
}
}
.#{$prefix}tabbar {
text-align: left;
list-style: none;
margin: 0;
padding: 0 10px;
line-height: 24px;
position: relative;
min-height: 24px;
background: linear-gradient(lighten($panel-header-base-color,20%), $panel-header-base-color);
overflow: hidden;
li {
margin: 0;
padding: 0 10px;
border: 1px solid $tab-border-color;
background: darken($tab-base-color, 5%);
display: inline-block;
position: relative;
z-index: 0;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
li a {
color: $tab-text-color;
text-decoration: none;
}
li:before,
li:after {
position: absolute;
bottom: -1px;
width: 5px;
height: 5px;
content: " ";
border: 1px solid $tab-border-color;
}
li:before {
left: -6px;
border-bottom-right-radius: 5px;
border-width: 0 1px 1px 0;
box-shadow: 2px 2px 0 darken($tab-base-color,5%);
}
li:after {
right: -6px;
border-bottom-left-radius: 5px;
border-width: 0 0 1px 1px;
box-shadow: -2px 2px 0 darken($tab-base-color,5%);
}
li.#{$prefix}selected {
background: $tab-base-color;
color: $tab-text-color;
z-index: 2;
border-bottom-color: $tab-base-color;
}
li.#{$prefix}selected:before {
box-shadow: 2px 2px 0 $tab-base-color;
}
li.#{$prefix}selected:after {
box-shadow: -2px 2px 0 $tab-base-color;
}
li a.#{$prefix}tabclose {
color: #aaa;
display: inline-block;
position: relative;
top: -5px;
left: 7px;
font-weight: bold;
font-size: 8px;
line-height: 8px;
background: #eee;
border: 1px solid #ccc;
border-radius: 2px;
padding: 0 2px;
}
}
.#{$prefix}tabbar:after {
position: absolute;
content: "";
width: 100%;
bottom: 0;
left: 0;
border-bottom: 1px solid $tab-border-color;
z-index: 1;
}
.#{$prefix}tabbar:before {
z-index: 1;
}
.#{$prefix}tabicon {
width: 16px;
height: 16px;
display: inline-block;
margin: 0 3px 0 0;
position: relative;
top: 3px;
}
.#{$prefix}tab-disabled .#{$prefix}tabicon {
opacity: 0.5;
}
.#{$prefix}tab-disabled span {
color: #aaa;
}
.#{$prefix}toolbar, .#{$prefix}buttonbar {
align-self: stretch;
flex: 0;
......
......@@ -429,3 +429,54 @@ itasks.Tree = Object.assign({
me.select(me.attributes.value, false);
}
},itasks.Selector);
itasks.TabBar = Object.assign({
domTag: 'ul',
cssCls: 'tabbar',
attributes: {
height: 'wrap',
width: 'flex',
multiple: false
},
initDOMEl: function() {
var me = this;
me.setOptions(me.attributes.options);
me.select(me.attributes.value, false);
},
selectInDOM(el,selected) {
el.classList[selected ? 'add':'remove'](this.cssPrefix + 'selected');
},
setOptions: function(options) {
var me = this, el = me.domEl;
//Store options
me.attributes.options = options;
//Clear
while (el.lastChild) {
el.removeChild(el.lastChild);
}
options.forEach(function(option) {
optionEl = document.createElement('li');
optionEl.value = option.id;
label = document.createElement('a');
label.innerHTML = '<span>'+ (option.text || '-')+'</span>';
label.href = '#';
label.addEventListener('click',function(e) {
me.select([option.id], false);
me.doEditEvent(me.attributes.taskId,me.attributes.editorId,me.attributes.value);
e.preventDefault();
},me);
optionEl.appendChild(label);
if(me.attributes.value.includes(option.id)) {
me.selectInDOM(optionEl, true);
}
option.domEl = optionEl;
el.appendChild(optionEl);
},me);
}
},itasks.Selector);
......@@ -38,6 +38,7 @@ from Data.Functor import class Functor
| SelectInList (c -> [ChoiceText]) (c [Int] -> [s])
| SelectInGrid (c -> ChoiceGrid) (c [Int] -> [s])
| SelectInTree (c -> [ChoiceNode]) (c [Int] -> [s])
| SelectInTabs (c -> [ChoiceText]) (c [Int] -> [s])
| E.v: SelectUsing (c -> v) (c [Int] -> [s]) (Editor (v, [Int])) & iTask v
//Common attributes as option
| SelectMultiple !Bool
......@@ -48,6 +49,7 @@ from Data.Functor import class Functor
| E.v: ChooseFromCheckGroup (o -> v) & iTask v
| E.v: ChooseFromList (o -> v) & iTask v
| E.v: ChooseFromGrid (o -> v) & iTask v
| E.v: ChooseFromTabs (o -> v) & iTask v
/*** General input/update/output tasks ***/
......
......@@ -65,6 +65,7 @@ selectEditor [SelectInCheckGroup toView fromView:_] = SelectUsing toView fromVie
selectEditor [SelectInList toView fromView:_] = SelectUsing toView fromView choiceList
selectEditor [SelectInGrid toView fromView:_] = SelectUsing toView fromView grid
selectEditor [SelectInTree toView fromView:_] = SelectUsing toView fromView tree
selectEditor [SelectInTabs toView fromView:_] = SelectUsing toView fromView tabBar
selectEditor [_:es] = selectEditor es
selectEditor [] = SelectUsing (const []) (\_ _ -> []) dropdown //Empty dropdown
......@@ -77,6 +78,7 @@ where
selectOptions` _ [ChooseFromCheckGroup f:os] = [SelectInCheckGroup (toTexts f) (findSelection target):selectOptions` True os]
selectOptions` _ [ChooseFromList f:os] = [SelectInList (toTexts f) (findSelection target):selectOptions` True os]
selectOptions` _ [ChooseFromGrid f:os] = [SelectInGrid (toGrid f) (findSelection target):selectOptions` True os]
selectOptions` _ [ChooseFromTabs f:os] = [SelectInTabs (toTexts f) (findSelection target):selectOptions` True os]
selectOptions` True [] = []
selectOptions` False [] = [SelectInDropdown (toTexts id) (findSelection target)]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment