diff --git a/LICENSE b/LICENSE
index c840fc5..92c1d00 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2020-2021 Esiur Foundation
+Copyright (c) 2020-2021 Esiur Foundation, Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/css/iui.css b/css/iui.css
index a5e65e1..4185647 100644
--- a/css/iui.css
+++ b/css/iui.css
@@ -2724,7 +2724,7 @@ html[dir='rtl'] .multiselect-list-remove {
height: 100%;
}
-.navbar-search
+.navbar-search, .sitebar-search
{
margin: 6px;
background-image: var(--search);
@@ -2734,13 +2734,29 @@ html[dir='rtl'] .multiselect-list-remove {
padding-left: 30px;
}
+
+.navbar-item > .navbar-menu
+{
+ transition: max-height ease-in-out 0.5s;
+ overflow: hidden;
+ max-height: 800px;
+}
+
+.navbar-item[collapsed] > .navbar-menu
+{
+ max-height: 0;
+ transition: max-height ease-in-out 0.3s;
+}
+
.navbar-container
{
overflow: auto;
visibility: hidden;
}
-.navbar-container > i-link > span > span
+
+.navbar i-link > span > span,
+.sitebar i-link > span > span
{
color: black;
background-color: #fff3d4;
@@ -2783,22 +2799,19 @@ html[dir='rtl'] .multiselect-list-remove {
visibility: visible;
}
-.navbar-container i-link
-{
- transition: height ease 0.2s;
-}
-.navbar-container i-link[data-level = '1'] {
+.navbar-container[level = '1'] > i-link {
padding-right: 20px;
font-size: 14px;
}
-.navbar-container i-link[data-level = '0'] {
+.navbar-container[level = '0'] > i-link,
+.sitebar-container[level = '0'] > i-link {
background-color: #e5e5e5;
/*border: 1px solid #cacaca;*/
}
-.navbar-container i-link[data-level = '2'] {
+.navbar-container[level = '2'] > i-link {
background-color: #d4d4d4;
padding-right: 40px;
font-size: 14px;
@@ -2806,23 +2819,17 @@ html[dir='rtl'] .multiselect-list-remove {
font-weight: bold;
}
-.navbar-container i-link[hidden] {
- /* display: none; */
- padding-top: 0;
- padding-bottom: 0;
- height: 0;
- transition: height ease 0.2s;
-}
-
-
-.navbar-container i-link[selected]
+.navbar-item[selected] > i-link, .navbar-item[selected] > i-link:hover,
+.sitebar-item[selected] > i-link, .sitebar-item[selected] > i-link:hover
{
font-weight: bold;
background:#4ebeec;
color: white;
}
-.navbar-container i-check {
+
+.navbar-container i-check
+{
width: 42px;
background-image: var(--arrow-left);
background-position: 0px 48%;
@@ -2835,6 +2842,120 @@ html[dir='rtl'] .multiselect-list-remove {
border-bottom-left-radius: 10px;
}
-.navbar-container i-check[checked='checked'] {
+.sitebar-container i-check
+{
+ width: 34px;
+ background-image: var(--arrow-left);
+ background-position: 0px 48%;
+ background-repeat: no-repeat;
+}
+
+.navbar-container i-check[checked='checked'],
+.sitebar-container i-check[checked='checked']
+{
background-image: var(--arrow-down-active);
}
+
+.sitebar {
+ display: flex;
+ height: 100%;
+}
+
+.sitebar-container{
+ display: flex;
+}
+
+.sitebar-item
+{
+ position: relative;
+}
+
+.sitebar-item > i-link
+{
+ display: flex;
+ background: #e9e9e9;
+
+}
+
+.sitebar-item > i-link:hover
+{
+ border-radius: 0;
+}
+
+.sitebar-menu
+{
+ position: absolute;
+ width: auto;
+ white-space: nowrap;
+ background: #e0e0e080;
+ display: flex;
+ flex-direction: column;
+ /* padding: 5px; */
+ border-bottom-left-radius: 10px;
+ border-bottom-right-radius: 10px;
+ box-shadow: 0px 1px 2px 0px #b5b5b5;
+ min-width: 100%;
+ /* top: calc(100% - 1px);*/
+ overflow: visible;
+}
+
+.sitebar-container > *
+{
+ text-align: center;
+}
+
+.sitebar-item > i-link
+{
+ padding: 10px;
+}
+
+/* .sitebar-item > .sitebar-menu
+{
+ display: none;
+}
+
+.sitebar-item:hover > .sitebar-menu
+{
+ display: block;
+} */
+
+
+.sitebar-item[level='0'] > .sitebar-menu
+{
+ transition: transform ease-in-out 0.2s;
+ transform: scaleY(1);
+ transform-origin: top;
+
+}
+
+
+.sitebar-item[level='0'][collapsed] > .sitebar-menu
+{
+ transition: transform ease-in-out 0.2s;
+ transform: scaleY(0);
+ transform-origin: top;
+
+}
+
+
+.sitebar-item[level='1'] > .sitebar-menu
+{
+ max-width: 800px;
+ left: -100%;
+ top: 0;
+ box-shadow: -1px 1px 1px 0px #c8c8c8;
+ border-bottom-right-radius: 0;
+
+ transition: transform ease-in-out 0.2s;
+ transform: scaleX(1);
+ transform-origin: right;
+
+}
+
+.sitebar-item[level='1'][collapsed] > .sitebar-menu
+{
+ transition: transform ease-in-out 0.2s;
+ transform: scaleX(0);
+ transform-origin: right;
+}
+
diff --git a/src/UI/Navbar.js b/src/UI/Navbar.js
index 9a7c8e7..89dda2a 100644
--- a/src/UI/Navbar.js
+++ b/src/UI/Navbar.js
@@ -8,9 +8,11 @@ export default IUI.module(class Navbar extends IUIElement
constructor()
{
super();
+
+ this._list = [];
}
- search(text) {
+ search_old(text) {
for(var i = 0; i < this._container.children.length; i++)
{
let el = this._container.children[i];
@@ -45,8 +47,45 @@ export default IUI.module(class Navbar extends IUIElement
}
}
+ search(text, within) {
+
+ let menu = within == null ? this._container : within.menu;
+
+ for(var i = 0; i < menu.children.length; i++)
+ {
+ let item = menu.children[i];
+ let link = item.link;
+ if (link.title.toLowerCase().includes(text))
+ {
+ link.text.innerHTML = link.title.replace(new RegExp(text, 'gi'), (str) => `${str}`);
+ item.style.display = "";
+
+ //if (within != null)
+ // within.removeAttribute("collapsed");
+
+ // make parents visible
+ let parent = within;
+
+ while (parent != null && parent != this)
+ {
+ parent.expand.checked = true;
+ parent.removeAttribute("collapsed");
+ parent.style.display = "";
+ parent = parent.parentElement.parentElement;
+ }
+
+ }
+ else
+ {
+ item.style.display = "none";
+ }
+
+ if (item.menu != null)
+ this.search(text, item);
+ }
+ }
- expand(link, value) {
+ expand_old(link, value) {
let next = link;// = link.nextElementSibling;
let level = parseInt(link.getAttribute("data-level"));
@@ -71,6 +110,23 @@ export default IUI.module(class Navbar extends IUIElement
}
}
+ expand(item, value) {
+ if (value)
+ item.removeAttribute("collapsed");
+ else
+ item.setAttribute("collapsed", "");
+
+ item.expand.checked = value;
+ }
+
+ get collapsed(){
+ return this.hasAttribute("collapsed");
+ }
+
+ get auto(){
+ return this.hasAttribute("auto");
+ }
+
build(){
this.innerHTML = "";
@@ -90,60 +146,92 @@ export default IUI.module(class Navbar extends IUIElement
this.appendChild(this._container);
- var appendRoutes = (routes, level) => {
+ let collapsed = this.collapsed;
+ let auto = this.auto;
+
+ const filterRoutes = (routes) =>
+ routes.filter(r => {
+ if (r.hasAttribute("private"))
+ return false;
+
+ if (this.private instanceof Function)
+ {
+ try{
+ if (this.private(r))
+ {
+ return false;
+ }
+ } catch(ex){
+ console.log(ex);
+ debugger;
+ }
+
+ return true;
+ }
+ });
+
+ const appendRoutes = (routes, level, container) => {
for (var i = 0; i < routes.length; i++) {
- if (routes[i].hasAttribute("private"))
- continue;
- if (this.private instanceof Function)
- {
- try{
- // console.log("F");
- if (this.private(routes[i]))
- {
- // console.log("private", route[i]);
- continue;
- }
- } catch(ex){
- console.log(ex);
- debugger;
- }
- }
+ let item = document.createElement("div");
+ item.className = this.cssClass + "-item";
- let el = new Link();// document.createElement("i-link");
- el.setAttribute("data-level", level);
- el.link = routes[i].link;
- el.title = routes[i].caption;
+ let link = new Link();// document.createElement("i-link");
+ item.setAttribute("level", level);
+ link.link = routes[i].link;
+ link.title = routes[i].caption;
if (routes[i].icon != null)
- el.innerHTML = "
";
+ link.innerHTML = "
";
- el.text = document.createElement("span");
- el.text.innerHTML = el.title;
- el.appendChild(el.text);
-
- this._container.appendChild(el);
+ link.text = document.createElement("span");
+ link.text.innerHTML = link.title;
+ link.appendChild(link.text);
- if (routes[i].routes.length > 0) {
+ item.link = link;
+
+ item.appendChild(link);
+ container.appendChild(item);
+
+ this._list.push(item);
+
+ let subRoutes = filterRoutes(routes[i].routes);
+
+ if (subRoutes.length > 0) {
// append plus
- el.expand = new Check({cssClass: this.cssClass + "-check"});// document.createElement("i-check");
- el.expand.checked = true;
+ item.expand = new Check({cssClass: this.cssClass + "-check"});// document.createElement("i-check");
+ item.expand.checked = this.collapsed ? false : true;
+ item.expand.checked = !collapsed;
- //plus.className = "expand";#f8f8f8
- el.expand.on("click", (e) => {
- self.expand(el, el.expand.checked);
+ if (collapsed)
+ item.setAttribute("collapsed", "");
+
+ link.appendChild(item.expand);
+
+ item.menu = document.createElement("div");
+ item.menu.className = this.cssClass + "-menu";
+ item.appendChild(item.menu);
+
+ item.expand.on("click", (e) => {
+ self.expand(item, item.expand.checked);
e.stopPropagation();
});
- el.appendChild(el.expand);
- appendRoutes(routes[i].routes, level + 1);
+
+ if (auto)
+ {
+ item.addEventListener("mouseenter", ()=> self.expand(item, true));
+ item.addEventListener("mouseleave", ()=> self.expand(item, false));
+ }
+
+ appendRoutes(subRoutes, level + 1, item.menu);
}
}
};
- appendRoutes(roots, 0);
+ appendRoutes(filterRoutes(roots), 0, this._container);
}
created() {
@@ -151,10 +239,11 @@ export default IUI.module(class Navbar extends IUIElement
window.router.on("created", this.build);
window.router.on("navigate", (e) => {
- for(var i = 0; i < this?._container?.children?.length; i++)
+
+ for(var i = 0; i < this._list.length; i++)
{
- var el = this._container.children[i];
- if (el.link == e.base)
+ var el = this._list[i];
+ if (el.link.link == e.base)
el.setAttribute("selected", "");
else
el.removeAttribute("selected");