@operato/layout 7.1.27 → 7.1.32
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 +18 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/.editorconfig +0 -29
- package/.storybook/main.js +0 -3
- package/.storybook/preview.js +0 -52
- package/.storybook/server.mjs +0 -8
- package/demo/index.html +0 -43
- package/src/actions/layout.ts +0 -222
- package/src/actions/snackbar.ts +0 -60
- package/src/components/ox-resize-splitter.ts +0 -137
- package/src/components/ox-split-pane.ts +0 -113
- package/src/index.ts +0 -16
- package/src/initializer.ts +0 -113
- package/src/layouts/ox-aside-bar.ts +0 -111
- package/src/layouts/ox-footer-bar.ts +0 -112
- package/src/layouts/ox-header-bar.ts +0 -108
- package/src/layouts/ox-nav-bar.ts +0 -113
- package/src/layouts/ox-page-footer-bar.ts +0 -112
- package/src/layouts/ox-page-header-bar.ts +0 -106
- package/src/layouts/ox-snack-bar.ts +0 -109
- package/src/reducers/layout.ts +0 -72
- package/src/reducers/snackbar.ts +0 -32
- package/tsconfig.json +0 -24
- package/web-dev-server.config.mjs +0 -27
- package/web-test-runner.config.mjs +0 -41
package/src/actions/layout.ts
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import { TemplateResult } from 'lit'
|
|
2
|
-
|
|
3
|
-
import { PopupHandle, PopupOptions, setOpenPopupImplementation } from '@operato/popup'
|
|
4
|
-
import { store } from '@operato/shell'
|
|
5
|
-
|
|
6
|
-
export type Viewpart = {
|
|
7
|
-
hovering?: 'center' | 'edge' | 'next'
|
|
8
|
-
show?: boolean
|
|
9
|
-
size?: string
|
|
10
|
-
title?: string
|
|
11
|
-
help?: string
|
|
12
|
-
level?: VIEWPART_LEVEL
|
|
13
|
-
closable?: boolean
|
|
14
|
-
search?: {
|
|
15
|
-
value?: string
|
|
16
|
-
handler?: (closure: any, value: string) => void
|
|
17
|
-
placeholder?: string
|
|
18
|
-
}
|
|
19
|
-
filter?: {
|
|
20
|
-
handler?: (closure: any) => void
|
|
21
|
-
}
|
|
22
|
-
backdrop?: boolean
|
|
23
|
-
temporary?: boolean /* auto remove */
|
|
24
|
-
resizable?: boolean
|
|
25
|
-
template?: TemplateResult
|
|
26
|
-
position?: VIEWPART_POSITION
|
|
27
|
-
templateProperties?: any
|
|
28
|
-
zIndex?: number
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export type AppendViewpartAction = {
|
|
32
|
-
name: string
|
|
33
|
-
viewpart: Viewpart
|
|
34
|
-
position: VIEWPART_POSITION
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export const appendViewpart = ({ name, viewpart, position }: AppendViewpartAction) => {
|
|
38
|
-
store.dispatch({
|
|
39
|
-
type: APPEND_VIEWPART,
|
|
40
|
-
name,
|
|
41
|
-
viewpart: {
|
|
42
|
-
...viewpart,
|
|
43
|
-
show: viewpart.hovering && viewpart.show ? false : viewpart.show
|
|
44
|
-
},
|
|
45
|
-
position
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
if (viewpart.hovering && viewpart.show) {
|
|
49
|
-
openOverlay(name)
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export const removeViewpart = (name: string) => {
|
|
54
|
-
store.dispatch({
|
|
55
|
-
type: REMOVE_VIEWPART,
|
|
56
|
-
name
|
|
57
|
-
})
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export const updateViewpart = (name: string, override: any) => {
|
|
61
|
-
store.dispatch({
|
|
62
|
-
type: UPDATE_VIEWPART,
|
|
63
|
-
name,
|
|
64
|
-
override
|
|
65
|
-
})
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export const APPEND_VIEWPART = 'APPEND_VIEWPART'
|
|
69
|
-
export const REMOVE_VIEWPART = 'REMOVE_VIEWPART'
|
|
70
|
-
export const UPDATE_VIEWPART = 'UPDATE_VIEWPART'
|
|
71
|
-
|
|
72
|
-
export enum VIEWPART_POSITION {
|
|
73
|
-
HEADERBAR = 'headerbar',
|
|
74
|
-
NAVBAR = 'navbar',
|
|
75
|
-
ASIDEBAR = 'asidebar',
|
|
76
|
-
FOOTERBAR = 'footerbar',
|
|
77
|
-
PAGE_HEADERBAR = 'page-headerbar',
|
|
78
|
-
PAGE_FOOTERBAR = 'page-footerbar'
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* 각 뷰파트 스택의 순서를 정하는 속성이다.
|
|
83
|
-
* 뷰파트의 level 속성에 정의되도록 한다.
|
|
84
|
-
* 맨 위/아래/좌측/우측에 보여져야하는 뷰파트는 TOPMOST 속성을 갖도록 하고,
|
|
85
|
-
* 쌓인 순서대로 보여지는 뷰파트는 NORMAL 속성을 갖도록 한다.
|
|
86
|
-
* default 속성은 NORMAL이다.
|
|
87
|
-
*/
|
|
88
|
-
export enum VIEWPART_LEVEL {
|
|
89
|
-
TOPMOST = 'TOPMOST',
|
|
90
|
-
NORMAL = 'NORMAL'
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export enum TOOL_POSITION {
|
|
94
|
-
FRONT_END = 'FRONT_END',
|
|
95
|
-
FRONT = 'FRONT',
|
|
96
|
-
CENTER = 'CENTER',
|
|
97
|
-
REAR = 'REAR',
|
|
98
|
-
REAR_END = 'REAR_END'
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export const UPDATE_VIEWPORT_WIDTH = 'UPDATE_VIEWPORT_WIDTH'
|
|
102
|
-
|
|
103
|
-
export const updateLayout = (wide?: boolean) => {
|
|
104
|
-
store.dispatch({
|
|
105
|
-
type: UPDATE_VIEWPORT_WIDTH,
|
|
106
|
-
width: wide ? 'WIDE' : 'NARROW'
|
|
107
|
-
})
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/* overlay navigation */
|
|
111
|
-
var overlaySequence = 0
|
|
112
|
-
|
|
113
|
-
export const openOverlay = (name: string, options?: any, silent?: boolean) => {
|
|
114
|
-
var beforeState = history.state
|
|
115
|
-
var beforeOverlay = beforeState ? beforeState.overlay : undefined
|
|
116
|
-
var beforeSequence = !beforeOverlay || beforeOverlay.sequence === undefined ? overlaySequence : beforeOverlay.sequence
|
|
117
|
-
var afterSequence = (overlaySequence = beforeSequence + 1)
|
|
118
|
-
|
|
119
|
-
/* store의 layout의 내용을 변경한다. */
|
|
120
|
-
if (!silent && options) {
|
|
121
|
-
store.dispatch({
|
|
122
|
-
type: UPDATE_VIEWPART,
|
|
123
|
-
name,
|
|
124
|
-
override: options
|
|
125
|
-
})
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/*
|
|
129
|
-
* 현재 history.state를 확인하고, overlay의 이름이 같은
|
|
130
|
-
* history에 추가하고 open 동작을 실행한다.
|
|
131
|
-
*/
|
|
132
|
-
var afterState = Object.assign({}, beforeState || {}, {
|
|
133
|
-
overlay: { name, sequence: afterSequence, escapable: options?.escapable !== false }
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
history.pushState(afterState, '', location.href)
|
|
137
|
-
|
|
138
|
-
window.dispatchEvent(
|
|
139
|
-
new CustomEvent('popstate', {
|
|
140
|
-
detail: { state: afterState }
|
|
141
|
-
})
|
|
142
|
-
)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export const closeOverlay = (name: string) => {
|
|
146
|
-
/*
|
|
147
|
-
* 실제로 overlay를 close하는 작업은 window.onpopstate 핸들러에서 한다.
|
|
148
|
-
*/
|
|
149
|
-
history.back()
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export const toggleOverlay = (name: string, options: any) => {
|
|
153
|
-
var { name: beforeOverlayName } = (history.state && history.state.overlay) || {}
|
|
154
|
-
|
|
155
|
-
if (beforeOverlayName == name) {
|
|
156
|
-
closeOverlay(name)
|
|
157
|
-
} else {
|
|
158
|
-
openOverlay(name, options)
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/*
|
|
163
|
-
* popup handling
|
|
164
|
-
*
|
|
165
|
-
* popup은 overlay의 특별한 형태이다.
|
|
166
|
-
* popup은 open될 때, viewpart를 append 하며, close 될 때 viewpart를 remove 한다.
|
|
167
|
-
* - name: '$popup-${popupSequence}'
|
|
168
|
-
* - position: VIEWPART_POSITION_HEADERBAR
|
|
169
|
-
* - hovering: 'center' | 'next' | 'edge'
|
|
170
|
-
*/
|
|
171
|
-
var popupSequence = 0
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* open popup in operato application environment
|
|
175
|
-
*
|
|
176
|
-
* @param {*} template html template to be rendered inside the popup
|
|
177
|
-
* @param {PopupOptions} options
|
|
178
|
-
* @returns popup handle object. This object is used to close the popup.
|
|
179
|
-
*/
|
|
180
|
-
export const openPopup = (template: TemplateResult, options: PopupOptions = {}): PopupHandle => {
|
|
181
|
-
var name = `$popup-${popupSequence++}`
|
|
182
|
-
|
|
183
|
-
appendViewpart({
|
|
184
|
-
name,
|
|
185
|
-
viewpart: {
|
|
186
|
-
hovering: 'center',
|
|
187
|
-
closable: true,
|
|
188
|
-
...options,
|
|
189
|
-
backdrop: true,
|
|
190
|
-
show: false,
|
|
191
|
-
temporary: true /* auto remove */,
|
|
192
|
-
template
|
|
193
|
-
},
|
|
194
|
-
position: VIEWPART_POSITION.HEADERBAR
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
openOverlay(name, options, true)
|
|
198
|
-
|
|
199
|
-
var popup = {
|
|
200
|
-
name,
|
|
201
|
-
close: () => {
|
|
202
|
-
/* 현재 overlay state를 확인해서, 자신인 경우에 history.back() 한다. */
|
|
203
|
-
var state = history.state
|
|
204
|
-
var overlay = (state || {}).overlay
|
|
205
|
-
|
|
206
|
-
overlay && overlay.name == name && history.back()
|
|
207
|
-
},
|
|
208
|
-
closed: false
|
|
209
|
-
} as PopupHandle
|
|
210
|
-
|
|
211
|
-
document.addEventListener('overlay-closed', function listener(e) {
|
|
212
|
-
if (name == (e as CustomEvent).detail) {
|
|
213
|
-
popup.closed = true
|
|
214
|
-
popup.onclosed && popup.onclosed()
|
|
215
|
-
document.removeEventListener('overlay-closed', listener)
|
|
216
|
-
}
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
return popup
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
setOpenPopupImplementation(openPopup)
|
package/src/actions/snackbar.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { Action } from 'redux'
|
|
2
|
-
|
|
3
|
-
export const OPEN_SNACKBAR = 'OPEN_SNACKBAR'
|
|
4
|
-
export const CLOSE_SNACKBAR = 'CLOSE_SNACKBAR'
|
|
5
|
-
|
|
6
|
-
var snackbarTimer: number
|
|
7
|
-
|
|
8
|
-
export type NotificationLevel = 'info' | 'warn' | 'error'
|
|
9
|
-
export type Notification = {
|
|
10
|
-
message: string
|
|
11
|
-
level?: NotificationLevel
|
|
12
|
-
option?: any
|
|
13
|
-
ex?: any
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function notify(notification: string | Notification): void {
|
|
17
|
-
if (typeof notification === 'string') {
|
|
18
|
-
return notify({ message: notification })
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
var { message, level, option, ex } = notification as Notification
|
|
22
|
-
|
|
23
|
-
document.dispatchEvent(
|
|
24
|
-
new CustomEvent('notify', {
|
|
25
|
-
detail: { message, level, ex, option }
|
|
26
|
-
})
|
|
27
|
-
)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export type SnackbarAction = {
|
|
31
|
-
type: 'OPEN_SNACKBAR' | 'CLOSE_SNACKBAR'
|
|
32
|
-
level?: NotificationLevel
|
|
33
|
-
message?: string
|
|
34
|
-
action?: any
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export const showSnackbar =
|
|
38
|
-
(
|
|
39
|
-
level: NotificationLevel,
|
|
40
|
-
{
|
|
41
|
-
message,
|
|
42
|
-
action,
|
|
43
|
-
timer = 5000
|
|
44
|
-
}: {
|
|
45
|
-
message: string
|
|
46
|
-
action?: any
|
|
47
|
-
timer?: number
|
|
48
|
-
}
|
|
49
|
-
) =>
|
|
50
|
-
(dispatch: (param: SnackbarAction) => Action<any>) => {
|
|
51
|
-
dispatch({
|
|
52
|
-
type: OPEN_SNACKBAR,
|
|
53
|
-
level,
|
|
54
|
-
message,
|
|
55
|
-
action
|
|
56
|
-
})
|
|
57
|
-
window.clearTimeout(snackbarTimer)
|
|
58
|
-
|
|
59
|
-
if (timer != -1) snackbarTimer = window.setTimeout(() => dispatch({ type: CLOSE_SNACKBAR }), timer)
|
|
60
|
-
}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { LitElement, css, html } from 'lit'
|
|
2
|
-
|
|
3
|
-
import { customElement } from 'lit/decorators.js'
|
|
4
|
-
|
|
5
|
-
@customElement('ox-resize-splitter')
|
|
6
|
-
export class ResizeSplitter extends LitElement {
|
|
7
|
-
static styles = css`
|
|
8
|
-
:host {
|
|
9
|
-
position: relative;
|
|
10
|
-
opacity: 0.7;
|
|
11
|
-
background-color: var(--splitter-background-color);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
:host(:hover) {
|
|
15
|
-
background-color: var(--splitter-hover-background-color);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
div {
|
|
19
|
-
position: absolute;
|
|
20
|
-
width: 100%;
|
|
21
|
-
height: 100%;
|
|
22
|
-
}
|
|
23
|
-
`
|
|
24
|
-
|
|
25
|
-
private dragstart?: { x: number; y: number }
|
|
26
|
-
|
|
27
|
-
connectedCallback() {
|
|
28
|
-
super.connectedCallback()
|
|
29
|
-
|
|
30
|
-
if (this.hasAttribute('vertical')) {
|
|
31
|
-
this.style.width = '3px'
|
|
32
|
-
this.style.height = '100%'
|
|
33
|
-
this.style.cursor = 'col-resize'
|
|
34
|
-
} else {
|
|
35
|
-
this.style.width = '100%'
|
|
36
|
-
this.style.height = '3px'
|
|
37
|
-
this.style.cursor = 'row-resize'
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
render() {
|
|
42
|
-
return html` <div @mousedown=${(e: MouseEvent) => this.onMouseDown(e)}></div> `
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// TODO onDrag 이벤트가 계속 발생하므로 처리하는 성능 저하됨. 그래서 throttling 하도록 함
|
|
46
|
-
_throttled(delay: number, fn: (...args: any) => void) {
|
|
47
|
-
let lastCall = 0
|
|
48
|
-
return function (...args: any) {
|
|
49
|
-
const now = new Date().getTime()
|
|
50
|
-
if (now - lastCall < delay) {
|
|
51
|
-
return
|
|
52
|
-
}
|
|
53
|
-
lastCall = now
|
|
54
|
-
return fn(...args)
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
private onMouseDown(e: MouseEvent) {
|
|
59
|
-
this.dragstart = {
|
|
60
|
-
x: e.clientX,
|
|
61
|
-
y: e.clientY
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
this.dispatchEvent(
|
|
65
|
-
new CustomEvent('splitter-dragstart', {
|
|
66
|
-
bubbles: true,
|
|
67
|
-
composed: true
|
|
68
|
-
})
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
window.addEventListener('mousemove', this.onMouseMoveHandler)
|
|
72
|
-
window.addEventListener('mouseup', this.onMouseUpHandler)
|
|
73
|
-
|
|
74
|
-
e.stopPropagation()
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
onMouseMoveHandler = this._throttled(100, this.onMouseMove.bind(this)) // this.onMouseMove.bind(this)
|
|
78
|
-
onMouseUpHandler = this.onMouseUp.bind(this)
|
|
79
|
-
|
|
80
|
-
private onMouseMove(e: MouseEvent) {
|
|
81
|
-
if (!this.dragstart) {
|
|
82
|
-
return
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
e.preventDefault()
|
|
86
|
-
|
|
87
|
-
this.dispatchEvent(
|
|
88
|
-
new CustomEvent('splitter-drag', {
|
|
89
|
-
bubbles: true,
|
|
90
|
-
composed: true,
|
|
91
|
-
detail: {
|
|
92
|
-
x: e.clientX - this.dragstart!.x,
|
|
93
|
-
y: e.clientY - this.dragstart!.y
|
|
94
|
-
}
|
|
95
|
-
})
|
|
96
|
-
)
|
|
97
|
-
requestAnimationFrame(() => {
|
|
98
|
-
dispatchEvent(new Event('resize'))
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
if (this.hasAttribute('vertical')) {
|
|
102
|
-
document.body.style.cursor = 'col-resize'
|
|
103
|
-
} else {
|
|
104
|
-
document.body.style.cursor = 'row-resize'
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
document.body.style.userSelect = 'none'
|
|
108
|
-
|
|
109
|
-
e.stopPropagation()
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
private onMouseUp(e: MouseEvent) {
|
|
113
|
-
window.removeEventListener('mousemove', this.onMouseMoveHandler)
|
|
114
|
-
window.removeEventListener('mouseup', this.onMouseUpHandler)
|
|
115
|
-
|
|
116
|
-
this.dispatchEvent(
|
|
117
|
-
new CustomEvent('splitter-dragend', {
|
|
118
|
-
bubbles: true,
|
|
119
|
-
composed: true,
|
|
120
|
-
detail: {
|
|
121
|
-
x: e.clientX - this.dragstart!.x,
|
|
122
|
-
y: e.clientY - this.dragstart!.y
|
|
123
|
-
}
|
|
124
|
-
})
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
requestAnimationFrame(() => {
|
|
128
|
-
dispatchEvent(new Event('resize'))
|
|
129
|
-
delete this.dragstart
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
document.body.style.cursor = ''
|
|
133
|
-
document.body.style.userSelect = ''
|
|
134
|
-
|
|
135
|
-
e.stopPropagation()
|
|
136
|
-
}
|
|
137
|
-
}
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { LitElement, html, css, PropertyValues, nothing } from 'lit'
|
|
2
|
-
import { customElement, property, query } from 'lit/decorators.js'
|
|
3
|
-
|
|
4
|
-
@customElement('ox-split-pane')
|
|
5
|
-
export class OxSplitPane extends LitElement {
|
|
6
|
-
static styles = css`
|
|
7
|
-
:host {
|
|
8
|
-
display: flex;
|
|
9
|
-
flex-direction: var(--flex-direction, column);
|
|
10
|
-
|
|
11
|
-
width: 100%;
|
|
12
|
-
height: 100%;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
#splitter {
|
|
16
|
-
background-color: #ccc;
|
|
17
|
-
cursor: var(--cursor-shape, col-resize);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
#splitter {
|
|
21
|
-
background-color: #ccc;
|
|
22
|
-
cursor: var(--cursor-shape, col-resize);
|
|
23
|
-
color: var(--md-sys-color-on-primary-container, #ccc);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
:host([direction='row']) #splitter {
|
|
27
|
-
height: 100%;
|
|
28
|
-
width: 4px;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
:host([direction='column']) #splitter {
|
|
32
|
-
width: 100%;
|
|
33
|
-
height: 4px;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
::slotted(*) {
|
|
37
|
-
overflow: hidden;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
slot[name='front']::slotted(*) {
|
|
41
|
-
flex: var(--split-ratio, 0.5);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
slot[name='back']::slotted(*) {
|
|
45
|
-
flex: calc(1 - var(--split-ratio, 0.5));
|
|
46
|
-
}
|
|
47
|
-
`
|
|
48
|
-
|
|
49
|
-
@property({ type: String, attribute: true }) direction: string = 'row'
|
|
50
|
-
@property({ type: Number, attribute: true }) ratio: number = 0.5
|
|
51
|
-
@property({ type: Boolean, attribute: true }) resizable: boolean = false
|
|
52
|
-
|
|
53
|
-
@query('#splitter') splitter!: HTMLDivElement
|
|
54
|
-
|
|
55
|
-
render() {
|
|
56
|
-
return html`
|
|
57
|
-
<slot name="front"></slot>
|
|
58
|
-
${this.resizable
|
|
59
|
-
? html`<div id="splitter" @mousedown=${this.startDragging} direction=${this.direction}></div>`
|
|
60
|
-
: nothing}
|
|
61
|
-
<slot name="back"></slot>
|
|
62
|
-
`
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async updated(changes: PropertyValues<this>) {
|
|
66
|
-
if (changes.has('direction')) {
|
|
67
|
-
this.style.setProperty('--flex-direction', this.direction)
|
|
68
|
-
this.style.setProperty('--cursor-shape', this.direction == 'row' ? 'col-resize' : 'row-resize')
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (changes.has('ratio')) {
|
|
72
|
-
this.style.setProperty('--split-ratio', String(this.ratio))
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
startDragging(e: MouseEvent) {
|
|
77
|
-
e.stopPropagation()
|
|
78
|
-
e.preventDefault()
|
|
79
|
-
|
|
80
|
-
document.addEventListener('mousemove', this.drag)
|
|
81
|
-
document.addEventListener('mouseup', this.stopDragging)
|
|
82
|
-
|
|
83
|
-
document.body.style.cursor = this.direction == 'row' ? 'col-resize' : 'row-resize'
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
drag = (e: MouseEvent) => {
|
|
87
|
-
e.stopPropagation()
|
|
88
|
-
e.preventDefault()
|
|
89
|
-
|
|
90
|
-
const { width, height, left, top } = this.getBoundingClientRect()
|
|
91
|
-
|
|
92
|
-
const mouseX = e.clientX - left
|
|
93
|
-
const mouseY = e.clientY - top
|
|
94
|
-
|
|
95
|
-
if (this.direction == 'row') {
|
|
96
|
-
const totalWidth = this.offsetWidth
|
|
97
|
-
this.ratio = mouseX / width
|
|
98
|
-
} else {
|
|
99
|
-
const totalHeight = this.offsetHeight
|
|
100
|
-
this.ratio = mouseY / height
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
stopDragging = (e: MouseEvent) => {
|
|
105
|
-
e.stopPropagation()
|
|
106
|
-
e.preventDefault()
|
|
107
|
-
|
|
108
|
-
document.removeEventListener('mousemove', this.drag)
|
|
109
|
-
document.removeEventListener('mouseup', this.stopDragging)
|
|
110
|
-
|
|
111
|
-
document.body.style.cursor = 'auto'
|
|
112
|
-
}
|
|
113
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import './initializer'
|
|
2
|
-
|
|
3
|
-
export { PopupHandle, PopupOptions } from '@operato/popup'
|
|
4
|
-
|
|
5
|
-
export * from './layouts/ox-snack-bar.js'
|
|
6
|
-
export * from './layouts/ox-header-bar.js'
|
|
7
|
-
export * from './layouts/ox-nav-bar.js'
|
|
8
|
-
export * from './layouts/ox-aside-bar.js'
|
|
9
|
-
export * from './layouts/ox-footer-bar.js'
|
|
10
|
-
export * from './layouts/ox-page-header-bar.js'
|
|
11
|
-
export * from './layouts/ox-page-footer-bar.js'
|
|
12
|
-
|
|
13
|
-
export * from './actions/layout'
|
|
14
|
-
export * from './actions/snackbar'
|
|
15
|
-
|
|
16
|
-
export * from './components/ox-split-pane'
|
package/src/initializer.ts
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { REGISTER_NAVIGATION_CALLBACK, store } from '@operato/shell'
|
|
2
|
-
import { UPDATE_VIEWPART, closeOverlay, openOverlay, openPopup, toggleOverlay } from './actions/layout'
|
|
3
|
-
|
|
4
|
-
import layout from './reducers/layout'
|
|
5
|
-
import { showSnackbar } from './actions/snackbar'
|
|
6
|
-
import snackbar from './reducers/snackbar'
|
|
7
|
-
|
|
8
|
-
store.addReducers({
|
|
9
|
-
layout,
|
|
10
|
-
snackbar
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
document.addEventListener('open-overlay', event => {
|
|
14
|
-
const { name, options } = (event as CustomEvent).detail
|
|
15
|
-
openOverlay(name, options)
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
document.addEventListener('close-overlay', event => {
|
|
19
|
-
const { name } = (event as CustomEvent).detail
|
|
20
|
-
closeOverlay(name)
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
document.addEventListener('toggle-overlay', event => {
|
|
24
|
-
const { name, options } = (event as CustomEvent).detail
|
|
25
|
-
toggleOverlay(name, options)
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
document.addEventListener('open-popup', event => {
|
|
29
|
-
const { template, options, callback } = (event as CustomEvent).detail
|
|
30
|
-
var popup = openPopup(template, options)
|
|
31
|
-
if (popup && callback) callback(popup)
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
document.addEventListener('notify', event => {
|
|
35
|
-
let { message, level, ex = '', option = {} } = (event as CustomEvent).detail
|
|
36
|
-
|
|
37
|
-
switch (level) {
|
|
38
|
-
case 'error':
|
|
39
|
-
console.error(message, ex)
|
|
40
|
-
break
|
|
41
|
-
case 'warn':
|
|
42
|
-
console.warn(message, ex)
|
|
43
|
-
break
|
|
44
|
-
case 'info':
|
|
45
|
-
console.info(message)
|
|
46
|
-
break
|
|
47
|
-
default:
|
|
48
|
-
break
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
store.dispatch(
|
|
52
|
-
showSnackbar(level, {
|
|
53
|
-
message,
|
|
54
|
-
...(option as {
|
|
55
|
-
action?: any
|
|
56
|
-
timer?: number
|
|
57
|
-
})
|
|
58
|
-
}) as any
|
|
59
|
-
)
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
/* overlay handling */
|
|
63
|
-
var overlayStack: any[] = []
|
|
64
|
-
function getLastSequence() {
|
|
65
|
-
return overlayStack.length > 0 ? overlayStack[overlayStack.length - 1].overlay.sequence : -1
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
document.addEventListener('keydown', event => {
|
|
69
|
-
if (overlayStack.length > 0 && (event.key === 'Escape' || event.key === 'Esc')) {
|
|
70
|
-
history.state?.overlay?.escapable && history.back()
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
const historyHandler = (location: string, event: Event) => {
|
|
75
|
-
var navigated = event instanceof PopStateEvent
|
|
76
|
-
|
|
77
|
-
var state = history.state
|
|
78
|
-
var overlay = state?.overlay
|
|
79
|
-
var sequence = overlay?.sequence || -1
|
|
80
|
-
|
|
81
|
-
var lastSequence = getLastSequence()
|
|
82
|
-
|
|
83
|
-
if (overlayStack.length > 0 && sequence < lastSequence) {
|
|
84
|
-
/* overlay 관련 history가 아닌 경우. */
|
|
85
|
-
do {
|
|
86
|
-
let { overlay } = overlayStack.pop()
|
|
87
|
-
store.dispatch({
|
|
88
|
-
type: UPDATE_VIEWPART,
|
|
89
|
-
name: overlay.name,
|
|
90
|
-
override: { show: false }
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
lastSequence = getLastSequence()
|
|
94
|
-
} while (sequence < lastSequence)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (!navigated && overlay) {
|
|
98
|
-
overlayStack.push({ ...state })
|
|
99
|
-
|
|
100
|
-
store.dispatch({
|
|
101
|
-
type: UPDATE_VIEWPART,
|
|
102
|
-
name: overlay.name,
|
|
103
|
-
override: { show: true }
|
|
104
|
-
})
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
store.dispatch({
|
|
109
|
-
type: REGISTER_NAVIGATION_CALLBACK,
|
|
110
|
-
callback: historyHandler
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
export default store
|