@operato/layout 1.0.0-beta.4 → 1.0.0-beta.40

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,319 +0,0 @@
1
- import '@operato/help/ox-help-icon.js'
2
- import '@material/mwc-icon'
3
-
4
- import { css, html, LitElement, PropertyValues } from 'lit'
5
- import { customElement, property } from 'lit/decorators.js'
6
-
7
- import { ScrollbarStyles } from '@operato/styles'
8
-
9
- @customElement('ox-floating-overlay')
10
- class FloatingOverlay extends LitElement {
11
- static styles = [
12
- ScrollbarStyles,
13
- css`
14
- /* for layout style */
15
- :host {
16
- position: relative;
17
- z-index: 1;
18
- }
19
-
20
- :host([hovering='edge']) {
21
- /* edge hovering 인 경우에는 상위 relative position 크기와 위치를 반영한다. */
22
- position: initial;
23
- }
24
-
25
- #backdrop {
26
- position: fixed;
27
- left: 0;
28
- top: 0;
29
-
30
- width: 100vw;
31
- height: 100vh;
32
-
33
- background-color: var(--overlay-background-color);
34
- }
35
-
36
- [overlayed] {
37
- position: absolute;
38
-
39
- display: flex;
40
- flex-direction: column;
41
- overflow: hidden;
42
- background: transparent;
43
- pointer-events: none;
44
- }
45
-
46
- [overlayed][hovering='center'] {
47
- position: fixed;
48
-
49
- left: 50%;
50
- top: 50%;
51
- transform: translate(-50%, -50%);
52
-
53
- opacity: 0;
54
- }
55
-
56
- [overlayed][hovering='center'][opened] {
57
- opacity: 1;
58
- transition: opacity 0.3s ease-in;
59
- }
60
-
61
- [hovering='center'] {
62
- width: var(--overlay-center-normal-width, 60%);
63
- height: var(--overlay-center-normal-height, 60%);
64
- }
65
-
66
- [hovering='center'][size='small'] {
67
- width: var(--overlay-center-small-width, 40%);
68
- height: var(--overlay-center-small-height, 40%);
69
- }
70
-
71
- [hovering='center'][size='large'] {
72
- width: var(--overlay-center-large-width, 100%);
73
- height: var(--overlay-center-large-height, 100%);
74
- }
75
-
76
- [header] {
77
- --help-icon-color: #fff;
78
- --help-icon-hover-color: #fff;
79
-
80
- pointer-events: initial;
81
- }
82
-
83
- [content] {
84
- flex: 1;
85
-
86
- overflow: hidden;
87
- }
88
-
89
- ::slotted(*) {
90
- box-sizing: border-box;
91
- pointer-events: initial;
92
- }
93
-
94
- [hovering='center'] [content] ::slotted(*) {
95
- width: 100%;
96
- height: 100%;
97
- }
98
- [direction='up'],
99
- [direction='down'] {
100
- width: 100%;
101
-
102
- max-height: 0;
103
- transition: max-height 0.7s ease-in;
104
- }
105
- [direction='up'] {
106
- bottom: 0;
107
- }
108
- [direction='down'] {
109
- top: 0;
110
- }
111
-
112
- [direction='up'][opened],
113
- [direction='down'][opened] {
114
- max-height: 100vh;
115
- }
116
-
117
- [settled][direction='down'] [content],
118
- [settled][direction='up'] [content] {
119
- overflow-y: auto;
120
- }
121
-
122
- [direction='left'],
123
- [direction='right'] {
124
- height: 100%;
125
-
126
- max-width: 0;
127
- transition: max-width 0.5s ease-in;
128
- }
129
- [direction='left'] {
130
- right: 0;
131
- }
132
- [direction='right'] {
133
- left: 0;
134
- }
135
-
136
- [direction='left'][opened],
137
- [direction='right'][opened] {
138
- max-width: 100vw;
139
- }
140
-
141
- [settled][direction='left'] [content],
142
- [settled][direction='right'] [content] {
143
- overflow-x: auto;
144
- }
145
-
146
- @media screen and (max-width: 460px) {
147
- [direction='up'],
148
- [direction='down'] {
149
- max-height: 100vh;
150
- }
151
-
152
- [direction='left'],
153
- [direction='right'] {
154
- max-width: 100vw;
155
- }
156
- }
157
- `,
158
- css`
159
- /* for header style */
160
- [header] {
161
- display: flex;
162
- flex-direction: row;
163
- align-items: center;
164
-
165
- background-color: var(--overlay-header-background-color);
166
- color: var(--overlay-header-color);
167
- }
168
-
169
- slot[name='header'] {
170
- flex: 1;
171
-
172
- display: flex;
173
- flex-direction: row;
174
- align-items: center;
175
- justify-content: center;
176
- }
177
-
178
- [name='header']::slotted(*) {
179
- margin: 0 auto;
180
- }
181
-
182
- [name='header'] > h1 {
183
- text-transform: capitalize;
184
- font: var(--overlay-header-font);
185
- }
186
-
187
- [historyback] {
188
- margin-left: 10px;
189
- margin-right: auto;
190
- }
191
-
192
- [close] {
193
- margin-left: auto;
194
- margin-right: 10px;
195
- }
196
-
197
- [historyback],
198
- [close] {
199
- display: none;
200
- }
201
-
202
- [closable][close] {
203
- display: block;
204
- }
205
-
206
- @media screen and (max-width: 460px) {
207
- [closable][historyback] {
208
- display: block;
209
- }
210
-
211
- [closable][close] {
212
- display: none;
213
- }
214
- }
215
- `
216
- ]
217
-
218
- @property({ type: Boolean }) backdrop: boolean = false
219
- @property({ type: String }) direction?: 'up' | 'down' | 'left' | 'right'
220
- @property({ type: String, reflect: true }) hovering?: 'center' | 'edge'
221
- @property({ type: String }) size?: 'small' | 'normal' | 'large'
222
- @property({ type: String }) name?: string
223
- @property({ type: String }) title: string = ''
224
- @property({ type: Boolean }) closable: boolean = false
225
- @property({ type: Object }) templateProperties: any
226
- @property({ type: Object }) help: any
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 || 'normal'}
241
- @close-overlay=${() => this.onClose()}
242
- @transitionstart=${(e: Event) => {
243
- /* to hide scrollbar during transition */
244
- ;(e.target as HTMLElement).removeAttribute('settled')
245
- }}
246
- @transitionend=${(e: Event) => {
247
- ;(e.target as HTMLElement).setAttribute('settled', '')
248
- }}
249
- >
250
- <div header>
251
- <mwc-icon @click=${() => this.onClose()} ?closable=${this.closable} historyback>arrow_back</mwc-icon>
252
- <slot name="header">
253
- ${this.title || this.closable
254
- ? html`
255
- <h1>
256
- ${this.title || ''}&nbsp;${this.help
257
- ? html` <ox-help-icon .topic=${this.help}></ox-help-icon>`
258
- : html``}
259
- </h1>
260
- `
261
- : html``}</slot
262
- >
263
- <mwc-icon @click=${() => this.onClose()} ?closable=${this.closable} close>close</mwc-icon>
264
- </div>
265
-
266
- <div content>
267
- <slot> </slot>
268
- </div>
269
- </div>
270
- `
271
- }
272
-
273
- updated(changes: PropertyValues<this>) {
274
- if (changes.has('templateProperties') && this.templateProperties) {
275
- var template = this.firstElementChild
276
- if (template) {
277
- for (let prop in this.templateProperties) {
278
- //@ts-ignore
279
- template[prop] = this.templateProperties[prop]
280
- }
281
- }
282
- }
283
- }
284
-
285
- firstUpdated() {
286
- requestAnimationFrame(() => {
287
- /* transition(animation) 효과를 위해 'opened' 속성을 변화시킨다. */
288
- this.renderRoot.querySelector('[overlayed]')?.setAttribute('opened', 'true')
289
- })
290
- }
291
-
292
- disconnectedCallback() {
293
- document.dispatchEvent(
294
- new CustomEvent('overlay-closed', {
295
- detail: this.name
296
- })
297
- )
298
-
299
- super.disconnectedCallback()
300
- }
301
-
302
- onClose(escape?: boolean) {
303
- /* 현재 overlay state를 확인해서, 자신이 포함하고 있는 템플릿인 경우에 history.back() 한다. */
304
-
305
- var state = history.state
306
- var overlay = (state || {}).overlay
307
-
308
- if (!overlay || overlay.name !== this.name) {
309
- return
310
- }
311
-
312
- /* Backdrop click 경우는 escape 시도라고 정의한다. overlay 속성이 escapable이 아닌 경우에는 동작하지 않는다. */
313
- if (escape && !overlay.escapable) {
314
- return true
315
- }
316
-
317
- history.back()
318
- }
319
- }