@operato/popup 0.2.35 → 0.2.42

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.
@@ -1,10 +1,10 @@
1
- import { LitElement, PropertyValues, css, html } from 'lit'
1
+ import { css, html, LitElement, PropertyValues } from 'lit'
2
2
  import { customElement, property, state } from 'lit/decorators.js'
3
3
 
4
- import { PopupMenu } from './ox-popup-menu'
4
+ import { OxPopupMenu } from './ox-popup-menu'
5
5
 
6
6
  @customElement('ox-popup-menuitem')
7
- export class PopupMenuItem extends LitElement {
7
+ export class OxPopupMenuItem extends LitElement {
8
8
  static styles = [
9
9
  css`
10
10
  :host {
@@ -52,7 +52,7 @@ export class PopupMenuItem extends LitElement {
52
52
  @property({ type: Boolean }) active: boolean = false
53
53
  @property({ type: String }) label!: string
54
54
 
55
- @state() _submenu?: PopupMenu
55
+ @state() _submenu?: OxPopupMenu
56
56
 
57
57
  render() {
58
58
  return html`
@@ -73,26 +73,26 @@ export class PopupMenuItem extends LitElement {
73
73
  this.addEventListener('click', this._onclick)
74
74
  }
75
75
 
76
- protected _onclick: (e: MouseEvent) => void = function (this: PopupMenuItem, e: MouseEvent) {
76
+ protected _onclick: (e: MouseEvent) => void = function (this: OxPopupMenuItem, e: MouseEvent) {
77
77
  if (!this._submenu) {
78
78
  return
79
79
  }
80
80
 
81
81
  e.stopPropagation()
82
82
 
83
- const parent = this.closest('ox-popup-menu') as PopupMenu
83
+ const parent = this.closest('ox-popup-menu') as OxPopupMenu
84
84
  if (parent) {
85
85
  parent.setActive(this)
86
86
  }
87
87
 
88
- this.dispatchEvent(new CustomEvent('selected'))
88
+ this.dispatchEvent(new CustomEvent('select'))
89
89
 
90
90
  requestAnimationFrame(() => {
91
91
  this.expand(false)
92
92
  })
93
93
  }.bind(this)
94
94
 
95
- protected _onkeydown: (e: KeyboardEvent) => void = function (this: PopupMenuItem, e: KeyboardEvent) {
95
+ protected _onkeydown: (e: KeyboardEvent) => void = function (this: OxPopupMenuItem, e: KeyboardEvent) {
96
96
  switch (e.key) {
97
97
  case 'Right':
98
98
  case 'ArrowRight':
@@ -115,8 +115,8 @@ export class PopupMenuItem extends LitElement {
115
115
  }
116
116
  }.bind(this)
117
117
 
118
- protected _onslotchange: (e: Event) => void = function (this: PopupMenuItem, e: Event) {
119
- this._submenu = this.querySelector('ox-popup-menu') as PopupMenu
118
+ protected _onslotchange: (e: Event) => void = function (this: OxPopupMenuItem, e: Event) {
119
+ this._submenu = this.querySelector('ox-popup-menu') as OxPopupMenu
120
120
  }.bind(this)
121
121
 
122
122
  updated(changes: PropertyValues<this>) {
@@ -139,7 +139,7 @@ export class PopupMenuItem extends LitElement {
139
139
  }
140
140
 
141
141
  const top = 0
142
- const left = this.offsetWidth + 8
142
+ const left = this.clientWidth
143
143
  this._submenu.open({ top, left, silent })
144
144
  }
145
145
 
package/src/ox-popup.ts CHANGED
@@ -1,17 +1,21 @@
1
1
  import { LitElement, css, html } from 'lit'
2
2
  import { customElement, state } from 'lit/decorators.js'
3
3
 
4
+ import { ScrollbarStyles } from '@operato/styles'
4
5
  import { render } from 'lit-html'
5
6
 
6
7
  @customElement('ox-popup')
7
- export class Popup extends LitElement {
8
+ export class OxPopup extends LitElement {
8
9
  static styles = [
10
+ ScrollbarStyles,
9
11
  css`
10
12
  :host {
11
13
  position: absolute;
12
14
  display: none;
13
15
  background-color: white;
14
16
  z-index: 100;
17
+ box-sizing: border-box;
18
+ min-width: fit-content;
15
19
  }
16
20
 
17
21
  :host([active]) {
@@ -30,7 +34,7 @@ export class Popup extends LitElement {
30
34
  return html` <slot> </slot> `
31
35
  }
32
36
 
33
- protected _onfocusout: (e: FocusEvent) => void = function (this: Popup, e: FocusEvent) {
37
+ protected _onfocusout: (e: FocusEvent) => void = function (this: OxPopup, e: FocusEvent) {
34
38
  const to = e.relatedTarget as HTMLElement
35
39
 
36
40
  if (!this.contains(to)) {
@@ -40,7 +44,7 @@ export class Popup extends LitElement {
40
44
  }
41
45
  }.bind(this)
42
46
 
43
- protected _onkeydown: (e: KeyboardEvent) => void = function (this: Popup, e: KeyboardEvent) {
47
+ protected _onkeydown: (e: KeyboardEvent) => void = function (this: OxPopup, e: KeyboardEvent) {
44
48
  e.stopPropagation()
45
49
 
46
50
  switch (e.key) {
@@ -51,24 +55,24 @@ export class Popup extends LitElement {
51
55
  }
52
56
  }.bind(this)
53
57
 
54
- protected _onkeyup: (e: KeyboardEvent) => void = function (this: Popup, e: KeyboardEvent) {
58
+ protected _onkeyup: (e: KeyboardEvent) => void = function (this: OxPopup, e: KeyboardEvent) {
55
59
  e.stopPropagation()
56
60
  }.bind(this)
57
61
 
58
- protected _onclick: (e: MouseEvent) => void = function (this: Popup, e: MouseEvent) {
62
+ protected _onclick: (e: MouseEvent) => void = function (this: OxPopup, e: MouseEvent) {
59
63
  e.stopPropagation()
60
64
  }.bind(this)
61
65
 
62
- protected _onclose: (e: Event) => void = function (this: Popup, e: Event) {
66
+ protected _onclose: (e: Event) => void = function (this: OxPopup, e: Event) {
63
67
  this.close()
64
68
  }.bind(this)
65
69
 
66
- protected _oncollapse: (e: Event) => void = function (this: Popup, e: Event) {
70
+ protected _oncollapse: (e: Event) => void = function (this: OxPopup, e: Event) {
67
71
  e.stopPropagation()
68
72
  this.close()
69
73
  }.bind(this)
70
74
 
71
- protected _onwindowblur: (e: Event) => void = function (this: Popup, e: Event) {
75
+ protected _onwindowblur: (e: Event) => void = function (this: OxPopup, e: Event) {
72
76
  // @ts-ignore for debug
73
77
  !window.POPUP_DEBUG && this.close()
74
78
  }.bind(this)
@@ -83,9 +87,6 @@ export class Popup extends LitElement {
83
87
  this.addEventListener('ox-close', this._onclose)
84
88
  this.addEventListener('ox-collapse', this._oncollapse)
85
89
 
86
- /* When the window is out of focus, all pop-ups should disappear. */
87
- window.addEventListener('blur', this._onwindowblur)
88
-
89
90
  this.setAttribute('tabindex', '0') // make this element focusable
90
91
  this.guaranteeFocus()
91
92
  }
@@ -109,33 +110,52 @@ export class Popup extends LitElement {
109
110
  template,
110
111
  top,
111
112
  left,
113
+ right,
114
+ bottom,
112
115
  parent
113
116
  }: {
114
117
  template: unknown
115
- top: number
116
- left: number
118
+ top?: number
119
+ left?: number
120
+ right?: number
121
+ bottom?: number
117
122
  parent?: Element | null
118
123
  }) {
119
124
  const owner = parent || document.body
120
- const target = document.createElement('ox-popup') as Popup
121
- render(template, target)
125
+ const target = document.createElement('ox-popup') as OxPopup
122
126
 
123
- target.style.left = `${left}px`
124
- target.style.top = `${top}px`
125
-
126
- target.setAttribute('active', '')
127
+ render(template, target)
127
128
 
128
129
  target._parent = owner
129
130
  owner.appendChild(target)
131
+
132
+ target.open({ top, left, right, bottom })
130
133
  }
131
134
 
132
- open({ left = 0, top = 0, silent = false }: { left?: number; top?: number; silent?: boolean }) {
133
- this.style.left = `${left}px`
134
- this.style.top = `${top}px`
135
+ open({
136
+ left,
137
+ top,
138
+ right,
139
+ bottom,
140
+ silent = false
141
+ }: {
142
+ left?: number
143
+ top?: number
144
+ right?: number
145
+ bottom?: number
146
+ silent?: boolean
147
+ }) {
148
+ if (left !== undefined) this.style.left = `${left}px`
149
+ if (top !== undefined) this.style.top = `${top}px`
150
+ if (right !== undefined) this.style.right = `${right}px`
151
+ if (bottom !== undefined) this.style.bottom = `${bottom}px`
135
152
 
136
153
  this.setAttribute('active', '')
137
154
 
138
155
  !silent && this.guaranteeFocus()
156
+
157
+ /* When the window is out of focus, all pop-ups should disappear. */
158
+ window.addEventListener('blur', this._onwindowblur)
139
159
  }
140
160
 
141
161
  guaranteeFocus() {
@@ -153,8 +173,10 @@ export class Popup extends LitElement {
153
173
  close() {
154
174
  this.removeAttribute('active')
155
175
 
176
+ window.removeEventListener('blur', this._onwindowblur)
177
+
156
178
  if (this._parent) {
157
- /* this case is when the popup is opened by Popup.open(...) */
179
+ /* this case is when the popup is opened by OxPopup.open(...) */
158
180
  this.removeEventListener('focusout', this._onfocusout)
159
181
  this.removeEventListener('keydown', this._onkeydown)
160
182
  this.removeEventListener('keyup', this._onkeyup)
@@ -162,8 +184,6 @@ export class Popup extends LitElement {
162
184
  this.removeEventListener('ox-close', this._onclose)
163
185
  this.removeEventListener('ox-collapse', this._oncollapse)
164
186
 
165
- window.removeEventListener('blur', this._onwindowblur)
166
-
167
187
  this._parent.removeChild(this)
168
188
  delete this._parent
169
189
  }
@@ -1,34 +1,33 @@
1
1
  import '../src/ox-popup-menu'
2
2
 
3
- import { html } from 'lit'
4
-
5
3
  import { expect, fixture } from '@open-wc/testing'
6
4
 
7
- import { PopupMenu } from '../src/ox-popup-menu'
5
+ import { OxPopupMenu } from '../src/ox-popup-menu'
6
+ import { html } from 'lit'
8
7
 
9
- describe('PopupMenu', () => {
8
+ describe('OxPopupMenu', () => {
10
9
  it('has a default title "Hey there" and counter 5', async () => {
11
- const el = await fixture<PopupMenu>(html`<ox-popup-menu></ox-popup-menu>`)
10
+ const el = await fixture<OxPopupMenu>(html`<ox-popup-menu></ox-popup-menu>`)
12
11
 
13
12
  expect(el.title).to.equal('Hey there')
14
13
  // expect(el.counter).to.equal(5)
15
14
  })
16
15
 
17
16
  it('increases the counter on button click', async () => {
18
- const el = await fixture<PopupMenu>(html`<ox-popup-menu></ox-popup-menu>`)
17
+ const el = await fixture<OxPopupMenu>(html`<ox-popup-menu></ox-popup-menu>`)
19
18
  el.shadowRoot!.querySelector('button')!.click()
20
19
 
21
20
  // expect(el.counter).to.equal(6)
22
21
  })
23
22
 
24
23
  it('can override the title via attribute', async () => {
25
- const el = await fixture<PopupMenu>(html`<ox-popup-menu title="attribute title"></ox-popup-menu>`)
24
+ const el = await fixture<OxPopupMenu>(html`<ox-popup-menu title="attribute title"></ox-popup-menu>`)
26
25
 
27
26
  expect(el.title).to.equal('attribute title')
28
27
  })
29
28
 
30
29
  it('passes the a11y audit', async () => {
31
- const el = await fixture<PopupMenu>(html`<ox-popup-menu></ox-popup-menu>`)
30
+ const el = await fixture<OxPopupMenu>(html`<ox-popup-menu></ox-popup-menu>`)
32
31
 
33
32
  await expect(el).shadowDom.to.be.accessible()
34
33
  })
@@ -1,34 +1,33 @@
1
1
  import '../src/ox-popup'
2
2
 
3
- import { html } from 'lit'
4
-
5
3
  import { expect, fixture } from '@open-wc/testing'
6
4
 
7
- import { Popup } from '../src/ox-popup'
5
+ import { OxPopup } from '../src/ox-popup'
6
+ import { html } from 'lit'
8
7
 
9
8
  describe('Popup', () => {
10
9
  it('has a default title "Hey there" and counter 5', async () => {
11
- const el = await fixture<Popup>(html`<ox-popup></ox-popup>`)
10
+ const el = await fixture<OxPopup>(html`<ox-popup></ox-popup>`)
12
11
 
13
12
  expect(el.title).to.equal('Hey there')
14
13
  // expect(el.counter).to.equal(5)
15
14
  })
16
15
 
17
16
  it('increases the counter on button click', async () => {
18
- const el = await fixture<Popup>(html`<ox-popup></ox-popup>`)
17
+ const el = await fixture<OxPopup>(html`<ox-popup></ox-popup>`)
19
18
  el.shadowRoot!.querySelector('button')!.click()
20
19
 
21
20
  // expect(el.counter).to.equal(6)
22
21
  })
23
22
 
24
23
  it('can override the title via attribute', async () => {
25
- const el = await fixture<Popup>(html`<ox-popup title="attribute title"></ox-popup>`)
24
+ const el = await fixture<OxPopup>(html`<ox-popup title="attribute title"></ox-popup>`)
26
25
 
27
26
  expect(el.title).to.equal('attribute title')
28
27
  })
29
28
 
30
29
  it('passes the a11y audit', async () => {
31
- const el = await fixture<Popup>(html`<ox-popup></ox-popup>`)
30
+ const el = await fixture<OxPopup>(html`<ox-popup></ox-popup>`)
32
31
 
33
32
  await expect(el).shadowDom.to.be.accessible()
34
33
  })