1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { BaseElement, element } from '../BaseElement'; 17import './LitMainMenuItem'; 18import './LitMainMenuGroup'; 19import { LitMainMenuGroup } from './LitMainMenuGroup'; 20import { LitMainMenuItem } from './LitMainMenuItem'; 21 22const initHtmlStyle:string = ` 23 <style> 24 :host{ 25 width: 248px; 26 height: 100vh; 27 display: flex; 28 flex-direction: column; 29 background-color: #fff; 30 } 31 .menu-body ::-webkit-scrollbar-thumb 32 { 33 background-color: var(--dark-background,#FFFFFF); 34 border-radius:10px; 35 36 } 37 .menu-body ::-webkit-scrollbar-track 38 { 39 border-radius:10px; 40 background-color:#F5F5F5; 41 42 } 43 .header{ 44 display: grid; 45 width: 100%; 46 height: 56px; 47 font-size: 1.4rem; 48 padding-left: 20px; 49 gap: 0 20px; 50 box-sizing: border-box; 51 grid-template-columns: min-content 1fr min-content; 52 grid-template-rows: auto; 53 color: #47A7E0; 54 background-color: var(--dark-background1); 55 border-bottom: 1px solid var(--dark-background1,#EFEFEF); 56 } 57 .bottom{ 58 width: 100%; 59 display: flex; 60 justify-content: space-between; 61 } 62 .header *{ 63 user-select: none; 64 align-self: center; 65 } 66 .version{ 67 width: 15rem; 68 padding: 20px 0; 69 text-align: center; 70 color: #94979d; 71 font-size: 0.6rem; 72 } 73 .color, .customColor{ 74 cursor: pointer; 75 font-size: 0.6rem; 76 padding: 20px 0px 20px 20px; 77 } 78 *{ 79 box-sizing: border-box; 80 } 81 .menu-button{ 82 display: flex; 83 align-content: center; 84 justify-content: right; 85 cursor: pointer; 86 height: 47px; 87 width: 48px; 88 } 89 </style> 90 `; 91 92@element('lit-main-menu') 93export class LitMainMenu extends BaseElement { 94 private slotElements: Element[] | undefined; 95 private _menus: Array<MenuGroup> | undefined; 96 97 static get observedAttributes() { 98 return []; 99 } 100 101 get menus(): Array<MenuGroup> | undefined { 102 return this._menus; 103 } 104 105 set menus(value: Array<MenuGroup> | undefined) { 106 this._menus = value; 107 this.shadowRoot?.querySelectorAll('lit-main-menu-group').forEach((a) => a.remove()); 108 let menuBody = this.shadowRoot?.querySelector('.menu-body'); 109 if (this.getAttribute('main_menu') === '1' && window.localStorage.getItem('Theme') == 'dark') { 110 this.style.backgroundColor = '#262f3c'; 111 } else { 112 this.style.backgroundColor = '#fff'; 113 } 114 value?.forEach((it) => { 115 let group: LitMainMenuGroup = new LitMainMenuGroup(); 116 group.setAttribute('title', it.title || ''); 117 if (it.describe !== '') { 118 group.setAttribute('describe', it.describe || ''); 119 } else { 120 group.removeAttribute('describe'); 121 } 122 group.setAttribute('icon', it.icon || ''); 123 if (it.collapsed) { 124 group.setAttribute('collapsed', ''); 125 } else { 126 group.removeAttribute('collapsed'); 127 } 128 let groupName: LitMainMenuGroup = group!.shadowRoot!.querySelector('.group-name') as LitMainMenuGroup; 129 let groupDescribe: LitMainMenuGroup = group!.shadowRoot!.querySelector('.group-describe') as LitMainMenuGroup; 130 menuBody?.appendChild(group); 131 it.children?.forEach((item: any) => { 132 if (item.children && item.children.length > 0) { 133 let secondGroup: LitMainMenuGroup = new LitMainMenuGroup(); 134 secondGroup.setAttribute('title', item.title || ''); 135 if (item.describe !== '') { 136 secondGroup.setAttribute('describe', item.describe || ''); 137 } else { 138 secondGroup.removeAttribute('describe'); 139 } 140 this.setChildren(item,group,groupName,groupDescribe,secondGroup); 141 } else { 142 this.notChildren(item,group,groupName,groupDescribe); 143 } 144 }); 145 }); 146 } 147 148 setChildren(item:any,group: LitMainMenuGroup,groupName: LitMainMenuGroup,groupDescribe: LitMainMenuGroup,secondGroup: LitMainMenuGroup):void{ 149 secondGroup.setAttribute('icon', item.icon || ''); 150 if (item.second) { 151 secondGroup.setAttribute('second', ''); 152 } else { 153 secondGroup.removeAttribute('second'); 154 } 155 if (item.collapsed) { 156 secondGroup.setAttribute('collapsed', ''); 157 } else { 158 secondGroup.removeAttribute('collapsed'); 159 } 160 group?.appendChild(secondGroup); 161 item.children?.forEach((v: any) => { 162 let th = new LitMainMenuItem(); 163 th.setAttribute('icon', v.icon || ''); 164 th.setAttribute('title', v.title || ''); 165 if (this.getAttribute('main_menu') === '1' && window.localStorage.getItem('Theme') === 'dark') { 166 groupName.style.color = 'white'; 167 groupDescribe.style.color = 'white'; 168 th!.style.color = 'white'; 169 } else { 170 groupName.style.color = 'black'; 171 groupDescribe.style.color = 'black'; 172 th!.style.color = 'black'; 173 } 174 if (v.fileChoose) { 175 th.setAttribute('file', ''); 176 th.addEventListener('file-change', (e) => { 177 if (v.fileHandler && !th.disabled) { 178 v.fileHandler(e); 179 } 180 }); 181 } else { 182 th.removeAttribute('file'); 183 th.addEventListener('click', (e) => { 184 if (v.clickHandler && !th.disabled) { 185 v.clickHandler(v); 186 } 187 }); 188 } 189 if (v.disabled != undefined) { 190 th.disabled = v.disabled; 191 } 192 secondGroup.appendChild(th); 193 }); 194 } 195 196 notChildren(item:any,group: LitMainMenuGroup,groupName: LitMainMenuGroup,groupDescribe: LitMainMenuGroup):void{ 197 let th = new LitMainMenuItem(); 198 th.setAttribute('icon', item.icon || ''); 199 th.setAttribute('title', item.title || ''); 200 if (this.getAttribute('main_menu') === '1' && window.localStorage.getItem('Theme') === 'dark') { 201 groupName.style.color = 'white'; 202 groupDescribe.style.color = 'white'; 203 th!.style.color = 'white'; 204 } else { 205 groupName.style.color = 'black'; 206 groupDescribe.style.color = 'black'; 207 th!.style.color = 'black'; 208 } 209 if (item.fileChoose) { 210 th.setAttribute('file', ''); 211 th.addEventListener('file-change', (e) => { 212 if (item.fileHandler && !th.disabled) { 213 item.fileHandler(e); 214 } 215 }); 216 } else { 217 th.removeAttribute('file'); 218 th.addEventListener('click', (e) => { 219 if (item.clickHandler && !th.disabled) { 220 item.clickHandler(item); 221 } 222 }); 223 } 224 if (item.disabled != undefined) { 225 th.disabled = item.disabled; 226 } 227 group?.appendChild(th); 228 } 229 230 initElements(): void { 231 let st: HTMLSlotElement | null | undefined = this.shadowRoot?.querySelector('#st'); 232 st?.addEventListener('slotchange', (e) => { 233 this.slotElements = st?.assignedElements(); 234 this.slotElements?.forEach((it) => { 235 it.querySelectorAll('lit-main-menu-item').forEach((cell) => {}); 236 }); 237 }); 238 let versionDiv: HTMLElement | null | undefined = this.shadowRoot?.querySelector<HTMLElement>('.version'); 239 versionDiv!.innerText = (window as any).version || ''; 240 } 241 242 initHtml(): string { 243 return ` 244 ${initHtmlStyle} 245 <div class="header" name="header"> 246 <img src="img/logo.png"/> 247 <div class="menu-button"> 248 <lit-icon name="menu" size="20" color="var(blue,#4D4D4D)"></lit-icon> 249 </div> 250 </div> 251 <div class="menu-body" style="overflow: auto;overflow-x:hidden;height: 100%"> 252 <slot id="st" ></slot> 253 </div> 254 <div class="bottom"> 255 <div class="customColor"> 256 <lit-icon name="bg-colors" size="20" color="grey"></lit-icon> 257 </div> 258 <div class="version" style=""> 259 </div> 260 </div>`; 261 } 262} 263 264export interface MenuGroup { 265 title: string; 266 describe: string; 267 second: boolean; 268 collapsed: boolean; 269 children: any; 270 icon: string; 271} 272 273export interface MenuItem { 274 icon: string; 275 title: string; 276 disabled?: boolean; 277 fileChoose?: boolean; 278 clickHandler?: Function; 279 fileHandler?: Function; 280} 281