@nyaruka/temba-components 0.35.1 → 0.35.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,8 +4,20 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### [v0.35.3](https://github.com/nyaruka/temba-components/compare/v0.35.2...v0.35.3)
8
+
9
+ - Fix offsets for temba-dropdown [`#229`](https://github.com/nyaruka/temba-components/pull/229)
10
+
11
+ #### [v0.35.2](https://github.com/nyaruka/temba-components/compare/v0.35.1...v0.35.2)
12
+
13
+ > 13 December 2022
14
+
15
+ - Relative dropdown placement, fix focus on window switching [`#227`](https://github.com/nyaruka/temba-components/pull/227)
16
+
7
17
  #### [v0.35.1](https://github.com/nyaruka/temba-components/compare/v0.35.0...v0.35.1)
8
18
 
19
+ > 9 December 2022
20
+
9
21
  - Update date formatting options [`#225`](https://github.com/nyaruka/temba-components/pull/225)
10
22
  - More date formatting options [`2975e3a`](https://github.com/nyaruka/temba-components/commit/2975e3acf28bcf2411f0b347de7ab256a49b21aa)
11
23
  - Add mock for temba-date [`d9565fe`](https://github.com/nyaruka/temba-components/commit/d9565fe319afade319927f84dd4a2df0b4d8259f)
@@ -4005,11 +4005,20 @@ function t(t,e,i,n){var o,s=arguments.length,r=s<3?e:null===n?n=Object.getOwnPro
4005
4005
  cursor: pointer;
4006
4006
  text-decoration: underline;
4007
4007
  }
4008
- `}handleClick(t){window.goto(t)}render(){return P`<slot href="${this.href}" @click="${this.handleClick}"></slot>`}}t([it({type:String})],fa.prototype,"href",void 0);class ga extends tt{constructor(){super(...arguments),this.open=!1,this.arrowSize=6,this.arrowOffset=2*this.arrowSize,this.offsetX=-10,this.offsetY=0}static get styles(){return s`
4008
+ `}handleClick(t){window.goto(t)}render(){return P`<slot href="${this.href}" @click="${this.handleClick}"></slot>`}}t([it({type:String})],fa.prototype,"href",void 0);class ga extends tt{constructor(){super(...arguments),this.open=!1,this.dropAlign="left",this.arrowSize=6,this.arrowOffset=2*this.arrowSize,this.offsetX=0,this.offsetY=0}static get styles(){return s`
4009
+ .wrapper {
4010
+ position: relative;
4011
+ }
4012
+
4009
4013
  .toggle {
4010
4014
  cursor: pointer;
4011
4015
  }
4012
4016
 
4017
+ .dropdown-wrapper {
4018
+ position: relative;
4019
+ overflow: auto;
4020
+ }
4021
+
4013
4022
  .dropdown {
4014
4023
  position: absolute;
4015
4024
  opacity: 0;
@@ -4047,15 +4056,25 @@ function t(t,e,i,n){var o,s=arguments.length,r=s<3?e:null===n?n=Object.getOwnPro
4047
4056
  pointer-events: auto;
4048
4057
  transform: translateY(0.5em);
4049
4058
  }
4050
- `}firstUpdated(t){super.firstUpdated(t);const e=this.shadowRoot.querySelector(".dropdown"),i=this.shadowRoot.querySelector(".arrow");i.style.borderWidth=this.arrowSize+"px",i.style.top="-"+this.arrowSize+"px",this.arrowOffset<0?i.style.right=Math.abs(this.arrowOffset)+"px":i.style.left=this.arrowOffset+"px",e.style.marginTop=this.offsetY+"px",e.offsetLeft+e.clientWidth>window.outerWidth?e.style.marginLeft="-"+(e.clientWidth-this.clientWidth-this.offsetX)+"px":e.style.marginLeft=this.offsetX+"px",e.addEventListener("blur",(()=>{window.setTimeout((()=>{this.open=!1}),200)}))}updated(t){super.updated(t),t.has("open")&&(this.open?this.classList.add("open"):this.classList.remove("open"))}handleOpen(){if(!this.open){this.open=!0;this.shadowRoot.querySelector(".dropdown").focus()}}render(){return P`
4051
- <div class=${this.open?"open":""}>
4052
- <slot name="toggle" class="toggle" @click="${this.handleOpen}"></slot>
4053
- <div class="dropdown" tabindex="0">
4059
+ `}firstUpdated(t){super.firstUpdated(t);const e=this.shadowRoot.querySelector(".arrow");e.style.borderWidth=this.arrowSize+"px",e.style.top="-"+this.arrowSize+"px",this.arrowOffset<0?e.style.right=Math.abs(this.arrowOffset)+"px":e.style.left=this.arrowOffset+"px";this.shadowRoot.querySelector(".dropdown").addEventListener("blur",(()=>{window.setTimeout((()=>{this.open=!1,this.shadowRoot.host.blur()}),200)}))}updated(t){if(super.updated(t),t.has("offsetY")||t.has("offsetX")){const t=this.shadowRoot.querySelector(".dropdown");t.style.marginTop=this.offsetY+"px",t.offsetLeft+t.clientWidth>window.outerWidth?t.style.marginLeft="-"+(t.clientWidth-this.clientWidth-this.offsetX)+"px":t.style.marginLeft=this.offsetX+"px"}t.has("open")&&(this.open?this.classList.add("open"):this.classList.remove("open"))}handleToggleClicked(){if(!this.open){this.open=!0;this.shadowRoot.querySelector(".dropdown").focus()}}render(){return P`
4060
+ <div class="wrapper ${this.open?"open":""}">
4061
+ <slot
4062
+ name="toggle"
4063
+ class="toggle"
4064
+ @click="${this.handleToggleClicked}"
4065
+ ></slot>
4066
+ <div
4067
+ class="dropdown"
4068
+ tabindex="0"
4069
+ style="${"right"==this.dropAlign?"right:0":""}"
4070
+ >
4054
4071
  <div class="arrow"></div>
4055
- <slot name="dropdown"></slot>
4072
+ <div class="dropdown-wrapper">
4073
+ <slot name="dropdown" tabindex="1"></slot>
4074
+ </div>
4056
4075
  </div>
4057
4076
  </div>
4058
- `}}t([it({type:Boolean})],ga.prototype,"open",void 0),t([it({type:Number})],ga.prototype,"arrowSize",void 0),t([it({type:Number})],ga.prototype,"arrowOffset",void 0),t([it({type:Number})],ga.prototype,"offsetX",void 0),t([it({type:Number})],ga.prototype,"offsetY",void 0);class va extends tt{constructor(){super(...arguments),this.collapses=!1,this.index=0}static get styles(){return s`
4077
+ `}}t([it({type:Boolean})],ga.prototype,"open",void 0),t([it({type:String,attribute:"drop_align"})],ga.prototype,"dropAlign",void 0),t([it({type:Number})],ga.prototype,"arrowSize",void 0),t([it({type:Number})],ga.prototype,"arrowOffset",void 0),t([it({type:Number})],ga.prototype,"offsetX",void 0),t([it({type:Number})],ga.prototype,"offsetY",void 0);class va extends tt{constructor(){super(...arguments),this.collapses=!1,this.index=0}static get styles(){return s`
4059
4078
  :host {
4060
4079
  display: flex;
4061
4080
  flex-direction: column;
package/dist/index.js CHANGED
@@ -4005,11 +4005,20 @@ function t(t,e,i,n){var o,s=arguments.length,r=s<3?e:null===n?n=Object.getOwnPro
4005
4005
  cursor: pointer;
4006
4006
  text-decoration: underline;
4007
4007
  }
4008
- `}handleClick(t){window.goto(t)}render(){return P`<slot href="${this.href}" @click="${this.handleClick}"></slot>`}}t([it({type:String})],fa.prototype,"href",void 0);class ga extends tt{constructor(){super(...arguments),this.open=!1,this.arrowSize=6,this.arrowOffset=2*this.arrowSize,this.offsetX=-10,this.offsetY=0}static get styles(){return s`
4008
+ `}handleClick(t){window.goto(t)}render(){return P`<slot href="${this.href}" @click="${this.handleClick}"></slot>`}}t([it({type:String})],fa.prototype,"href",void 0);class ga extends tt{constructor(){super(...arguments),this.open=!1,this.dropAlign="left",this.arrowSize=6,this.arrowOffset=2*this.arrowSize,this.offsetX=0,this.offsetY=0}static get styles(){return s`
4009
+ .wrapper {
4010
+ position: relative;
4011
+ }
4012
+
4009
4013
  .toggle {
4010
4014
  cursor: pointer;
4011
4015
  }
4012
4016
 
4017
+ .dropdown-wrapper {
4018
+ position: relative;
4019
+ overflow: auto;
4020
+ }
4021
+
4013
4022
  .dropdown {
4014
4023
  position: absolute;
4015
4024
  opacity: 0;
@@ -4047,15 +4056,25 @@ function t(t,e,i,n){var o,s=arguments.length,r=s<3?e:null===n?n=Object.getOwnPro
4047
4056
  pointer-events: auto;
4048
4057
  transform: translateY(0.5em);
4049
4058
  }
4050
- `}firstUpdated(t){super.firstUpdated(t);const e=this.shadowRoot.querySelector(".dropdown"),i=this.shadowRoot.querySelector(".arrow");i.style.borderWidth=this.arrowSize+"px",i.style.top="-"+this.arrowSize+"px",this.arrowOffset<0?i.style.right=Math.abs(this.arrowOffset)+"px":i.style.left=this.arrowOffset+"px",e.style.marginTop=this.offsetY+"px",e.offsetLeft+e.clientWidth>window.outerWidth?e.style.marginLeft="-"+(e.clientWidth-this.clientWidth-this.offsetX)+"px":e.style.marginLeft=this.offsetX+"px",e.addEventListener("blur",(()=>{window.setTimeout((()=>{this.open=!1}),200)}))}updated(t){super.updated(t),t.has("open")&&(this.open?this.classList.add("open"):this.classList.remove("open"))}handleOpen(){if(!this.open){this.open=!0;this.shadowRoot.querySelector(".dropdown").focus()}}render(){return P`
4051
- <div class=${this.open?"open":""}>
4052
- <slot name="toggle" class="toggle" @click="${this.handleOpen}"></slot>
4053
- <div class="dropdown" tabindex="0">
4059
+ `}firstUpdated(t){super.firstUpdated(t);const e=this.shadowRoot.querySelector(".arrow");e.style.borderWidth=this.arrowSize+"px",e.style.top="-"+this.arrowSize+"px",this.arrowOffset<0?e.style.right=Math.abs(this.arrowOffset)+"px":e.style.left=this.arrowOffset+"px";this.shadowRoot.querySelector(".dropdown").addEventListener("blur",(()=>{window.setTimeout((()=>{this.open=!1,this.shadowRoot.host.blur()}),200)}))}updated(t){if(super.updated(t),t.has("offsetY")||t.has("offsetX")){const t=this.shadowRoot.querySelector(".dropdown");t.style.marginTop=this.offsetY+"px",t.offsetLeft+t.clientWidth>window.outerWidth?t.style.marginLeft="-"+(t.clientWidth-this.clientWidth-this.offsetX)+"px":t.style.marginLeft=this.offsetX+"px"}t.has("open")&&(this.open?this.classList.add("open"):this.classList.remove("open"))}handleToggleClicked(){if(!this.open){this.open=!0;this.shadowRoot.querySelector(".dropdown").focus()}}render(){return P`
4060
+ <div class="wrapper ${this.open?"open":""}">
4061
+ <slot
4062
+ name="toggle"
4063
+ class="toggle"
4064
+ @click="${this.handleToggleClicked}"
4065
+ ></slot>
4066
+ <div
4067
+ class="dropdown"
4068
+ tabindex="0"
4069
+ style="${"right"==this.dropAlign?"right:0":""}"
4070
+ >
4054
4071
  <div class="arrow"></div>
4055
- <slot name="dropdown"></slot>
4072
+ <div class="dropdown-wrapper">
4073
+ <slot name="dropdown" tabindex="1"></slot>
4074
+ </div>
4056
4075
  </div>
4057
4076
  </div>
4058
- `}}t([it({type:Boolean})],ga.prototype,"open",void 0),t([it({type:Number})],ga.prototype,"arrowSize",void 0),t([it({type:Number})],ga.prototype,"arrowOffset",void 0),t([it({type:Number})],ga.prototype,"offsetX",void 0),t([it({type:Number})],ga.prototype,"offsetY",void 0);class va extends tt{constructor(){super(...arguments),this.collapses=!1,this.index=0}static get styles(){return s`
4077
+ `}}t([it({type:Boolean})],ga.prototype,"open",void 0),t([it({type:String,attribute:"drop_align"})],ga.prototype,"dropAlign",void 0),t([it({type:Number})],ga.prototype,"arrowSize",void 0),t([it({type:Number})],ga.prototype,"arrowOffset",void 0),t([it({type:Number})],ga.prototype,"offsetX",void 0),t([it({type:Number})],ga.prototype,"offsetY",void 0);class va extends tt{constructor(){super(...arguments),this.collapses=!1,this.index=0}static get styles(){return s`
4059
4078
  :host {
4060
4079
  display: flex;
4061
4080
  flex-direction: column;
package/dist/sw.js CHANGED
@@ -1,2 +1,2 @@
1
- if(!self.define){const e=e=>{"require"!==e&&(e+=".js");let r=Promise.resolve();return t[e]||(r=new Promise(async r=>{if("document"in self){const t=document.createElement("script");t.src=e,document.head.appendChild(t),t.onload=r}else importScripts(e),r()})),r.then(()=>{if(!t[e])throw new Error(`Module ${e} didn’t register its module`);return t[e]})},r=(r,t)=>{Promise.all(r.map(e)).then(e=>t(1===e.length?e[0]:e))},t={require:Promise.resolve(r)};self.define=(r,s,o)=>{t[r]||(t[r]=Promise.resolve().then(()=>{let t={};const n={uri:location.origin+r.slice(1)};return Promise.all(s.map(r=>{switch(r){case"exports":return t;case"module":return n;default:return e(r)}})).then(e=>{const r=o(...e);return t.default||(t.default=r),t})}))}}define("./sw.js",["./workbox-80efdfd1"],(function(e){"use strict";e.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"ba7fe497.js",revision:"ce58e9484ad291adc48b92f3c226e11c"},{url:"templates/components-body.html",revision:"7bc1c830091bbccb872d33a4d02622a5"},{url:"templates/components-head.html",revision:"5e62ca574f66698c7c320186d4114af6"}],{}),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"))),e.registerRoute("polyfills/*.js",new e.CacheFirst,"GET")}));
1
+ if(!self.define){const e=e=>{"require"!==e&&(e+=".js");let r=Promise.resolve();return t[e]||(r=new Promise(async r=>{if("document"in self){const t=document.createElement("script");t.src=e,document.head.appendChild(t),t.onload=r}else importScripts(e),r()})),r.then(()=>{if(!t[e])throw new Error(`Module ${e} didn’t register its module`);return t[e]})},r=(r,t)=>{Promise.all(r.map(e)).then(e=>t(1===e.length?e[0]:e))},t={require:Promise.resolve(r)};self.define=(r,s,o)=>{t[r]||(t[r]=Promise.resolve().then(()=>{let t={};const n={uri:location.origin+r.slice(1)};return Promise.all(s.map(r=>{switch(r){case"exports":return t;case"module":return n;default:return e(r)}})).then(e=>{const r=o(...e);return t.default||(t.default=r),t})}))}}define("./sw.js",["./workbox-80efdfd1"],(function(e){"use strict";e.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"445f048b.js",revision:"de488e2d5e2dd015cff6bf1aa3c452e9"},{url:"templates/components-body.html",revision:"47f708377964c222c2bff54485b969a4"},{url:"templates/components-head.html",revision:"5c283453ef64a5e252abffae26033b25"}],{}),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"))),e.registerRoute("polyfills/*.js",new e.CacheFirst,"GET")}));
2
2
  //# sourceMappingURL=sw.js.map
package/dist/sw.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sw.js","sources":["../../../../../tmp/8698df99b6974935e12a0980e3acb1e3/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-routing/registerRoute.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {skipWaiting as workbox_core_skipWaiting} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-core/skipWaiting.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nworkbox_core_skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"ba7fe497.js\",\n \"revision\": \"ce58e9484ad291adc48b92f3c226e11c\"\n },\n {\n \"url\": \"templates/components-body.html\",\n \"revision\": \"7bc1c830091bbccb872d33a4d02622a5\"\n },\n {\n \"url\": \"templates/components-head.html\",\n \"revision\": \"5e62ca574f66698c7c320186d4114af6\"\n }\n], {});\n\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"/index.html\")));\n\n\nworkbox_routing_registerRoute(\"polyfills/*.js\", new workbox_strategies_CacheFirst(), 'GET');\n\n\n\n\n"],"names":["url","revision","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","workbox_strategies_CacheFirst"],"mappings":"k1BAmCoC,CAClC,CACEA,IAAO,cACPC,SAAY,oCAEd,CACED,IAAO,iCACPC,SAAY,oCAEd,CACED,IAAO,iCACPC,SAAY,qCAEb,oBAE2B,IAAIC,kBAAgCC,0BAA2C,iCAG/E,iBAAkB,IAAIC,aAAiC"}
1
+ {"version":3,"file":"sw.js","sources":["../../../../../tmp/c139078bd7b03fda0cd1d0ca439fcfe4/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-routing/registerRoute.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {skipWaiting as workbox_core_skipWaiting} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-core/skipWaiting.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nworkbox_core_skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"445f048b.js\",\n \"revision\": \"de488e2d5e2dd015cff6bf1aa3c452e9\"\n },\n {\n \"url\": \"templates/components-body.html\",\n \"revision\": \"47f708377964c222c2bff54485b969a4\"\n },\n {\n \"url\": \"templates/components-head.html\",\n \"revision\": \"5c283453ef64a5e252abffae26033b25\"\n }\n], {});\n\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"/index.html\")));\n\n\nworkbox_routing_registerRoute(\"polyfills/*.js\", new workbox_strategies_CacheFirst(), 'GET');\n\n\n\n\n"],"names":["url","revision","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","workbox_strategies_CacheFirst"],"mappings":"k1BAmCoC,CAClC,CACEA,IAAO,cACPC,SAAY,oCAEd,CACED,IAAO,iCACPC,SAAY,oCAEd,CACED,IAAO,iCACPC,SAAY,qCAEb,oBAE2B,IAAIC,kBAAgCC,0BAA2C,iCAG/E,iBAAkB,IAAIC,aAAiC"}
@@ -1 +1 @@
1
- <script type="module" src="{{STATIC_URL}}@nyaruka/temba-components/dist/ba7fe497.js"></script><script>window.TEMBA_COMPONENTS_VERSION="0.35.1"</script>
1
+ <script type="module" src="{{STATIC_URL}}@nyaruka/temba-components/dist/445f048b.js"></script><script>window.TEMBA_COMPONENTS_VERSION="0.35.3"</script>
@@ -1 +1 @@
1
- <link rel="modulepreload" href="{{STATIC_URL}}@nyaruka/temba-components/dist/ba7fe497.js" crossorigin="anonymous">
1
+ <link rel="modulepreload" href="{{STATIC_URL}}@nyaruka/temba-components/dist/445f048b.js" crossorigin="anonymous">
@@ -6,17 +6,27 @@ export class Dropdown extends RapidElement {
6
6
  constructor() {
7
7
  super(...arguments);
8
8
  this.open = false;
9
+ this.dropAlign = 'left';
9
10
  this.arrowSize = 6;
10
11
  this.arrowOffset = this.arrowSize * 2;
11
- this.offsetX = -10;
12
+ this.offsetX = 0;
12
13
  this.offsetY = 0;
13
14
  }
14
15
  static get styles() {
15
16
  return css `
17
+ .wrapper {
18
+ position: relative;
19
+ }
20
+
16
21
  .toggle {
17
22
  cursor: pointer;
18
23
  }
19
24
 
25
+ .dropdown-wrapper {
26
+ position: relative;
27
+ overflow: auto;
28
+ }
29
+
20
30
  .dropdown {
21
31
  position: absolute;
22
32
  opacity: 0;
@@ -58,7 +68,6 @@ export class Dropdown extends RapidElement {
58
68
  }
59
69
  firstUpdated(props) {
60
70
  super.firstUpdated(props);
61
- const dropdown = this.shadowRoot.querySelector('.dropdown');
62
71
  const arrow = this.shadowRoot.querySelector('.arrow');
63
72
  arrow.style.borderWidth = this.arrowSize + 'px';
64
73
  arrow.style.top = '-' + this.arrowSize + 'px';
@@ -68,25 +77,31 @@ export class Dropdown extends RapidElement {
68
77
  else {
69
78
  arrow.style.left = this.arrowOffset + 'px';
70
79
  }
71
- dropdown.style.marginTop = this.offsetY + 'px';
72
- if (dropdown.offsetLeft + dropdown.clientWidth > window.outerWidth) {
73
- dropdown.style.marginLeft =
74
- '-' + (dropdown.clientWidth - this.clientWidth - this.offsetX) + 'px';
75
- }
76
- else {
77
- dropdown.style.marginLeft = this.offsetX + 'px';
78
- }
80
+ const dropdown = this.shadowRoot.querySelector('.dropdown');
79
81
  dropdown.addEventListener('blur', () => {
80
82
  // we nest this to deal with clicking the toggle to close
81
83
  // as we don't want it to toggle an immediate open, probably
82
84
  // a better way to deal with this
83
85
  window.setTimeout(() => {
84
86
  this.open = false;
87
+ // blur our host element too
88
+ this.shadowRoot.host.blur();
85
89
  }, 200);
86
90
  });
87
91
  }
88
92
  updated(changedProperties) {
89
93
  super.updated(changedProperties);
94
+ if (changedProperties.has('offsetY') || changedProperties.has('offsetX')) {
95
+ const dropdown = this.shadowRoot.querySelector('.dropdown');
96
+ dropdown.style.marginTop = this.offsetY + 'px';
97
+ if (dropdown.offsetLeft + dropdown.clientWidth > window.outerWidth) {
98
+ dropdown.style.marginLeft =
99
+ '-' + (dropdown.clientWidth - this.clientWidth - this.offsetX) + 'px';
100
+ }
101
+ else {
102
+ dropdown.style.marginLeft = this.offsetX + 'px';
103
+ }
104
+ }
90
105
  if (changedProperties.has('open')) {
91
106
  if (this.open) {
92
107
  this.classList.add('open');
@@ -96,7 +111,7 @@ export class Dropdown extends RapidElement {
96
111
  }
97
112
  }
98
113
  }
99
- handleOpen() {
114
+ handleToggleClicked() {
100
115
  if (!this.open) {
101
116
  this.open = true;
102
117
  const dropdown = this.shadowRoot.querySelector('.dropdown');
@@ -105,11 +120,21 @@ export class Dropdown extends RapidElement {
105
120
  }
106
121
  render() {
107
122
  return html `
108
- <div class=${this.open ? 'open' : ''}>
109
- <slot name="toggle" class="toggle" @click="${this.handleOpen}"></slot>
110
- <div class="dropdown" tabindex="0">
123
+ <div class="wrapper ${this.open ? 'open' : ''}">
124
+ <slot
125
+ name="toggle"
126
+ class="toggle"
127
+ @click="${this.handleToggleClicked}"
128
+ ></slot>
129
+ <div
130
+ class="dropdown"
131
+ tabindex="0"
132
+ style="${this.dropAlign == 'right' ? 'right:0' : ''}"
133
+ >
111
134
  <div class="arrow"></div>
112
- <slot name="dropdown"></slot>
135
+ <div class="dropdown-wrapper">
136
+ <slot name="dropdown" tabindex="1"></slot>
137
+ </div>
113
138
  </div>
114
139
  </div>
115
140
  `;
@@ -118,6 +143,9 @@ export class Dropdown extends RapidElement {
118
143
  __decorate([
119
144
  property({ type: Boolean })
120
145
  ], Dropdown.prototype, "open", void 0);
146
+ __decorate([
147
+ property({ type: String, attribute: 'drop_align' })
148
+ ], Dropdown.prototype, "dropAlign", void 0);
121
149
  __decorate([
122
150
  property({ type: Number })
123
151
  ], Dropdown.prototype, "arrowSize", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.js","sourceRoot":"","sources":["../../../src/dropdown/Dropdown.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators';\nimport { RapidElement } from '../RapidElement';\n\nexport class Dropdown extends RapidElement {\n static get styles() {\n return css`\n .toggle {\n cursor: pointer;\n }\n\n .dropdown {\n position: absolute;\n opacity: 0;\n z-index: 10;\n pointer-events: none;\n padding: 0;\n border-radius: var(--curvature);\n background: #fff;\n transform: translateY(-1em);\n transition: all calc(0.6 * var(--transition-speed)) linear;\n user-select: none;\n margin-top: 0px;\n margin-left: 0px;\n box-shadow: var(--dropdown-shadow);\n }\n\n .dropdown:focus {\n outline: none;\n }\n\n .arrow {\n content: '';\n width: 0px;\n height: 0;\n top: -6px;\n z-index: 10;\n position: absolute;\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n border-bottom: 6px solid white;\n }\n\n .open .dropdown {\n opacity: 1;\n pointer-events: auto;\n transform: translateY(0.5em);\n }\n `;\n }\n\n @property({ type: Boolean })\n open = false;\n\n @property({ type: Number })\n arrowSize = 6;\n\n @property({ type: Number })\n arrowOffset = this.arrowSize * 2;\n\n @property({ type: Number })\n offsetX = -10;\n\n @property({ type: Number })\n offsetY = 0;\n\n public firstUpdated(props: any) {\n super.firstUpdated(props);\n\n const dropdown = this.shadowRoot.querySelector(\n '.dropdown'\n ) as HTMLDivElement;\n const arrow = this.shadowRoot.querySelector('.arrow') as HTMLDivElement;\n\n arrow.style.borderWidth = this.arrowSize + 'px';\n arrow.style.top = '-' + this.arrowSize + 'px';\n\n if (this.arrowOffset < 0) {\n arrow.style.right = Math.abs(this.arrowOffset) + 'px';\n } else {\n arrow.style.left = this.arrowOffset + 'px';\n }\n\n dropdown.style.marginTop = this.offsetY + 'px';\n\n if (dropdown.offsetLeft + dropdown.clientWidth > window.outerWidth) {\n dropdown.style.marginLeft =\n '-' + (dropdown.clientWidth - this.clientWidth - this.offsetX) + 'px';\n } else {\n dropdown.style.marginLeft = this.offsetX + 'px';\n }\n\n dropdown.addEventListener('blur', () => {\n // we nest this to deal with clicking the toggle to close\n // as we don't want it to toggle an immediate open, probably\n // a better way to deal with this\n window.setTimeout(() => {\n this.open = false;\n }, 200);\n });\n }\n\n public updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties);\n if (changedProperties.has('open')) {\n if (this.open) {\n this.classList.add('open');\n } else {\n this.classList.remove('open');\n }\n }\n }\n\n public handleOpen(): void {\n if (!this.open) {\n this.open = true;\n\n const dropdown = this.shadowRoot.querySelector(\n '.dropdown'\n ) as HTMLDivElement;\n dropdown.focus();\n }\n }\n\n public render(): TemplateResult {\n return html`\n <div class=${this.open ? 'open' : ''}>\n <slot name=\"toggle\" class=\"toggle\" @click=\"${this.handleOpen}\"></slot>\n <div class=\"dropdown\" tabindex=\"0\">\n <div class=\"arrow\"></div>\n <slot name=\"dropdown\"></slot>\n </div>\n </div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"Dropdown.js","sourceRoot":"","sources":["../../../src/dropdown/Dropdown.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators';\nimport { RapidElement } from '../RapidElement';\n\nexport class Dropdown extends RapidElement {\n static get styles() {\n return css`\n .wrapper {\n position: relative;\n }\n\n .toggle {\n cursor: pointer;\n }\n\n .dropdown-wrapper {\n position: relative;\n overflow: auto;\n }\n\n .dropdown {\n position: absolute;\n opacity: 0;\n z-index: 10;\n pointer-events: none;\n padding: 0;\n border-radius: var(--curvature);\n background: #fff;\n transform: translateY(-1em);\n transition: all calc(0.6 * var(--transition-speed)) linear;\n user-select: none;\n margin-top: 0px;\n margin-left: 0px;\n box-shadow: var(--dropdown-shadow);\n }\n\n .dropdown:focus {\n outline: none;\n }\n\n .arrow {\n content: '';\n width: 0px;\n height: 0;\n top: -6px;\n z-index: 10;\n position: absolute;\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n border-bottom: 6px solid white;\n }\n\n .open .dropdown {\n opacity: 1;\n pointer-events: auto;\n transform: translateY(0.5em);\n }\n `;\n }\n\n @property({ type: Boolean })\n open = false;\n\n @property({ type: String, attribute: 'drop_align' })\n dropAlign = 'left';\n\n @property({ type: Number })\n arrowSize = 6;\n\n @property({ type: Number })\n arrowOffset = this.arrowSize * 2;\n\n @property({ type: Number })\n offsetX = 0;\n\n @property({ type: Number })\n offsetY = 0;\n\n public firstUpdated(props: any) {\n super.firstUpdated(props);\n\n const arrow = this.shadowRoot.querySelector('.arrow') as HTMLDivElement;\n arrow.style.borderWidth = this.arrowSize + 'px';\n arrow.style.top = '-' + this.arrowSize + 'px';\n\n if (this.arrowOffset < 0) {\n arrow.style.right = Math.abs(this.arrowOffset) + 'px';\n } else {\n arrow.style.left = this.arrowOffset + 'px';\n }\n\n const dropdown = this.shadowRoot.querySelector(\n '.dropdown'\n ) as HTMLDivElement;\n\n dropdown.addEventListener('blur', () => {\n // we nest this to deal with clicking the toggle to close\n // as we don't want it to toggle an immediate open, probably\n // a better way to deal with this\n window.setTimeout(() => {\n this.open = false;\n // blur our host element too\n (this.shadowRoot.host as HTMLDivElement).blur();\n }, 200);\n });\n }\n\n public updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties);\n\n if (changedProperties.has('offsetY') || changedProperties.has('offsetX')) {\n const dropdown = this.shadowRoot.querySelector(\n '.dropdown'\n ) as HTMLDivElement;\n\n dropdown.style.marginTop = this.offsetY + 'px';\n if (dropdown.offsetLeft + dropdown.clientWidth > window.outerWidth) {\n dropdown.style.marginLeft =\n '-' + (dropdown.clientWidth - this.clientWidth - this.offsetX) + 'px';\n } else {\n dropdown.style.marginLeft = this.offsetX + 'px';\n }\n }\n\n if (changedProperties.has('open')) {\n if (this.open) {\n this.classList.add('open');\n } else {\n this.classList.remove('open');\n }\n }\n }\n\n public handleToggleClicked(): void {\n if (!this.open) {\n this.open = true;\n\n const dropdown = this.shadowRoot.querySelector(\n '.dropdown'\n ) as HTMLDivElement;\n dropdown.focus();\n }\n }\n\n public render(): TemplateResult {\n return html`\n <div class=\"wrapper ${this.open ? 'open' : ''}\">\n <slot\n name=\"toggle\"\n class=\"toggle\"\n @click=\"${this.handleToggleClicked}\"\n ></slot>\n <div\n class=\"dropdown\"\n tabindex=\"0\"\n style=\"${this.dropAlign == 'right' ? 'right:0' : ''}\"\n >\n <div class=\"arrow\"></div>\n <div class=\"dropdown-wrapper\">\n <slot name=\"dropdown\" tabindex=\"1\"></slot>\n </div>\n </div>\n </div>\n `;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nyaruka/temba-components",
3
- "version": "0.35.1",
3
+ "version": "0.35.3",
4
4
  "description": "Web components to support rapidpro and related projects",
5
5
  "author": "Nyaruka <code@nyaruka.coim>",
6
6
  "main": "dist/index.js",
@@ -5,10 +5,19 @@ import { RapidElement } from '../RapidElement';
5
5
  export class Dropdown extends RapidElement {
6
6
  static get styles() {
7
7
  return css`
8
+ .wrapper {
9
+ position: relative;
10
+ }
11
+
8
12
  .toggle {
9
13
  cursor: pointer;
10
14
  }
11
15
 
16
+ .dropdown-wrapper {
17
+ position: relative;
18
+ overflow: auto;
19
+ }
20
+
12
21
  .dropdown {
13
22
  position: absolute;
14
23
  opacity: 0;
@@ -52,6 +61,9 @@ export class Dropdown extends RapidElement {
52
61
  @property({ type: Boolean })
53
62
  open = false;
54
63
 
64
+ @property({ type: String, attribute: 'drop_align' })
65
+ dropAlign = 'left';
66
+
55
67
  @property({ type: Number })
56
68
  arrowSize = 6;
57
69
 
@@ -59,7 +71,7 @@ export class Dropdown extends RapidElement {
59
71
  arrowOffset = this.arrowSize * 2;
60
72
 
61
73
  @property({ type: Number })
62
- offsetX = -10;
74
+ offsetX = 0;
63
75
 
64
76
  @property({ type: Number })
65
77
  offsetY = 0;
@@ -67,11 +79,7 @@ export class Dropdown extends RapidElement {
67
79
  public firstUpdated(props: any) {
68
80
  super.firstUpdated(props);
69
81
 
70
- const dropdown = this.shadowRoot.querySelector(
71
- '.dropdown'
72
- ) as HTMLDivElement;
73
82
  const arrow = this.shadowRoot.querySelector('.arrow') as HTMLDivElement;
74
-
75
83
  arrow.style.borderWidth = this.arrowSize + 'px';
76
84
  arrow.style.top = '-' + this.arrowSize + 'px';
77
85
 
@@ -81,14 +89,9 @@ export class Dropdown extends RapidElement {
81
89
  arrow.style.left = this.arrowOffset + 'px';
82
90
  }
83
91
 
84
- dropdown.style.marginTop = this.offsetY + 'px';
85
-
86
- if (dropdown.offsetLeft + dropdown.clientWidth > window.outerWidth) {
87
- dropdown.style.marginLeft =
88
- '-' + (dropdown.clientWidth - this.clientWidth - this.offsetX) + 'px';
89
- } else {
90
- dropdown.style.marginLeft = this.offsetX + 'px';
91
- }
92
+ const dropdown = this.shadowRoot.querySelector(
93
+ '.dropdown'
94
+ ) as HTMLDivElement;
92
95
 
93
96
  dropdown.addEventListener('blur', () => {
94
97
  // we nest this to deal with clicking the toggle to close
@@ -96,12 +99,29 @@ export class Dropdown extends RapidElement {
96
99
  // a better way to deal with this
97
100
  window.setTimeout(() => {
98
101
  this.open = false;
102
+ // blur our host element too
103
+ (this.shadowRoot.host as HTMLDivElement).blur();
99
104
  }, 200);
100
105
  });
101
106
  }
102
107
 
103
108
  public updated(changedProperties: Map<string, any>) {
104
109
  super.updated(changedProperties);
110
+
111
+ if (changedProperties.has('offsetY') || changedProperties.has('offsetX')) {
112
+ const dropdown = this.shadowRoot.querySelector(
113
+ '.dropdown'
114
+ ) as HTMLDivElement;
115
+
116
+ dropdown.style.marginTop = this.offsetY + 'px';
117
+ if (dropdown.offsetLeft + dropdown.clientWidth > window.outerWidth) {
118
+ dropdown.style.marginLeft =
119
+ '-' + (dropdown.clientWidth - this.clientWidth - this.offsetX) + 'px';
120
+ } else {
121
+ dropdown.style.marginLeft = this.offsetX + 'px';
122
+ }
123
+ }
124
+
105
125
  if (changedProperties.has('open')) {
106
126
  if (this.open) {
107
127
  this.classList.add('open');
@@ -111,7 +131,7 @@ export class Dropdown extends RapidElement {
111
131
  }
112
132
  }
113
133
 
114
- public handleOpen(): void {
134
+ public handleToggleClicked(): void {
115
135
  if (!this.open) {
116
136
  this.open = true;
117
137
 
@@ -124,11 +144,21 @@ export class Dropdown extends RapidElement {
124
144
 
125
145
  public render(): TemplateResult {
126
146
  return html`
127
- <div class=${this.open ? 'open' : ''}>
128
- <slot name="toggle" class="toggle" @click="${this.handleOpen}"></slot>
129
- <div class="dropdown" tabindex="0">
147
+ <div class="wrapper ${this.open ? 'open' : ''}">
148
+ <slot
149
+ name="toggle"
150
+ class="toggle"
151
+ @click="${this.handleToggleClicked}"
152
+ ></slot>
153
+ <div
154
+ class="dropdown"
155
+ tabindex="0"
156
+ style="${this.dropAlign == 'right' ? 'right:0' : ''}"
157
+ >
130
158
  <div class="arrow"></div>
131
- <slot name="dropdown"></slot>
159
+ <div class="dropdown-wrapper">
160
+ <slot name="dropdown" tabindex="1"></slot>
161
+ </div>
132
162
  </div>
133
163
  </div>
134
164
  `;