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'; 17 18const initHtmlStyle: string = ` 19 <style> 20 :host{ 21 user-select: none; 22 display: flex; 23 font-family: Helvetica; 24 font-size: 14px; 25 color: #000; 26 text-align: left; 27 line-height: 20px; 28 font-weight: 400 29 background-color: #FFFFFF; 30 transition: background-color .3s; 31 } 32 :host(:not([disabled]):hover){ 33 display: flex; 34 background-color: var(--dark-background8,#6C9BFA); 35 color: #FFFFFF; 36 cursor: pointer; 37 } 38 :host([disabled]:hover){ 39 display: flex; 40 /*background-color:#3391FF;*/ 41 /*color: #FFFFFF;*/ 42 cursor:not-allowed; 43 } 44 :host([disabled]) .root{ 45 cursor:not-allowed; 46 display: flex; 47 align-items: center; 48 padding: 10px 24px; 49 width: 100%; 50 } 51 :host(:not([disabled])) .root{ 52 cursor:pointer; 53 display: flex; 54 align-items: center; 55 padding: 10px 24px; 56 width: 100%; 57 } 58 .name{ 59 padding-left: 10px; 60 cursor: pointer; 61 overflow-wrap: anywhere; 62 } 63 .icon{ 64 pointer-events: none; 65 } 66 :host(:not([file])) .name{ 67 pointer-events: none; 68 } 69 :host(:not([file])) .root{ 70 pointer-events: none; 71 } 72 :host([file]) .name{ 73 pointer-events: none; 74 } 75 :host([file]) .icon{ 76 pointer-events: none; 77 } 78 79 :host([back]) { 80 background-color: var(--dark-background8,#6C9BFA); 81 } 82 83 </style> 84 `; 85 86@element('lit-main-menu-item') 87export class LitMainMenuItem extends BaseElement { 88 private titleEl: HTMLElement | null | undefined; 89 private rootEL: HTMLElement | null | undefined; 90 private iconEl: HTMLElement | null | undefined; 91 private fileEL: HTMLInputElement | undefined | null; 92 93 static get observedAttributes(): string[] { 94 return ['title', 'icon', 'file', 'disabled']; 95 } 96 97 get title(): string { 98 return this.getAttribute('title') || ''; 99 } 100 101 set title(val: string) { 102 this.setAttribute('title', val); 103 } 104 105 get disabled(): boolean { 106 return this.hasAttribute('disabled'); 107 } 108 109 set disabled(val: boolean) { 110 if (val) { 111 this.setAttribute('disabled', val.toString()); 112 this.fileEL?.setAttribute('disabled', val.toString()); 113 } else { 114 this.removeAttribute('disabled'); 115 this.fileEL?.removeAttribute('disabled'); 116 } 117 } 118 119 get back(): boolean { 120 return this.hasAttribute('back'); 121 } 122 123 set back(isShowBack: boolean) { 124 if (isShowBack) { 125 this.setAttribute('back', ''); 126 } else { 127 this.removeAttribute('back'); 128 } 129 } 130 131 initElements(): void { 132 this.rootEL = this.shadowRoot?.querySelector('.root'); 133 this.titleEl = this.shadowRoot?.querySelector('.name'); 134 this.iconEl = this.shadowRoot?.querySelector('.icon'); 135 this.fileEL = this.shadowRoot?.querySelector('.file'); 136 } 137 138 isFile(): boolean { 139 if (this.hasAttribute('file')) { 140 if (this.fileEL) { 141 return true; 142 } 143 } 144 return false; 145 } 146 147 connectedCallback(): void { 148 if (this.hasAttribute('file')) { 149 if (this.fileEL) { 150 this.fileEL!.addEventListener('change', (event) => { 151 let files = this.fileEL!.files; 152 if (files && files.length > 0) { 153 if (this.titleEl!.textContent!.includes('long trace')) { 154 this.dispatchEvent( 155 new CustomEvent('file-change', { 156 // @ts-ignore 157 target: this, 158 // @ts-ignore 159 detail: event.target!.files, 160 }) 161 ); 162 } else { 163 this.dispatchEvent( 164 new CustomEvent('file-change', { 165 // @ts-ignore 166 target: this, 167 detail: files[0], 168 }) 169 ); 170 } 171 if (this.fileEL) { 172 this.fileEL.value = ''; 173 } 174 if (this.fileEL) { 175 this.fileEL.value = ''; 176 } 177 } 178 }); 179 } 180 this.addEventListener('click', (e) => { 181 e.stopPropagation(); 182 }); 183 } 184 } 185 186 initHtml(): string { 187 return ` 188 ${initHtmlStyle} 189 <input id="file" class="file" type="file" style="display:none;pointer-events: none" /> 190 <label class="root" for="file"> 191 <lit-icon class="icon" name="user" size="20"></lit-icon> 192 <label class="name"></label> 193 </label> 194 `; 195 } 196 197 attributeChangedCallback(name: string, oldValue: string, newValue: string): void { 198 switch (name) { 199 case 'title': 200 if (this.titleEl) { 201 this.titleEl.textContent = newValue; 202 if (newValue.includes('long trace')) { 203 this.fileEL!.setAttribute('multiple', ''); 204 this.fileEL!.setAttribute('webkitdirectory', ''); 205 this.fileEL!.setAttribute('directory', ''); 206 } else { 207 if (this.fileEL!.hasAttribute('multiple')) { 208 this.fileEL!.removeAttribute('multiple'); 209 this.fileEL!.removeAttribute('webkitdirectory'); 210 this.fileEL!.removeAttribute('directory'); 211 } 212 } 213 } 214 break; 215 case 'icon': 216 if (this.iconEl) { 217 this.iconEl.setAttribute('name', newValue); 218 } 219 break; 220 } 221 } 222} 223