1import mwCore from "/js/mw-core/mw-core.js"; 2import mwUtility from "/js/mw-core/mw-utility.js"; 3import "/js/mw-core/mw-core-icon.js"; 4 5class mwCoreTable extends mwCore { 6 // livecycle methods 7 8 beforeFirstRender() { 9 let template; 10 11 // render data 12 13 try { 14 template = this.querySelector(`template[is="component-data"]`); 15 16 this._data = JSON.parse(template.content.textContent); 17 18 // remove template from DOM 19 20 template.remove(); 21 } catch (error) { 22 console.error(error); 23 return; 24 } 25 26 // media query 27 28 this._mq = this.breakpoint ? parseInt(this.breakpoint) : 767; 29 30 let instance = this; 31 mwUtility.mediaQuery(this._mq, { 32 yep: function () { 33 instance.display = "mobile"; 34 }, 35 nope: function () { 36 instance.display = "desktop"; 37 } 38 }); 39 40 // load swiper async if necessary 41 42 if (this.variant === "slider") { 43 import("/js/mw-core/swiper.js").then((_) => { 44 // load css 45 46 let styles = document.createElement("link"); 47 styles.setAttribute("href", "/css/swiper.css"); 48 styles.setAttribute("rel", "stylesheet"); 49 50 this.shadowRoot.appendChild(styles); 51 52 // set swiper flag 53 54 this._swiperLoaded = true; 55 this._swiperInit = false; 56 57 // rerender layout 58 59 this.reRender(); 60 }); 61 } 62 } 63 64 updated() { 65 // init swiper if swiper async loaded 66 67 if (this.variant === "slider" && this._swiperLoaded && !this._swiperInit) { 68 let breakpoints = { 69 0: { 70 slidesPerView: 2 71 }, 72 650: { 73 slidesPerView: 3 74 }, 75 980: { 76 slidesPerView: 4 77 } 78 }; 79 80 if (this.sliderbreakpoints) { 81 // get custom breakpoints (attribute or property) 82 // format px:slidesPerView 83 // example: 768:4 84 85 let customBreakpoints = this.sliderbreakpoints.split("|"); 86 87 breakpoints = {}; 88 89 for (let breakpoint of customBreakpoints) { 90 breakpoints[breakpoint.split(":")[0]] = { 91 slidesPerView: breakpoint.split(":")[1] 92 }; 93 } 94 } 95 96 this._swiperInstance = new Swiper( 97 this.shadowRoot.querySelector(".swiper-container"), 98 { 99 pagination: { 100 el: this.shadowRoot.querySelector(".swiper-pagination"), 101 clickable: true 102 }, 103 navigation: { 104 nextEl: this.shadowRoot.querySelector(".swiper-button-next"), 105 prevEl: this.shadowRoot.querySelector(".swiper-button-prev") 106 }, 107 breakpoints: breakpoints 108 } 109 ); 110 } 111 112 // cache DOM 113 114 this.cacheDOM(); 115 116 // register eventListener 117 118 this.registerEventListener(); 119 } 120 121 static get observedAttributes() { 122 return [ 123 "variant", 124 "display", 125 "breakpoint", 126 "sliderbreakpoints", 127 "fixfirstcolumn", 128 "reverse", 129 "hidefirstcolumninfirstrow" 130 ]; 131 } 132 133 // css 134 135 styles() { 136 return [ 137 `<link href="/css/styleguide.css" rel="stylesheet">`, 138 ` 139 *:focus-visible { 140 outline: 2px solid black !important; 141 outline-offset: -2px !important; 142 transition: none !important; 143 } 144 145 /*** Variant Default - Mobile ***/ 146 147 :host([display="mobile"]) .table-default .entry { 148 margin: 0 0 6px; 149 } 150 :host([display="mobile"]) .table-default .entry .row { 151 display: flex; 152 } 153 :host([display="mobile"]) .table-default .entry .row .column:nth-child(1) { 154 background: var(--mw-core-color-background-bright); 155 flex: 2; 156 overflow: hidden; 157 padding: 10px; 158 text-overflow: ellipsis; 159 } 160 :host([display="mobile"]) .table-default .entry .row .column:nth-child(2) { 161 flex: 3; 162 padding: 10px; 163 } 164 165 /*** Variant Default - Desktop ***/ 166 167 :host([display="desktop"]) .table-default .row { 168 border-bottom: 1px solid var(--mw-core-color-background-bright); 169 display: flex; 170 } 171 :host([display="desktop"]) .table-default .row:nth-child(1) { 172 border-color: transparent; 173 } 174 :host([display="desktop"]) .table-default .row .column { 175 flex: 1; 176 overflow: hidden; 177 padding: 10px; 178 text-overflow: ellipsis; 179 } 180 :host([display="desktop"]) .table-default .row:nth-child(1) .column { 181 background: var(--mw-core-color-background-bright); 182 } 183 :host([display="desktop"]) .table-default .row:hover .column { 184 background: var(--mw-core-color-background-bright); 185 } 186 187 /*** Variant Slider ***/ 188 189 :host([variant="slider"]) * { 190 user-select: none; 191 } 192 :host([variant="slider"]) .root { 193 padding: 0 0 60px; 194 } 195 .table-slider { 196 position: relative; 197 } 198 .table-slider .row {
199 align-items: center; 200 border-bottom: 1px solid var(--mw-core-color-background-bright); 201 display: block; 202 line-height: 50px; 203 overflow: hidden; 204 padding: 0 10px; 205 text-overflow: ellipsis; 206 white-space: nowrap; 207 } 208 .table-slider .column .row:nth-child(1) { 209 background: var(--mw-core-color-background-bright); 210 border-color: transparent; 211 } 212 213 /*** Swiper ***/ 214 215 .table-slider .swiper-pagination { 216 align-items: center; 217 bottom: -60px; 218 display: flex; 219 height: 40px; 220 justify-content: center; 221 left: 60px; 222 right: 60px; 223 } 224 .table-slider .swiper-pagination-bullet { 225 display: block; 226 flex: 0 0 10px; 227 height: 10px; 228 margin: 0 5px; 229 outline: none; 230 } 231 .table-slider .swiper-pagination-bullet-active { 232 background: var(--mw-core-color-action-primary); 233 } 234 .table-slider .swiper-button-prev { 235 bottom: -60px; 236 color: var(--mw-core-color-action-primary); 237 height: 40px; 238 left: 0; 239 outline: none; 240 top: auto; 241 user-select: none; 242 width: 40px; 243 } 244 .table-slider .swiper-button-prev:after { 245 content: ""; 246 } 247 .table-slider .swiper-button-next { 248 bottom: -60px; 249 color: var(--mw-core-color-action-primary); 250 height: 40px; 251 outline: none; 252 right: 0; 253 top: auto; 254 user-select: none; 255 width: 40px; 256 } 257 .table-slider .swiper-button-next:after { 258 content: ""; 259 } 260 261 /*** Variant Slider with fixfirstcolumn ***/ 262 263 :host([fixfirstcolumn]) .table-slider .table-content { 264 display: flex; 265 } 266 :host([fixfirstcolumn]) .table-slider .table-content .fixedColumn { 267 flex: 0 0 180px; 268 } 269 :host([fixfirstcolumn]) .table-slider .table-content .swiper-container { 270 flex: 1; 271 } 272 :host([fixfirstcolumn][hidefirstcolumninfirstrow]) .table-slider .table-content .fixedColumn .row:first-child { 273 visibility: hidden; 274 } 275 276 @media all and (min-width: 500px) { 277 278 :host([fixfirstcolumn]) .table-slider .table-content .column { 279 border-right: 1px solid var(--mw-core-color-background-bright); 280 } 281 :host([fixfirstcolumn]) .table-slider .table-content .fixedColumn { 282 flex: 0 0 280px; 283 width: 280px; 284 } 285 :host([fixfirstcolumn]) .table-slider .row { 286 border: 0; 287 border-top: 1px solid var(--mw-core-color-background-bright); 288 } 289 :host([fixfirstcolumn]) .table-slider .column .row:nth-child(1) { 290 background: none; 291 } 292 :host([fixfirstcolumn]) .table-slider .row:last-child { 293 border-bottom: 1px solid var(--mw-core-color-background-bright); 294 } 295 :host([fixfirstcolumn]) .table-slider .swiper-slide.column .row { 296 justify-content: center; 297 } 298 :host([fixfirstcolumn]) .table-slider .table-content .fixedColumn .row { 299 border-left: 1px solid var(--mw-core-color-background-bright); 300 margin-right: 40px; 301 } 302 :host([fixfirstcolumn]) .table-slider .table-content .fixedColumn .row:first-child { 303 margin-right: 0; 304 } 305 :host([fixfirstcolumn]) .table-slider .table-content .swiper-container { 306 margin: 0 40px 0 0; 307 } 308 :host([fixfirstcolumn]) .table-slider .swiper-button-prev { 309 background: var(--mw-core-color-action-primary); 310 border-radius: 0; 311 bottom: 0; 312 color: #FFFFFF; 313 height: auto; 314 left: 240px; 315 top: 50px; 316 } 317 :host([fixfirstcolumn]) .table-slider .swiper-button-next { 318 background: var(--mw-core-color-action-primary); 319 border-radius: 0; 320 bottom: 0; 321 color: #FFFFFF; 322 height: auto; 323 top: 50px; 324 } 325 326 } 327 328 ` 329 ]; 330 } 331 332 // render template 333 334 render() { 335 // check data 336 337 if (!this._data) { 338 console.error("no valid data"); 339 return ""; 340 } 341 342 let content = ``; 343 344 // check if data is array 345 // and if array length > 0 346 347 if (!Array.isArray(this._data)) { 348 console.error("table data not an array"); 349 return; 350 } else if (this._data.length === 0) { 351 console.error("table data empty"); 352 return; 353 } 354 355 // switch table layout 356 357 switch (this.variant) { 358 case "default": 359 case null: 360 // default layout 361 362 if (this.display === "mobile") { 363 content = this.renderDefaultMobileTable(); 364 } else { 365 content = this.renderDefaultDesktopTable(); 366 } 367 368 break; 369 370 case "slider": 371 // slider layout 372 373 content = this.renderSliderTable(); 374 375 break; 376 } 377 378 return `${content}`; 379 } 380 381 // getter and setter 382 383 get variant() { 384 return this._getAttribute("variant"); 385 } 386 387 set variant(val) { 388 this._setAttribute("variant", val); 389 } 390 391 get display() { 392 return this._getAttribute("display"); 393 } 394 395 set display(val) { 396 this._setAttribute("display", val); 397 } 398 399 get breakpoint() { 400 return this._getAttribute("breakpoint"); 401 } 402 403 set breakpoint(val) { 404 this._setAttribute("breakpoint", val); 405 } 406 407 get fixfirstcolumn() { 408 return this._getAttribute("fixfirstcolumn"); 409 } 410 411 set fixfirstcolumn(val) { 412 this._setAttribute("fixfirstcolumn", val); 413 } 414 415 get reverse() { 416 return this._getAttribute("reverse"); 417 } 418 419 set reverse(val) { 420 this._setAttribute("reverse", val); 421 } 422 423 get sliderbreakpoints() { 424 return this._getAttribute("sliderbreakpoints"); 425 } 426 427 set sliderbreakpoints(val) { 428 this._setAttribute("sliderbreakpoints", val); 429 } 430 431 get hidefirstcolumninfirstrow() { 432 return this._getAttribute("hidefirstcolumninfirstrow"); 433 } 434 435 set hidefirstcolumninfirstrow(val) { 436 this._setAttribute("hidefirstcolumninfirstrow", val); 437 } 438 439 // custom methods 440 441 cacheDOM() { 442 // cache dom elements for faster access 443 444 this._dom = {}; 445 } 446 447 registerEventListener() {} 448 449 renderDefaultMobileTable() { 450 // render default mobile table 451 452 let content = ``; 453 454 if (this._data.length <= 1) { 455 console.error("table data missing rows"); 456 return ""; 457 } 458 459 for (let i = 1; i < this._data.length; i++) { 460 content += `<div class="entry">`; 461 462 for (let j = 0; j < this._data[i].columns.length; j++) { 463 let currentData = this._data[i].columns[j].text; 464 465 content += `<div class="row"> 466 <div class="column normal-text-bold">${this._data[0].columns[j].text}</div> 467 <div class="column normal-text">${currentData}</div> 468 </div>`; 469 } 470 471 content += `</div>`; 472 } 473 474 return `<div class="table-default">${content}</div>`; 475 } 476 477 renderDefaultDesktopTable() { 478 // render default mobile table 479 480 let content = ``; 481 482 if (this._data.length <= 1) { 483 console.error("table data missing rows"); 484 return ""; 485 } 486 487 if (!this.reverse) { 488 for (let i = 0; i < this._data.length; i++) { 489 content += `<div class="row">`; 490 491 for (let j = 0; j < this._data[i].columns.length; j++) {
492 let currentData = this._data[i].columns[j].text; 493 let align = this._data[i].columns[j].align; 494 495 content += `<div class="column ${ 496 i === 0 ? `normal-text-bold` : `normal-text` 497 }" style="text-align: ${align}">${currentData}</div>`; 498 } 499 500 content += `</div>`; 501 } 502 } else { 503 for (let j = 0; j < this._data[0].columns.length; j++) { 504 content += `<div class="row">`; 505 506 for (let i = 0; i < this._data.length; i++) { 507 let currentData = this._data[i].columns[j].text; 508 let align = this._data[i].columns[j].align; 509 510 content += `<div class="column ${ 511 i === 0 ? `normal-text-bold` : `normal-text` 512 }" style="text-align: ${align}">${currentData}</div>`; 513 } 514 515 content += `</div>`; 516 } 517 } 518 519 return `<div class="table-default">${content}</div>`; 520 } 521 522 renderSliderTable() { 523 // render slider table 524 525 let content = ``; 526 let firstColumn = ``; 527 528 if (this._data.length < 1) { 529 console.error("table data missing rows"); 530 return ""; 531 } 532 533 if (!this.reverse) { 534 for (let j = 0; j < this._data[0].columns.length; j++) { 535 // detect firstColumn 536 // if fixfirstcolumn is true 537 538 if (j === 0 && this.fixfirstcolumn) { 539 firstColumn += `<div class="fixedColumn column">`; 540 } else { 541 content += `<div class="column swiper-slide">`; 542 } 543 544 for (let i = 0; i < this._data.length; i++) { 545 if (j === 0 && this.fixfirstcolumn) { 546 firstColumn += `<div class="row ${ 547 i === 0 ? `normal-text-bold` : `normal-text` 548 }" style="text-align: ${this._data[i].columns[j].align}"> 549 ${this._data[i].columns[j].text} 550 </div>`; 551 } else { 552 content += `<div class="row ${ 553 i === 0 ? `normal-text-bold` : `normal-text` 554 }" style="text-align: ${this._data[i].columns[j].align}"> 555 ${this._data[i].columns[j].text} 556 </div>`; 557 } 558 } 559 560 if (j === 0 && this.fixfirstcolumn) { 561 firstColumn += `</div>`; 562 } else { 563 content += `</div>`; 564 } 565 } 566 } else { 567 for (let i = 0; i < this._data.length; i++) { 568 if (i === 0 && this.fixfirstcolumn) { 569 firstColumn += `<div class="fixedColumn column">`; 570 } else { 571 content += `<div class="column swiper-slide">`; 572 } 573 574 for (let j = 0; j < this._data[i].columns.length; j++) { 575 if (i === 0 && this.fixfirstcolumn) { 576 firstColumn += `<div class="row ${ 577 j === 0 ? `normal-text-bold` : `normal-text` 578 }"> 579 ${this._data[i].columns[j]} 580 </div>`; 581 } else { 582 content += `<div class="row ${ 583 j === 0 ? `normal-text-bold` : `normal-text` 584 }"> 585 ${this._data[i].columns[j]} 586 </div>`; 587 } 588 } 589 590 if (i === 0 && this.fixfirstcolumn) { 591 firstColumn += `</div>`; 592 } else { 593 content += `</div>`; 594 } 595 } 596 } 597 598 return ` 599 <div class="table-slider"> 600 <div class="table-content"> 601 ${firstColumn} 602 <div class="swiper-container"> 603 <div class="swiper-wrapper"> 604 ${content} 605 </div> 606 </div> 607 </div> 608 <div class="swiper-pagination"></div> 609 <div class="swiper-button-prev effect-border-radius"> 610 <mw-core-icon size="m" name="chevronleft"></mw-core-icon> 611 </div> 612 <div class="swiper-button-next effect-border-radius"> 613 <mw-core-icon size="m" name="chevronright"></mw-core-icon> 614 </div> 615 </div> 616 `; 617 } 618} 619 620customElements.define("mw-core-table", mwCoreTable);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.