@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.
- package/CHANGELOG.md +364 -0
- package/assets/images/no-image.png +0 -0
- package/dist/src/index.d.ts +5 -4
- package/dist/src/index.js +5 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/open-popup.d.ts +59 -0
- package/dist/src/open-popup.js +84 -0
- package/dist/src/open-popup.js.map +1 -0
- package/dist/src/ox-floating-overlay.d.ts +21 -0
- package/dist/src/ox-floating-overlay.js +349 -0
- package/dist/src/ox-floating-overlay.js.map +1 -0
- package/dist/src/ox-popup.js +4 -2
- package/dist/src/ox-popup.js.map +1 -1
- package/dist/stories/open-popup.stories.d.ts +46 -0
- package/dist/stories/open-popup.stories.js +51 -0
- package/dist/stories/open-popup.stories.js.map +1 -0
- package/dist/stories/ox-popup-list.stories.d.ts +18 -0
- package/dist/stories/ox-popup-list.stories.js +50 -0
- package/dist/stories/ox-popup-list.stories.js.map +1 -0
- package/dist/stories/ox-popup-menu.stories.d.ts +19 -0
- package/dist/stories/ox-popup-menu.stories.js +131 -0
- package/dist/stories/ox-popup-menu.stories.js.map +1 -0
- package/dist/stories/ox-popup.stories.d.ts +15 -0
- package/dist/stories/ox-popup.stories.js +32 -0
- package/dist/stories/ox-popup.stories.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -8
- package/src/index.ts +6 -4
- package/src/open-popup.ts +140 -0
- package/src/ox-floating-overlay.ts +330 -0
- package/src/ox-popup.ts +4 -2
- package/stories/open-popup.stories.ts +81 -0
- package/stories/ox-popup-list.stories.ts +65 -0
- package/stories/ox-popup-menu.stories.ts +145 -0
- package/stories/ox-popup.stories.ts +46 -0
- package/themes/app-theme.css +142 -0
- package/themes/input-theme.css +19 -0
- package/dist/stories/index.stories.d.ts +0 -33
- package/dist/stories/index.stories.js +0 -33
- package/dist/stories/index.stories.js.map +0 -1
- 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 || ''} ${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 {
|
|
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 = {}
|