A simple OffCanvas webComponent
Tags: webcomponents, customelements, javascript, webreflections
Published: 2021-05-03 21:20:04

There are dozens libraries to create custom elements. 
For this demo, I have choosen  [uce](https://github.com/WebReflection/uce).

If you have any questions or suggestions, feel free to comment.

Here, I have defined two custom elements:
 - my-sidebar
 - my-link

Here is how they ared used in an html page :

```html
<div class="topbar">
  <my-sidebar>
    <my-link label='Google' target="https://www.google.com"></my-link>
  </my-sidebar>
  <div style="text-align:center">
    Custom side bar with uce
  </div>
  <div>
    About
  </div>
</div>
```
The JS part :

```js

const {html, define, render} = uce

 define("my-sidebar", {
    init() {
      this.width = this.getAttribute("width") || 250
      this.links = Array
        .from(this.querySelectorAll("my-link"))
        .map(l => ({
          label: l.getAttribute("label"),
          target: l.getAttribute("target")
        }))
      this.render()
    },
    render() {
      this.html`
        <div id="mySidenav" class="sidenav">
          <a class=${`closebtn `} onclick=${()=> this.closeNav()}>X</a>
          <div style='border-bottom:1px solid grey;position:relative;top:-11px'></div>
          ${this.links.map(l => html`<a href="${l.target}">${l.label}</a>`)}
        </div>
        <span style="font-size:30px;cursor:pointer" onclick=${()=> this.openNav()}>&#9776</span>
      `
    },
    openNav() {
      (mySidenav).style.width = "250px"
    },
    closeNav() {
      (mySidenav).style.width = "0px"
    }
  })

  define("my-link", {})

```
You can test it here : [UceOffCanvas](https://flems.io/#0=N4IgtglgJlA2CmIBcA2FA6FBOANCAZhAgM7IDaoAdgIZiJIjoAWALmLCHgMYD2lL8fshAAeKBABuAAi6xqxYgF4AOiBY8ADgCNqAJ1UA+ZZSlSRYAJ4BaYtHg7dRk6bOWrsCJQDWUuVviwigDkAOI8PADmCEFSLHoR8CwqIKwsGsRIAPSZAO556BHhUfDovGCGIpluHt5OppVutlD2enVm4tLELBYIyQIAHixW1B4RlEhcggL6IG2mAMIArl08YFJN8FIOUjkQLExSi5PG9ZkdbWKSc1IAglo8iywnZmdXxpXnxl-OnCDEAfAuCwIHxSAwAIwABlQVmhkJAAF8cFRaPRGAArUjcPgCIQMXiULpSYCsdg4KTNQiUeDk3SCZq6BFSRSHY6UE6UzzwAAUqkadgcqnJwGepk8e25AEpiaKXPsIMR0LsoPtmbEmAqCokbiwWLoIFpHjzVMr9qppQAfC1SABMAFZIbLTPLFTUvMQ1TddLpqBYnS50PhdKtuS70ABHRbwXQWADKAKBPF0N1gsF54GsbvNkv9pnQYGoGm5sGZBik3JFzhc1d81H8sCQvi1LB1eoNRvTfgC5pwubl8USjdgzdb+sNAnTcV0CSeIBzVZrCMl85r6s1dMoDKlsqRso3W+lldXYdJsAABn3LtJoMlLLG7DQJKoZHIFMkNo-DH36tQX-IlAAJMAZ6yDw-xaCwJhnkyfCyBAXBeIoQFSooZZhqB-wAHLUBIUoIgYAAalTUNcq5Xus3S9EE9y6AyVj3LqqxIOCGj9OsPAeFAUgRHSFgANwaGBewguMdJyMCEjwHx6gaEgVjgix-RBAYHxvAuq5AWGbqKgWRYlqhUinmeIi-kwdL4MkQHDlOM4IoYVnoF2sAIsRBhnpKdnqS4qkSKR3nEBo1AmF0PTwMk+A4jYEAAF7wEgADMkKsXxXCLLoxBJkggmeNMz6wR4CFIcAKFoRqiqaII2G4R5BgAGQAMRYAA7E1KCVAFQV+ReC67guFWUFVUoyl53J3g+OGSugIUIEq0Cqiyqj2kl-SqDuvYLhh8CDYe-qjXG40SJN00lKaBwLSAy2rT1zxLt8pictS6bVJ4XhCsSS6-P8CBAiJYIgPF4JIDa8Wwkg8JIiidDCKUCi-ASuIsMI9xQBYw2mAW06eI2kJ8cYnnGOgMnbEeWzUAhPEPJujZaHICG484vCwJlOQagI9P3QqGhyBYjb4Ag-Ts1I6LLMC+DWPDUyNh1kz0YkOTwIIgsjBAYxWHs8BgBkkz8NGguBTAngREgdrJXj3xTQdaOGfAKusI2UKQgApILp3Y6bziCbYwJ8LzED9PAUCC9FaubvA-T24LMnY4LCD4CwbsC88Ojk8GiyblYjOZVI9UKeCgs8JJuh8zwORWOHhnQM0lCRz6hLCT7UiQug8XxXaxB69QBuUBEVhR1IKDLYLNF0fqER21IinsZx3G8fT+OUBbVc4VIv4k-r4jd42AAcrFSDvbH71I8U2u7zph0MzS8D63vjFIlB8FJzwRfwUWxY29qnzIHFZ-VW-gn-f9BbiACtzamTM6bPD1EFL2IlsbN3iu3M27IF4fmXtQJATAC7RitpnXQQ5bYsB4grauSCCaoOkKUJm4FIJW09vXW+dYMqwCNJHTQ79P6j3HuCAALJ-Z+QxbBv1tCfROzgMYRE8O4eAcdGwOk-qldKWdso610HPc25CpCULAvYSCGCsG6GJFIZ4uDGx0kDqQygAABOg4hfzEC4HSQQK9NzlgLP0KwTAbZj3jlIbhcj+g7WcIvQQy8SamHXobXubCJ4m1EaYTyeYNGr1lPw1+cUJ770Fp5Tyn0Ew3z+tw7hzE7SIgALp4G0uQSGaIjiIDwGlDgDBUjpCyJkNOGgvARFKKsNpkxLHgnQOCDANoqieHQJiX43QNBonsfqDQiMESlIREAA)