@operato/popup 1.0.0-beta.7 → 1.0.0

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +364 -0
  2. package/assets/images/no-image.png +0 -0
  3. package/dist/src/index.d.ts +5 -4
  4. package/dist/src/index.js +5 -4
  5. package/dist/src/index.js.map +1 -1
  6. package/dist/src/open-popup.d.ts +59 -0
  7. package/dist/src/open-popup.js +84 -0
  8. package/dist/src/open-popup.js.map +1 -0
  9. package/dist/src/ox-floating-overlay.d.ts +21 -0
  10. package/dist/src/ox-floating-overlay.js +349 -0
  11. package/dist/src/ox-floating-overlay.js.map +1 -0
  12. package/dist/src/ox-popup.js +4 -2
  13. package/dist/src/ox-popup.js.map +1 -1
  14. package/dist/stories/open-popup.stories.d.ts +46 -0
  15. package/dist/stories/open-popup.stories.js +51 -0
  16. package/dist/stories/open-popup.stories.js.map +1 -0
  17. package/dist/stories/ox-popup-list.stories.d.ts +18 -0
  18. package/dist/stories/ox-popup-list.stories.js +50 -0
  19. package/dist/stories/ox-popup-list.stories.js.map +1 -0
  20. package/dist/stories/ox-popup-menu.stories.d.ts +19 -0
  21. package/dist/stories/ox-popup-menu.stories.js +131 -0
  22. package/dist/stories/ox-popup-menu.stories.js.map +1 -0
  23. package/dist/stories/ox-popup.stories.d.ts +15 -0
  24. package/dist/stories/ox-popup.stories.js +32 -0
  25. package/dist/stories/ox-popup.stories.js.map +1 -0
  26. package/dist/tsconfig.tsbuildinfo +1 -1
  27. package/package.json +9 -8
  28. package/src/index.ts +6 -4
  29. package/src/open-popup.ts +140 -0
  30. package/src/ox-floating-overlay.ts +330 -0
  31. package/src/ox-popup.ts +4 -2
  32. package/stories/open-popup.stories.ts +81 -0
  33. package/stories/ox-popup-list.stories.ts +65 -0
  34. package/stories/ox-popup-menu.stories.ts +145 -0
  35. package/stories/ox-popup.stories.ts +46 -0
  36. package/themes/app-theme.css +142 -0
  37. package/themes/input-theme.css +19 -0
  38. package/dist/stories/index.stories.d.ts +0 -33
  39. package/dist/stories/index.stories.js +0 -33
  40. package/dist/stories/index.stories.js.map +0 -1
  41. package/stories/index.stories.ts +0 -52
@@ -0,0 +1,330 @@
1
+ import '@material/mwc-icon'
2
+
3
+ import { css, html, LitElement, PropertyValues } from 'lit'
4
+ import { customElement, property } from 'lit/decorators.js'
5
+
6
+ import { ScrollbarStyles } from '@operato/styles'
7
+
8
+ @customElement('ox-floating-overlay')
9
+ export class OxFloatingOverlay extends LitElement {
10
+ static styles = [
11
+ ScrollbarStyles,
12
+ css`
13
+ /* for layout style */
14
+ :host {
15
+ position: relative;
16
+ z-index: 1;
17
+ }
18
+
19
+ :host([hovering='edge']) {
20
+ /* edge hovering 인 경우에는 상위 relative position 크기와 위치를 반영한다. */
21
+ position: initial;
22
+ }
23
+
24
+ #backdrop {
25
+ position: fixed;
26
+ left: 0;
27
+ top: 0;
28
+
29
+ width: 100vw;
30
+ height: 100vh;
31
+
32
+ background-color: var(--overlay-background-color);
33
+ }
34
+
35
+ [overlayed] {
36
+ position: absolute;
37
+
38
+ display: flex;
39
+ flex-direction: column;
40
+ overflow: hidden;
41
+ background: transparent;
42
+ pointer-events: none;
43
+ }
44
+
45
+ [overlayed][hovering='center'] {
46
+ position: fixed;
47
+
48
+ left: 50%;
49
+ top: 50%;
50
+ transform: translate(-50%, -50%);
51
+
52
+ opacity: 0;
53
+ }
54
+
55
+ [overlayed][hovering='center'][opened] {
56
+ opacity: 1;
57
+ transition: opacity 0.3s ease-in;
58
+ }
59
+
60
+ [hovering='center'] {
61
+ width: var(--overlay-center-normal-width, 60%);
62
+ height: var(--overlay-center-normal-height, 60%);
63
+ }
64
+
65
+ [hovering='center'][size='small'] {
66
+ width: var(--overlay-center-small-width, 40%);
67
+ height: var(--overlay-center-small-height, 40%);
68
+ }
69
+
70
+ [hovering='center'][size='large'] {
71
+ width: var(--overlay-center-large-width, 100%);
72
+ height: var(--overlay-center-large-height, 100%);
73
+ }
74
+
75
+ [header] {
76
+ --help-icon-color: #fff;
77
+ --help-icon-hover-color: #fff;
78
+
79
+ pointer-events: initial;
80
+ }
81
+
82
+ [content] {
83
+ flex: 1;
84
+
85
+ overflow: hidden;
86
+ }
87
+
88
+ ::slotted(*) {
89
+ box-sizing: border-box;
90
+ pointer-events: initial;
91
+ }
92
+
93
+ [hovering='center'] [content] ::slotted(*) {
94
+ width: 100%;
95
+ height: 100%;
96
+ }
97
+ [direction='up'],
98
+ [direction='down'] {
99
+ width: 100%;
100
+
101
+ max-height: 0;
102
+ transition: max-height 0.7s ease-in;
103
+ }
104
+ [direction='up'] {
105
+ bottom: 0;
106
+ }
107
+ [direction='down'] {
108
+ top: 0;
109
+ }
110
+
111
+ [direction='up'][opened],
112
+ [direction='down'][opened] {
113
+ max-height: 100vh;
114
+ }
115
+
116
+ [settled][direction='down'] [content],
117
+ [settled][direction='up'] [content] {
118
+ overflow-y: auto;
119
+ }
120
+
121
+ [direction='left'],
122
+ [direction='right'] {
123
+ height: 100%;
124
+
125
+ max-width: 0;
126
+ transition: max-width 0.5s ease-in;
127
+ }
128
+ [direction='left'] {
129
+ right: 0;
130
+ }
131
+ [direction='right'] {
132
+ left: 0;
133
+ }
134
+
135
+ [direction='left'][opened],
136
+ [direction='right'][opened] {
137
+ max-width: 100vw;
138
+ }
139
+
140
+ [settled][direction='left'] [content],
141
+ [settled][direction='right'] [content] {
142
+ overflow-x: auto;
143
+ }
144
+
145
+ @media screen and (max-width: 460px) {
146
+ [direction='up'],
147
+ [direction='down'] {
148
+ max-height: 100vh;
149
+ }
150
+
151
+ [direction='left'],
152
+ [direction='right'] {
153
+ max-width: 100vw;
154
+ }
155
+ }
156
+ `,
157
+ css`
158
+ /* for header style */
159
+ [header] {
160
+ display: flex;
161
+ flex-direction: row;
162
+ align-items: center;
163
+
164
+ background-color: var(--overlay-header-background-color);
165
+ color: var(--overlay-header-color);
166
+ }
167
+
168
+ slot[name='header'] {
169
+ flex: 1;
170
+
171
+ display: flex;
172
+ flex-direction: row;
173
+ align-items: center;
174
+ justify-content: center;
175
+ }
176
+
177
+ [name='header']::slotted(*) {
178
+ margin: 0 auto;
179
+ }
180
+
181
+ [name='header'] > h1 {
182
+ text-transform: capitalize;
183
+ font: var(--overlay-header-font);
184
+ }
185
+
186
+ [historyback] {
187
+ margin-left: 10px;
188
+ margin-right: auto;
189
+ }
190
+
191
+ [close] {
192
+ margin-left: auto;
193
+ margin-right: 10px;
194
+ }
195
+
196
+ [historyback],
197
+ [close] {
198
+ display: none;
199
+ }
200
+
201
+ [closable][close] {
202
+ display: block;
203
+ }
204
+
205
+ @media screen and (max-width: 460px) {
206
+ [closable][historyback] {
207
+ display: block;
208
+ }
209
+
210
+ [closable][close] {
211
+ display: none;
212
+ }
213
+ }
214
+ `
215
+ ]
216
+
217
+ @property({ type: Boolean }) backdrop?: boolean = false
218
+ @property({ type: String }) direction?: 'up' | 'down' | 'left' | 'right'
219
+ @property({ type: String, reflect: true }) hovering?: 'center' | 'edge' | 'next'
220
+ @property({ type: String }) size?: 'small' | 'medium' | 'large'
221
+ @property({ type: String }) name?: string
222
+ @property({ type: String }) title: string = ''
223
+ @property({ type: Boolean }) closable?: boolean = false
224
+ @property({ type: Object }) templateProperties: any
225
+ @property({ type: Object }) help: any
226
+ @property({ type: Boolean }) historical?: boolean = false
227
+
228
+ render() {
229
+ var direction = this.hovering == 'center' ? false : this.direction
230
+
231
+ return html`
232
+ ${Boolean(this.backdrop)
233
+ ? html` <div id="backdrop" ?hidden=${!this.backdrop} @click=${() => this.onClose(true)}></div> `
234
+ : html``}
235
+
236
+ <div
237
+ overlayed
238
+ hovering=${this.hovering || 'center'}
239
+ direction=${direction}
240
+ size=${this.size || 'medium'}
241
+ @close-overlay=${(e: Event) => {
242
+ e.stopPropagation()
243
+ this.onClose()
244
+ }}
245
+ @transitionstart=${(e: Event) => {
246
+ /* to hide scrollbar during transition */
247
+ ;(e.target as HTMLElement).removeAttribute('settled')
248
+ }}
249
+ @transitionend=${(e: Event) => {
250
+ ;(e.target as HTMLElement).setAttribute('settled', '')
251
+ }}
252
+ >
253
+ <div header>
254
+ <mwc-icon @click=${() => this.onClose()} ?closable=${this.closable} historyback>arrow_back</mwc-icon>
255
+ <slot name="header">
256
+ ${this.title || this.closable
257
+ ? html`
258
+ <h1>
259
+ ${this.title || ''}&nbsp;${this.help
260
+ ? html` <ox-help-icon .topic=${this.help}></ox-help-icon>`
261
+ : html``}
262
+ </h1>
263
+ `
264
+ : html``}</slot
265
+ >
266
+ <mwc-icon @click=${() => this.onClose()} ?closable=${this.closable} close>close</mwc-icon>
267
+ </div>
268
+
269
+ <div content>
270
+ <slot> </slot>
271
+ </div>
272
+ </div>
273
+ `
274
+ }
275
+
276
+ updated(changes: PropertyValues<this>) {
277
+ if (changes.has('templateProperties') && this.templateProperties) {
278
+ var template = this.firstElementChild
279
+ if (template) {
280
+ for (let prop in this.templateProperties) {
281
+ //@ts-ignore
282
+ template[prop] = this.templateProperties[prop]
283
+ }
284
+ }
285
+ }
286
+ }
287
+
288
+ firstUpdated() {
289
+ requestAnimationFrame(() => {
290
+ /* transition(animation) 효과를 위해 'opened' 속성을 변화시킨다. */
291
+ this.renderRoot.querySelector('[overlayed]')?.setAttribute('opened', 'true')
292
+ })
293
+ }
294
+
295
+ disconnectedCallback() {
296
+ document.dispatchEvent(
297
+ new CustomEvent('overlay-closed', {
298
+ detail: this.name
299
+ })
300
+ )
301
+
302
+ super.disconnectedCallback()
303
+ }
304
+
305
+ close() {
306
+ this.parentElement?.removeChild(this)
307
+ }
308
+
309
+ onClose(escape?: boolean) {
310
+ /* 현재 overlay state를 확인해서, 자신이 포함하고 있는 템플릿인 경우에 history.back() 한다. */
311
+
312
+ if (this.historical) {
313
+ var state = history.state
314
+ var overlay = (state || {}).overlay
315
+
316
+ if (!overlay || overlay.name !== this.name) {
317
+ return
318
+ }
319
+
320
+ /* Backdrop click 경우는 escape 시도라고 정의한다. overlay 속성이 escapable이 아닌 경우에는 동작하지 않는다. */
321
+ if (escape && !overlay.escapable) {
322
+ return true
323
+ }
324
+
325
+ history.back()
326
+ } else {
327
+ this.close()
328
+ }
329
+ }
330
+ }
package/src/ox-popup.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { LitElement, css, html } from 'lit'
1
+ import { css, html, LitElement } from 'lit'
2
+ import { render } from 'lit-html'
2
3
  import { customElement, state } from 'lit/decorators.js'
3
4
 
4
5
  import { ScrollbarStyles } from '@operato/styles'
5
- import { render } from 'lit-html'
6
6
 
7
7
  @customElement('ox-popup')
8
8
  export class OxPopup extends LitElement {
@@ -18,6 +18,8 @@ export class OxPopup extends LitElement {
18
18
  box-shadow: 2px 3px 10px 5px rgba(0, 0, 0, 0.15);
19
19
  box-sizing: border-box;
20
20
  min-width: fit-content;
21
+ line-height: initial;
22
+ text-align: initial;
21
23
  }
22
24
 
23
25
  :host([active]) {
@@ -0,0 +1,81 @@
1
+ import { html, TemplateResult } from 'lit'
2
+
3
+ import { openPopup, PopupOptions } from '../src/open-popup'
4
+
5
+ export default {
6
+ title: 'openPopup',
7
+ component: 'ox-popup',
8
+ argTypes: {
9
+ title: { constol: 'string' },
10
+ size: { control: 'select', options: ['large', 'medium', 'small'] },
11
+ hovering: { control: 'select', options: ['center', 'next', 'edge'] },
12
+ closable: { control: 'boolean' },
13
+ escapable: { control: 'boolean' },
14
+ backdrop: { control: 'boolean' },
15
+ help: { constol: 'string' }
16
+ }
17
+ }
18
+
19
+ interface Story<T> {
20
+ (args: T): TemplateResult
21
+ args?: Partial<T>
22
+ argTypes?: Record<string, unknown>
23
+ }
24
+
25
+ interface ArgTypes {
26
+ title: string
27
+ size: 'large' | 'medium' | 'small'
28
+ hovering: 'center' | 'next' | 'edge'
29
+ closable: boolean
30
+ escapable: boolean
31
+ backdrop: boolean
32
+ help: string
33
+ }
34
+
35
+ function popup(e: MouseEvent, options: PopupOptions) {
36
+ const noImage = new URL('/assets/images/no-image.png', import.meta.url).href
37
+
38
+ return openPopup(html`<img src=${noImage} />`, options)
39
+ }
40
+
41
+ const Template: Story<ArgTypes> = ({
42
+ title = '',
43
+ size = 'medium',
44
+ hovering = 'center',
45
+ closable,
46
+ escapable,
47
+ backdrop,
48
+ help
49
+ }: ArgTypes) =>
50
+ html`
51
+ <link href="/themes/app-theme.css" rel="stylesheet" />
52
+ <link href="https://fonts.googleapis.com/css?family=Material+Icons&display=block" rel="stylesheet" />
53
+
54
+ <style>
55
+ #place {
56
+ width: 100%;
57
+ height: 500px;
58
+ background: lightgreen;
59
+ text-align: center;
60
+ line-height: 500px;
61
+ }
62
+ </style>
63
+
64
+ <div
65
+ id="place"
66
+ @click=${(e: MouseEvent) => popup(e, { title, size, hovering, closable, escapable, backdrop, help })}
67
+ >
68
+ Click this to popup image
69
+ </div>
70
+ `
71
+
72
+ export const Regular = Template.bind({})
73
+ Regular.args = {
74
+ title: 'Regular popup',
75
+ size: 'medium',
76
+ hovering: 'center',
77
+ closable: true,
78
+ escapable: true,
79
+ backdrop: true,
80
+ help: ''
81
+ }
@@ -0,0 +1,65 @@
1
+ import '@material/mwc-icon'
2
+ import '@operato/input/ox-checkbox.js'
3
+ import '../src/ox-popup-list.js'
4
+
5
+ import { html, TemplateResult } from 'lit'
6
+
7
+ import { OxPopupList } from '../src/ox-popup-list.js'
8
+
9
+ export default {
10
+ title: 'OxPopuList',
11
+ component: 'ox-popup-list',
12
+ argTypes: {}
13
+ }
14
+
15
+ interface Story<T> {
16
+ (args: T): TemplateResult
17
+ args?: Partial<T>
18
+ argTypes?: Record<string, unknown>
19
+ }
20
+
21
+ interface ArgTypes {}
22
+
23
+ function popup(e: MouseEvent) {
24
+ const popupList = document.querySelector('#popup-list') as OxPopupList
25
+ popupList?.open({
26
+ top: e.pageY,
27
+ left: e.pageX
28
+ })
29
+ }
30
+
31
+ const Template: Story<ArgTypes> = ({}: ArgTypes) =>
32
+ html`
33
+ <link href="https://fonts.googleapis.com/css?family=Material+Icons&display=block" rel="stylesheet" />
34
+ <style>
35
+ #place {
36
+ width: 100%;
37
+ height: 500px;
38
+ background: lightgreen;
39
+ text-align: center;
40
+ line-height: 500px;
41
+ }
42
+ </style>
43
+
44
+ <div id="place" @click=${(e: MouseEvent) => popup(e)}>Click this to popup list</div>
45
+ <ox-popup-list id="popup-list" @select=${(e: Event) => console.log('select', e.target)} multiple>
46
+ <div option>Plain Text</div>
47
+
48
+ <div option>
49
+ <ox-checkbox label="checkbox" slot="icon" checked />checkbox</ox-checkbox>
50
+ </div>
51
+
52
+ <div option>
53
+ <input id="checkbox-01" type="checkbox" />
54
+ <label for="checkbox-01">custom option</label>
55
+ </div>
56
+
57
+ <div option>
58
+ <label for="text-01">value</label>
59
+ <input id="text-01" type="text" value="Plain text input" />
60
+ </div>
61
+ </ox-popup-list>
62
+ `
63
+
64
+ export const Regular = Template.bind({})
65
+ Regular.args = {}
@@ -0,0 +1,145 @@
1
+ import '../src/ox-popup-menu.js'
2
+ import '../src/ox-popup-menuitem.js'
3
+ import '@material/mwc-icon'
4
+ import '@operato/input/ox-checkbox.js'
5
+
6
+ import { html, TemplateResult } from 'lit'
7
+
8
+ import { OxPopupMenu } from '../src/ox-popup-menu.js'
9
+
10
+ export default {
11
+ title: 'OxPopuMenu',
12
+ component: 'ox-popup-menu',
13
+ argTypes: {}
14
+ }
15
+
16
+ interface Story<T> {
17
+ (args: T): TemplateResult
18
+ args?: Partial<T>
19
+ argTypes?: Record<string, unknown>
20
+ }
21
+
22
+ interface ArgTypes {}
23
+
24
+ function popup(e: MouseEvent) {
25
+ OxPopupMenu.open({
26
+ template: html`
27
+ <ox-popup-menuitem
28
+ label="article - click me"
29
+ @selected=${function (e: Event) {
30
+ console.log('first level article selected')
31
+ }}
32
+ >
33
+ <mwc-icon slot="icon">article</mwc-icon>
34
+ </ox-popup-menuitem>
35
+
36
+ <ox-popup-menuitem label="home">
37
+ <mwc-icon slot="icon">home</mwc-icon>
38
+ </ox-popup-menuitem>
39
+
40
+ <ox-popup-menuitem label="empty"> </ox-popup-menuitem>
41
+
42
+ <ox-popup-menuitem
43
+ label="click me to toggle"
44
+ @selected=${function (e: Event) {
45
+ const icon = (e.target as HTMLElement).querySelector('mwc-icon')
46
+ icon && (icon.innerHTML = icon.innerHTML == 'check' ? '' : 'check')
47
+ }}
48
+ alive-on-select
49
+ >
50
+ <mwc-icon slot="icon" style="width: 20px;height: 20px;"></mwc-icon>
51
+ </ox-popup-menuitem>
52
+
53
+ <ox-popup-menuitem label="verified" @selected=${(e: Event) => console.log('selected verified')}>
54
+ <mwc-icon slot="icon">verified</mwc-icon>
55
+ <ox-popup-menu>
56
+ <ox-popup-menuitem
57
+ label="article"
58
+ @selected=${function (e: Event) {
59
+ console.log('article selected')
60
+ }}
61
+ alive-on-select
62
+ >
63
+ <mwc-icon slot="icon">article</mwc-icon>
64
+ </ox-popup-menuitem>
65
+
66
+ <ox-popup-menuitem label="home">
67
+ <mwc-icon slot="icon">home</mwc-icon>
68
+ </ox-popup-menuitem>
69
+
70
+ <ox-popup-menuitem label="verified">
71
+ <mwc-icon slot="icon">verified</mwc-icon>
72
+ <ox-popup-menu>
73
+ <ox-popup-menuitem label="article">
74
+ <mwc-icon slot="icon">article</mwc-icon>
75
+ </ox-popup-menuitem>
76
+
77
+ <ox-popup-menuitem label="home">
78
+ <mwc-icon slot="icon">home</mwc-icon>
79
+ </ox-popup-menuitem>
80
+
81
+ <ox-popup-menuitem label="verified">
82
+ <mwc-icon slot="icon">verified</mwc-icon>
83
+ </ox-popup-menuitem>
84
+
85
+ <ox-popup-menuitem label="checkbox">
86
+ <input type="checkbox" slot="icon" />
87
+ </ox-popup-menuitem>
88
+
89
+ <div separator></div>
90
+ </ox-popup-menu>
91
+ </ox-popup-menuitem>
92
+
93
+ <div separator></div>
94
+
95
+ <ox-popup-menuitem label="checkbox">
96
+ <input type="checkbox" slot="icon" />
97
+ </ox-popup-menuitem>
98
+ </ox-popup-menu>
99
+ </ox-popup-menuitem>
100
+
101
+ <ox-popup-menuitem label="checkbox in icon area" alive-on-select>
102
+ <input type="checkbox" slot="icon" />
103
+ </ox-popup-menuitem>
104
+
105
+ <div separator></div>
106
+
107
+ <div menu>Plain Text</div>
108
+
109
+ <div menu alive-on-select>
110
+ <ox-checkbox label="checkbox" slot="icon" checked />checkbox</ox-checkbox>
111
+ </div>
112
+
113
+ <div menu alive-on-select>
114
+ <input id="checkbox-01" type="checkbox" />
115
+ <label for="checkbox-01">custom menu</label>
116
+ </div>
117
+ <div menu alive-on-select>
118
+ <label for="text-01">value</label>
119
+ <input id="text-01" type="text" value="Plain text input" />
120
+ </div>
121
+ `,
122
+ top: e.pageY,
123
+ left: e.pageX,
124
+ parent: e.target as HTMLElement
125
+ })
126
+ }
127
+
128
+ const Template: Story<ArgTypes> = ({}: ArgTypes) =>
129
+ html`
130
+ <link href="https://fonts.googleapis.com/css?family=Material+Icons&display=block" rel="stylesheet" />
131
+ <style>
132
+ #place {
133
+ width: 100%;
134
+ height: 500px;
135
+ background: lightgreen;
136
+ text-align: center;
137
+ line-height: 500px;
138
+ }
139
+ </style>
140
+
141
+ <div id="place" @click=${(e: MouseEvent) => popup(e)}>Click this to popup menu</div>
142
+ `
143
+
144
+ export const Regular = Template.bind({})
145
+ Regular.args = {}
@@ -0,0 +1,46 @@
1
+ import { html, TemplateResult } from 'lit'
2
+
3
+ import { OxPopup } from '../src/ox-popup'
4
+
5
+ export default {
6
+ title: 'ContextMenu',
7
+ component: 'ox-popup',
8
+ argTypes: {}
9
+ }
10
+
11
+ interface Story<T> {
12
+ (args: T): TemplateResult
13
+ args?: Partial<T>
14
+ argTypes?: Record<string, unknown>
15
+ }
16
+
17
+ interface ArgTypes {}
18
+
19
+ function popup(e: MouseEvent) {
20
+ const noImage = new URL('/assets/images/no-image.png', import.meta.url).href
21
+
22
+ OxPopup.open({
23
+ template: html`<img src=${noImage} />`,
24
+ top: e.pageY,
25
+ left: e.pageX,
26
+ parent: e.target as HTMLElement
27
+ })
28
+ }
29
+
30
+ const Template: Story<ArgTypes> = ({}: ArgTypes) =>
31
+ html`
32
+ <style>
33
+ #place {
34
+ width: 100%;
35
+ height: 500px;
36
+ background: lightgreen;
37
+ text-align: center;
38
+ line-height: 500px;
39
+ }
40
+ </style>
41
+
42
+ <div id="place" @click=${(e: MouseEvent) => popup(e)}>Click this to popup image</div>
43
+ `
44
+
45
+ export const Regular = Template.bind({})
46
+ Regular.args = {}