@things-factory/layout-ui 5.0.0-zeta.7 → 5.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.
@@ -1,7 +1,7 @@
1
1
  body {
2
2
  --header-bar-background-color: var(--secondary-color);
3
3
  --header-bar-icon-size: var(--icon-default-size);
4
- --header-bar-title: bold 16px var(--theme-font);
4
+ --header-bar-title: bold 17.5px var(--theme-font);
5
5
  --header-bar-color: #fff;
6
6
  --header-bar-height: 45px;
7
7
  --header-bar-item-padding: 0px 5px 0 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/layout-ui",
3
- "version": "5.0.0-zeta.7",
3
+ "version": "5.0.0",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -24,8 +24,8 @@
24
24
  "migration:create": "node ../../node_modules/typeorm/cli.js migration:create -d ./server/migrations"
25
25
  },
26
26
  "dependencies": {
27
- "@operato/help": "1.0.0-beta.38",
28
- "@things-factory/layout-base": "^5.0.0-zeta.7"
27
+ "@operato/help": "^1.0.0",
28
+ "@operato/layout": "^1.0.0"
29
29
  },
30
- "gitHead": "e9618dfd6077ba14ebbca0ffb123a5a82660697b"
30
+ "gitHead": "32cb91663e38de9ab1bb7a72af923c3bf8ac187b"
31
31
  }
@@ -1,324 +0,0 @@
1
- import '@operato/help/ox-help-icon.js'
2
- import '@material/mwc-icon'
3
-
4
- import { css, html, LitElement } from 'lit'
5
-
6
- import { ScrollbarStyles } from '@things-factory/styles'
7
-
8
- class FloatingOverlay extends LitElement {
9
- static get properties() {
10
- return {
11
- backdrop: Boolean,
12
- direction: String,
13
- hovering: { type: String, reflect: true },
14
- size: String,
15
- name: String,
16
- title: String,
17
- closable: Boolean,
18
- templateProperties: Object,
19
- help: Object
20
- }
21
- }
22
-
23
- static get styles() {
24
- return [
25
- ScrollbarStyles,
26
- css`
27
- /* for layout style */
28
- :host {
29
- position: relative;
30
- z-index: 1;
31
- }
32
-
33
- :host([hovering='edge']) {
34
- /* edge hovering 인 경우에는 상위 relative position 크기와 위치를 반영한다. */
35
- position: initial;
36
- }
37
-
38
- #backdrop {
39
- position: fixed;
40
- left: 0;
41
- top: 0;
42
-
43
- width: 100vw;
44
- height: 100vh;
45
-
46
- background-color: var(--overlay-background-color);
47
- }
48
-
49
- [overlayed] {
50
- position: absolute;
51
-
52
- display: flex;
53
- flex-direction: column;
54
- overflow: hidden;
55
- background: transparent;
56
- pointer-events: none;
57
- }
58
-
59
- [overlayed][hovering='center'] {
60
- position: fixed;
61
-
62
- left: 50%;
63
- top: 50%;
64
- transform: translate(-50%, -50%);
65
-
66
- opacity: 0;
67
- }
68
-
69
- [overlayed][hovering='center'][opened] {
70
- opacity: 1;
71
- transition: opacity 0.3s ease-in;
72
- }
73
-
74
- [hovering='center'] {
75
- width: var(--overlay-center-normal-width, 60%);
76
- height: var(--overlay-center-normal-height, 60%);
77
- }
78
-
79
- [hovering='center'][size='small'] {
80
- width: var(--overlay-center-small-width, 40%);
81
- height: var(--overlay-center-small-height, 40%);
82
- }
83
-
84
- [hovering='center'][size='large'] {
85
- width: var(--overlay-center-large-width, 100%);
86
- height: var(--overlay-center-large-height, 100%);
87
- }
88
-
89
- [header] {
90
- --help-icon-color: #fff;
91
- --help-icon-hover-color: #fff;
92
-
93
- pointer-events: initial;
94
- }
95
-
96
- [content] {
97
- flex: 1;
98
-
99
- overflow: hidden;
100
- }
101
-
102
- ::slotted(*) {
103
- box-sizing: border-box;
104
- pointer-events: initial;
105
- }
106
-
107
- [hovering='center'] [content] ::slotted(*) {
108
- width: 100%;
109
- height: 100%;
110
- }
111
- [direction='up'],
112
- [direction='down'] {
113
- width: 100%;
114
-
115
- max-height: 0;
116
- transition: max-height 0.7s ease-in;
117
- }
118
- [direction='up'] {
119
- bottom: 0;
120
- }
121
- [direction='down'] {
122
- top: 0;
123
- }
124
-
125
- [direction='up'][opened],
126
- [direction='down'][opened] {
127
- max-height: 100vh;
128
- }
129
-
130
- [settled][direction='down'] [content],
131
- [settled][direction='up'] [content] {
132
- overflow-y: auto;
133
- }
134
-
135
- [direction='left'],
136
- [direction='right'] {
137
- height: 100%;
138
-
139
- max-width: 0;
140
- transition: max-width 0.5s ease-in;
141
- }
142
- [direction='left'] {
143
- right: 0;
144
- }
145
- [direction='right'] {
146
- left: 0;
147
- }
148
-
149
- [direction='left'][opened],
150
- [direction='right'][opened] {
151
- max-width: 100vw;
152
- }
153
-
154
- [settled][direction='left'] [content],
155
- [settled][direction='right'] [content] {
156
- overflow-x: auto;
157
- }
158
-
159
- @media screen and (max-width: 460px) {
160
- [direction='up'],
161
- [direction='down'] {
162
- max-height: 100vh;
163
- }
164
-
165
- [direction='left'],
166
- [direction='right'] {
167
- max-width: 100vw;
168
- }
169
- }
170
- `,
171
- css`
172
- /* for header style */
173
- [header] {
174
- display: flex;
175
- flex-direction: row;
176
- align-items: center;
177
-
178
- background-color: var(--overlay-header-background-color);
179
- color: var(--overlay-header-color);
180
- }
181
-
182
- slot[name='header'] {
183
- flex: 1;
184
-
185
- display: flex;
186
- flex-direction: row;
187
- align-items: center;
188
- justify-content: center;
189
- }
190
-
191
- [name='header']::slotted(*) {
192
- margin: 0 auto;
193
- }
194
-
195
- [name='header'] > h1 {
196
- text-transform: capitalize;
197
- font: var(--overlay-header-font);
198
- }
199
-
200
- [historyback] {
201
- margin-left: 10px;
202
- margin-right: auto;
203
- }
204
-
205
- [close] {
206
- margin-left: auto;
207
- margin-right: 10px;
208
- }
209
-
210
- [historyback],
211
- [close] {
212
- display: none;
213
- }
214
-
215
- [closable][close] {
216
- display: block;
217
- }
218
-
219
- @media screen and (max-width: 460px) {
220
- [closable][historyback] {
221
- display: block;
222
- }
223
-
224
- [closable][close] {
225
- display: none;
226
- }
227
- }
228
- `
229
- ]
230
- }
231
-
232
- render() {
233
- var direction = this.hovering == 'center' ? false : this.direction
234
-
235
- return html`
236
- ${Boolean(this.backdrop)
237
- ? html` <div id="backdrop" ?hidden=${!this.backdrop} @click=${e => this.onClose(true)}></div> `
238
- : html``}
239
-
240
- <div
241
- overlayed
242
- hovering=${this.hovering || 'center'}
243
- direction=${direction}
244
- size=${this.size || 'normal'}
245
- @close-overlay=${e => this.onClose()}
246
- @transitionstart=${e => {
247
- /* to hide scrollbar during transition */
248
- e.target.removeAttribute('settled', '')
249
- }}
250
- @transitionend=${e => {
251
- e.target.setAttribute('settled', '')
252
- }}
253
- >
254
- <div header>
255
- <mwc-icon @click=${e => this.onClose()} ?closable=${this.closable} historyback>arrow_back</mwc-icon>
256
- <slot name="header">
257
- ${this.title || this.closable
258
- ? html`
259
- <h1>
260
- ${this.title || ''}&nbsp;${this.help
261
- ? html` <ox-help-icon .topic=${this.help}></ox-help-icon>`
262
- : html``}
263
- </h1>
264
- `
265
- : html``}</slot
266
- >
267
- <mwc-icon @click=${e => this.onClose()} ?closable=${this.closable} close>close</mwc-icon>
268
- </div>
269
-
270
- <div content>
271
- <slot> </slot>
272
- </div>
273
- </div>
274
- `
275
- }
276
-
277
- updated(changed) {
278
- if (changed.has('templateProperties') && this.templateProperties) {
279
- var template = this.firstElementChild
280
- if (template) {
281
- for (let prop in this.templateProperties) {
282
- template[prop] = this.templateProperties[prop]
283
- }
284
- }
285
- }
286
- }
287
-
288
- firstUpdated() {
289
- requestAnimationFrame(() => {
290
- /* transition(animation) 효과를 위해 'opened' 속성을 변화시킨다. */
291
- this.shadowRoot.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
- onClose(escape) {
306
- /* 현재 overlay state를 확인해서, 자신이 포함하고 있는 템플릿인 경우에 history.back() 한다. */
307
-
308
- var state = history.state
309
- var overlay = (state || {}).overlay
310
-
311
- if (!overlay || overlay.name !== this.name) {
312
- return
313
- }
314
-
315
- /* Backdrop click 경우는 escape 시도라고 정의한다. overlay 속성이 escapable이 아닌 경우에는 동작하지 않는다. */
316
- if (escape && !overlay.escapable) {
317
- return true
318
- }
319
-
320
- history.back()
321
- }
322
- }
323
-
324
- customElements.define('floating-overlay', FloatingOverlay)
@@ -1,128 +0,0 @@
1
- import { LitElement, html, css } from 'lit'
2
-
3
- export class ResizeSplitter extends LitElement {
4
- static get dragImage() {
5
- if (!ResizeSplitter._dragImage) {
6
- ResizeSplitter._dragImage = new Image()
7
- ResizeSplitter._dragImage.src =
8
- 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='
9
- }
10
- return ResizeSplitter._dragImage
11
- }
12
-
13
- static get styles() {
14
- return css`
15
- :host {
16
- position: relative;
17
- opacity: 0.7;
18
- background-color: var(--splitter-background-color);
19
- }
20
-
21
- :host(:hover) {
22
- background-color: var(--splitter-hover-background-color);
23
- }
24
-
25
- div {
26
- position: absolute;
27
- width: 100%;
28
- height: 100%;
29
- }
30
- `
31
- }
32
-
33
- static get properties() {
34
- return {}
35
- }
36
-
37
- connectedCallback() {
38
- super.connectedCallback()
39
-
40
- if (this.hasAttribute('vertical')) {
41
- this.style.width = '3px'
42
- this.style.height = '100%'
43
- this.style.cursor = 'col-resize'
44
- } else {
45
- this.style.width = '100%'
46
- this.style.height = '3px'
47
- this.style.cursor = 'row-resize'
48
- }
49
- }
50
-
51
- render() {
52
- return html`
53
- <div
54
- draggable="true"
55
- @dragstart=${e => this._onDragStart(e)}
56
- @drag=${this._throttled(100, this._onDrag.bind(this))}
57
- @dragend=${e => this._onDragEnd(e)}
58
- ></div>
59
- `
60
- }
61
-
62
- // TODO onDrag 이벤트가 계속 발생하므로 처리하는 성능 저하됨. 그래서 throttling 하도록 함
63
- _throttled(delay, fn) {
64
- let lastCall = 0
65
- return function (...args) {
66
- const now = new Date().getTime()
67
- if (now - lastCall < delay) {
68
- return
69
- }
70
- lastCall = now
71
- return fn(...args)
72
- }
73
- }
74
-
75
- _onDragStart(e) {
76
- e.dataTransfer.setDragImage(ResizeSplitter.dragImage, 0, 0)
77
-
78
- this.dragstart = {
79
- x: e.clientX,
80
- y: e.clientY
81
- }
82
-
83
- this.dispatchEvent(
84
- new CustomEvent('splitter-dragstart', {
85
- bubbles: true,
86
- composed: true
87
- })
88
- )
89
-
90
- e.stopPropagation()
91
- }
92
-
93
- _onDrag(e) {
94
- if (e.clientX == 0) {
95
- return
96
- }
97
-
98
- this.dispatchEvent(
99
- new CustomEvent('splitter-drag', {
100
- bubbles: true,
101
- composed: true,
102
- detail: {
103
- x: e.clientX - this.dragstart.x,
104
- y: e.clientY - this.dragstart.y
105
- }
106
- })
107
- )
108
-
109
- e.stopPropagation()
110
- }
111
-
112
- _onDragEnd(e) {
113
- this.dispatchEvent(
114
- new CustomEvent('splitter-dragend', {
115
- bubbles: true,
116
- composed: true,
117
- detail: {
118
- x: e.clientX - this.dragstart.x,
119
- y: e.clientY - this.dragstart.y
120
- }
121
- })
122
- )
123
-
124
- e.stopPropagation()
125
- }
126
- }
127
-
128
- customElements.define('resize-splitter', ResizeSplitter)
@@ -1,111 +0,0 @@
1
- import { LitElement, html, css } from 'lit'
2
-
3
- import { connect } from 'pwa-helpers/connect-mixin.js'
4
- import { store } from '@things-factory/shell'
5
- import { ScrollbarStyles } from '@things-factory/styles'
6
- import { VIEWPART_LEVEL } from '@things-factory/layout-base'
7
-
8
- import '../components/floating-overlay'
9
- import '../components/resize-splitter'
10
-
11
- class AsideBar extends connect(store)(LitElement) {
12
- static get properties() {
13
- return {
14
- viewparts: Array,
15
- fullbleed: {
16
- attribute: 'fullbleed',
17
- type: Boolean
18
- }
19
- }
20
- }
21
-
22
- static get styles() {
23
- return [
24
- ScrollbarStyles,
25
- css`
26
- :host {
27
- display: flex;
28
- flex-flow: row-reverse nowrap;
29
- align-items: stretch;
30
-
31
- position: relative;
32
- }
33
-
34
- *[asidebar] {
35
- display: block;
36
- overflow-y: auto;
37
- }
38
- `
39
- ]
40
- }
41
-
42
- render() {
43
- var viewparts = this.viewparts
44
- var asidebars = Object.keys(viewparts)
45
- .map(name => {
46
- return {
47
- name,
48
- ...viewparts[name]
49
- }
50
- })
51
- .filter(viewpart => viewpart.position == 'asidebar' && (!this.fullbleed || viewpart.hovering))
52
-
53
- asidebars = [
54
- ...asidebars.filter(viewpart => viewpart.level == VIEWPART_LEVEL.TOPMOST),
55
- ...asidebars.filter(viewpart => viewpart.level !== VIEWPART_LEVEL.TOPMOST)
56
- ]
57
-
58
- return html`
59
- ${asidebars.map(asidebar =>
60
- !asidebar.show
61
- ? html``
62
- : asidebar.hovering
63
- ? html`
64
- <floating-overlay
65
- .backdrop=${asidebar.backdrop}
66
- direction="left"
67
- .hovering=${asidebar.hovering}
68
- .name=${asidebar.name}
69
- .size=${asidebar.size}
70
- .title=${asidebar.title}
71
- .help=${asidebar.help}
72
- .closable=${asidebar.closable}
73
- .templateProperties=${asidebar.templateProperties}
74
- >${asidebar.template}</floating-overlay
75
- >
76
- `
77
- : html`
78
- <div asidebar>${asidebar.template}</div>
79
- ${asidebar.resizable
80
- ? html`
81
- <resize-splitter
82
- @splitter-dragstart=${e => this.resizeStart(e)}
83
- @splitter-drag=${e => this.resizeDrag(e)}
84
- vertical
85
- ></resize-splitter>
86
- `
87
- : html``}
88
- `
89
- )}
90
- `
91
- }
92
-
93
- resizeStart(e) {
94
- this._startWidth = e.target.previousElementSibling.offsetWidth
95
- }
96
-
97
- resizeDrag(e) {
98
- var delta = e.detail
99
-
100
- var x = e.target.previousElementSibling.querySelectorAll('*')
101
- Array.from(x).forEach(ele => {
102
- ele.style.width = `${this._startWidth - delta.x}px`
103
- })
104
- }
105
-
106
- stateChanged(state) {
107
- this.viewparts = state.layout.viewparts || {}
108
- }
109
- }
110
-
111
- customElements.define('aside-bar', AsideBar)
@@ -1,111 +0,0 @@
1
- import { store } from '@things-factory/shell'
2
- import { css, html, LitElement } from 'lit'
3
- import { connect } from 'pwa-helpers/connect-mixin.js'
4
- import { VIEWPART_LEVEL } from '@things-factory/layout-base'
5
-
6
- import '../components/floating-overlay'
7
- import '../components/resize-splitter'
8
-
9
- class FooterBar extends connect(store)(LitElement) {
10
- static get properties() {
11
- return {
12
- viewparts: Array,
13
- fullbleed: {
14
- attribute: 'fullbleed',
15
- type: Boolean
16
- }
17
- }
18
- }
19
-
20
- static get styles() {
21
- return [
22
- css`
23
- :host {
24
- display: flex;
25
- flex-flow: column-reverse nowrap;
26
- align-items: stretch;
27
- position: relative;
28
- }
29
-
30
- *[footerbar] {
31
- display: block;
32
- }
33
-
34
- @media screen and (max-width: 460px) {
35
- :host {
36
- padding-bottom: 0;
37
- }
38
- }
39
- `
40
- ]
41
- }
42
-
43
- render() {
44
- var viewparts = this.viewparts
45
- var footerbars = Object.keys(viewparts)
46
- .map(name => {
47
- return {
48
- name,
49
- ...viewparts[name]
50
- }
51
- })
52
- .filter(viewpart => viewpart.position == 'footerbar' && (!this.fullbleed || viewpart.hovering))
53
-
54
- footerbars = [
55
- ...footerbars.filter(viewpart => viewpart.level == VIEWPART_LEVEL.TOPMOST),
56
- ...footerbars.filter(viewpart => viewpart.level !== VIEWPART_LEVEL.TOPMOST)
57
- ]
58
-
59
- return html`
60
- ${footerbars.map(footerbar =>
61
- !footerbar.show
62
- ? html``
63
- : footerbar.hovering
64
- ? html`
65
- <floating-overlay
66
- .backdrop=${footerbar.backdrop}
67
- direction="up"
68
- .hovering=${footerbar.hovering}
69
- .name=${footerbar.name}
70
- .title=${footerbar.title}
71
- .help=${footerbar.help}
72
- .size=${footerbar.size}
73
- .closable=${footerbar.closable}
74
- .templateProperties=${footerbar.templateProperties}
75
- >${footerbar.template}</floating-overlay
76
- >
77
- `
78
- : html`
79
- <div footerbar>${footerbar.template}</div>
80
- ${footerbar.resizable
81
- ? html`
82
- <resize-splitter
83
- @splitter-dragstart=${e => this.resizeStart(e)}
84
- @splitter-drag=${e => this.resizeDrag(e)}
85
- ></resize-splitter>
86
- `
87
- : html``}
88
- `
89
- )}
90
- `
91
- }
92
-
93
- resizeStart(e) {
94
- this._startHeight = e.target.previousElementSibling.offsetHeight
95
- }
96
-
97
- resizeDrag(e) {
98
- var delta = e.detail
99
-
100
- var x = e.target.previousElementSibling.querySelectorAll('*')
101
- Array.from(x).forEach(ele => {
102
- ele.style.height = `${this._startHeight - delta.y}px`
103
- })
104
- }
105
-
106
- stateChanged(state) {
107
- this.viewparts = state.layout.viewparts || {}
108
- }
109
- }
110
-
111
- customElements.define('footer-bar', FooterBar)
@@ -1,109 +0,0 @@
1
- import { LitElement, html, css } from 'lit'
2
-
3
- import { connect } from 'pwa-helpers/connect-mixin.js'
4
- import { store } from '@things-factory/shell'
5
- import { VIEWPART_LEVEL } from '@things-factory/layout-base'
6
-
7
- import '../components/floating-overlay'
8
- import '../components/resize-splitter'
9
-
10
- class HeaderBar extends connect(store)(LitElement) {
11
- static get properties() {
12
- return {
13
- viewparts: Array,
14
- fullbleed: {
15
- attribute: 'fullbleed',
16
- type: Boolean
17
- }
18
- }
19
- }
20
-
21
- static get styles() {
22
- return [
23
- css`
24
- :host {
25
- display: flex;
26
- flex-flow: column nowrap;
27
- align-items: stretch;
28
-
29
- position: relative;
30
-
31
- background-color: var(--header-bar-background-color);
32
- }
33
-
34
- *[headerbar] {
35
- display: block;
36
- }
37
- `
38
- ]
39
- }
40
-
41
- render() {
42
- var viewparts = this.viewparts
43
- var headerbars = Object.keys(viewparts)
44
- .map(name => {
45
- return {
46
- name,
47
- ...viewparts[name]
48
- }
49
- })
50
- .filter(viewpart => viewpart.position == 'headerbar' && (!this.fullbleed || viewpart.hovering))
51
-
52
- headerbars = [
53
- ...headerbars.filter(viewpart => viewpart.level == VIEWPART_LEVEL.TOPMOST),
54
- ...headerbars.filter(viewpart => viewpart.level !== VIEWPART_LEVEL.TOPMOST)
55
- ]
56
-
57
- return html`
58
- ${headerbars.map(headerbar =>
59
- !headerbar.show
60
- ? html``
61
- : headerbar.hovering
62
- ? html`
63
- <floating-overlay
64
- .backdrop=${headerbar.backdrop}
65
- direction="down"
66
- .hovering=${headerbar.hovering}
67
- .name=${headerbar.name}
68
- .title=${headerbar.title}
69
- .help=${headerbar.help}
70
- .size=${headerbar.size}
71
- .closable=${headerbar.closable}
72
- .templateProperties=${headerbar.templateProperties}
73
- >${headerbar.template}</floating-overlay
74
- >
75
- `
76
- : html`
77
- <div headerbar>${headerbar.template}</div>
78
- ${headerbar.resizable
79
- ? html`
80
- <resize-splitter
81
- @splitter-dragstart=${e => this.resizeStart(e)}
82
- @splitter-drag=${e => this.resizeDrag(e)}
83
- ></resize-splitter>
84
- `
85
- : html``}
86
- `
87
- )}
88
- `
89
- }
90
-
91
- resizeStart(e) {
92
- this._startHeight = e.target.previousElementSibling.offsetHeight
93
- }
94
-
95
- resizeDrag(e) {
96
- var delta = e.detail
97
-
98
- var x = e.target.previousElementSibling.querySelectorAll('*')
99
- Array.from(x).forEach(ele => {
100
- ele.style.height = `${this._startHeight + delta.y}px`
101
- })
102
- }
103
-
104
- stateChanged(state) {
105
- this.viewparts = state.layout.viewparts || {}
106
- }
107
- }
108
-
109
- customElements.define('header-bar', HeaderBar)
@@ -1,6 +0,0 @@
1
- import './snack-bar'
2
-
3
- import './header-bar'
4
- import './nav-bar'
5
- import './aside-bar'
6
- import './footer-bar'
@@ -1,113 +0,0 @@
1
- import { LitElement, html, css } from 'lit'
2
-
3
- import { connect } from 'pwa-helpers/connect-mixin.js'
4
- import { store } from '@things-factory/shell'
5
- import { ScrollbarStyles } from '@things-factory/styles'
6
- import { VIEWPART_LEVEL } from '@things-factory/layout-base'
7
-
8
- import '../components/floating-overlay'
9
- import '../components/resize-splitter'
10
-
11
- class NavBar extends connect(store)(LitElement) {
12
- static get properties() {
13
- return {
14
- viewparts: Array,
15
- fullbleed: {
16
- attribute: 'fullbleed',
17
- type: Boolean
18
- }
19
- }
20
- }
21
-
22
- static get styles() {
23
- return [
24
- ScrollbarStyles,
25
- css`
26
- :host {
27
- display: flex;
28
- flex-flow: row nowrap;
29
- align-items: stretch;
30
-
31
- position: relative;
32
-
33
- background-color: var(--nav-bar-background-color);
34
- }
35
-
36
- *[navbar] {
37
- display: flex;
38
- flex-direction: row;
39
- }
40
- `
41
- ]
42
- }
43
-
44
- render() {
45
- var viewparts = this.viewparts
46
- var navbars = Object.keys(viewparts)
47
- .map(name => {
48
- return {
49
- name,
50
- ...viewparts[name]
51
- }
52
- })
53
- .filter(viewpart => viewpart.position == 'navbar' && (!this.fullbleed || viewpart.hovering))
54
-
55
- navbars = [
56
- ...navbars.filter(viewpart => viewpart.level == VIEWPART_LEVEL.TOPMOST),
57
- ...navbars.filter(viewpart => viewpart.level !== VIEWPART_LEVEL.TOPMOST)
58
- ]
59
-
60
- return html`
61
- ${navbars.map(navbar =>
62
- !navbar.show
63
- ? html``
64
- : navbar.hovering
65
- ? html`
66
- <floating-overlay
67
- .backdrop=${navbar.backdrop}
68
- direction="right"
69
- .hovering=${navbar.hovering}
70
- .name=${navbar.name}
71
- .title=${navbar.title}
72
- .help=${navbar.help}
73
- .size=${navbar.size}
74
- .closable=${navbar.closable}
75
- .templateProperties=${navbar.templateProperties}
76
- >${navbar.template}</floating-overlay
77
- >
78
- `
79
- : html`
80
- <div navbar>${navbar.template}</div>
81
- ${navbar.resizable
82
- ? html`
83
- <resize-splitter
84
- @splitter-dragstart=${e => this.resizeStart(e)}
85
- @splitter-drag=${e => this.resizeDrag(e)}
86
- vertical
87
- ></resize-splitter>
88
- `
89
- : html``}
90
- `
91
- )}
92
- `
93
- }
94
-
95
- resizeStart(e) {
96
- this._startWidth = e.target.previousElementSibling.offsetWidth
97
- }
98
-
99
- resizeDrag(e) {
100
- var delta = e.detail
101
-
102
- var x = e.target.previousElementSibling.querySelectorAll('*')
103
- Array.from(x).forEach(ele => {
104
- ele.style.width = `${this._startWidth + delta.x}px`
105
- })
106
- }
107
-
108
- stateChanged(state) {
109
- this.viewparts = state.layout.viewparts || {}
110
- }
111
- }
112
-
113
- customElements.define('nav-bar', NavBar)
@@ -1,117 +0,0 @@
1
- import '@material/mwc-button'
2
- import '@material/mwc-icon'
3
- import { CLOSE_SNACKBAR } from '@things-factory/layout-base'
4
- import { store } from '@things-factory/shell'
5
- import { css, html, LitElement } from 'lit'
6
- import { connect } from 'pwa-helpers/connect-mixin.js'
7
-
8
- class SnackBar extends connect(store)(LitElement) {
9
- static get properties() {
10
- return {
11
- level: String,
12
- message: String,
13
- active: {
14
- reflect: true,
15
- type: Boolean
16
- },
17
- action: Object
18
- }
19
- }
20
-
21
- static get styles() {
22
- return [
23
- css`
24
- :host {
25
- display: block;
26
- position: fixed;
27
- top: 100%;
28
- left: 0;
29
- right: 0;
30
- padding: 12px;
31
- background-color: black;
32
- color: white;
33
- box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
34
- text-align: center;
35
- will-change: transform;
36
- transform: translate3d(0, 0, 0);
37
- transition-property: visibility, transform;
38
- transition-duration: 0.2s;
39
- visibility: hidden;
40
- }
41
-
42
- :host([active]) {
43
- visibility: visible;
44
- transform: translate3d(0, -100%, 0);
45
- }
46
-
47
- mwc-icon {
48
- --mdc-icon-size: 1.2em;
49
- vertical-align: middle;
50
- max-width: 20px;
51
- }
52
-
53
- mwc-button {
54
- display: block;
55
- }
56
-
57
- .info {
58
- color: green;
59
- }
60
-
61
- .warn {
62
- color: yellow;
63
- }
64
-
65
- .error {
66
- color: red;
67
- }
68
-
69
- @media (min-width: 460px) {
70
- :host {
71
- width: 320px;
72
- margin: auto;
73
- }
74
- }
75
- `
76
- ]
77
- }
78
-
79
- render() {
80
- return html`
81
- <span>
82
- <mwc-icon class=${this.level}
83
- >${this.level == 'info'
84
- ? html` notification_important `
85
- : this.level == 'warn'
86
- ? html` warning `
87
- : this.level == 'error'
88
- ? html` error `
89
- : html``}</mwc-icon
90
- >
91
- </span>
92
- <span>${this.message}</span>
93
- ${this.action && this.action.label
94
- ? html`
95
- <mwc-button
96
- @click=${e => {
97
- store.dispatch({ type: CLOSE_SNACKBAR })
98
- this.action.callback()
99
- }}
100
- >${this.action.label}</mwc-button
101
- >
102
- `
103
- : html``}
104
- `
105
- }
106
-
107
- stateChanged(state) {
108
- var { level, message, snackbarOpened, action } = state.snackbar || {}
109
-
110
- this.level = level
111
- this.message = message
112
- this.active = snackbarOpened
113
- this.action = action
114
- }
115
- }
116
-
117
- window.customElements.define('snack-bar', SnackBar)