@operato/layout 0.3.21 → 0.3.27

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 (75) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/src/actions/layout.d.ts +89 -0
  3. package/dist/src/actions/layout.js +159 -0
  4. package/dist/src/actions/layout.js.map +1 -0
  5. package/dist/src/actions/snackbar.d.ts +22 -0
  6. package/dist/src/actions/snackbar.js +24 -0
  7. package/dist/src/actions/snackbar.js.map +1 -0
  8. package/dist/src/components/ox-floating-overlay.d.ts +2 -0
  9. package/dist/src/components/ox-floating-overlay.js +333 -0
  10. package/dist/src/components/ox-floating-overlay.js.map +1 -0
  11. package/dist/src/components/ox-resize-splitter.d.ts +13 -0
  12. package/dist/src/components/ox-resize-splitter.js +108 -0
  13. package/dist/src/components/ox-resize-splitter.js.map +1 -0
  14. package/dist/src/index.d.ts +8 -1
  15. package/dist/src/index.js +8 -1
  16. package/dist/src/index.js.map +1 -1
  17. package/dist/src/initializer.d.ts +2 -0
  18. package/dist/src/initializer.js +91 -0
  19. package/dist/src/initializer.js.map +1 -0
  20. package/dist/src/layouts/ox-aside-bar.d.ts +2 -0
  21. package/dist/src/layouts/ox-aside-bar.js +106 -0
  22. package/dist/src/layouts/ox-aside-bar.js.map +1 -0
  23. package/dist/src/layouts/ox-footer-bar.d.ts +2 -0
  24. package/dist/src/layouts/ox-footer-bar.js +107 -0
  25. package/dist/src/layouts/ox-footer-bar.js.map +1 -0
  26. package/dist/src/layouts/ox-header-bar.d.ts +2 -0
  27. package/dist/src/layouts/ox-header-bar.js +104 -0
  28. package/dist/src/layouts/ox-header-bar.js.map +1 -0
  29. package/dist/src/layouts/ox-nav-bar.d.ts +2 -0
  30. package/dist/src/layouts/ox-nav-bar.js +108 -0
  31. package/dist/src/layouts/ox-nav-bar.js.map +1 -0
  32. package/dist/src/layouts/ox-snack-bar.d.ts +2 -0
  33. package/dist/src/layouts/ox-snack-bar.js +119 -0
  34. package/dist/src/layouts/ox-snack-bar.js.map +1 -0
  35. package/dist/src/reducers/layout.d.ts +13 -0
  36. package/dist/src/reducers/layout.js +62 -0
  37. package/dist/src/reducers/layout.js.map +1 -0
  38. package/dist/src/reducers/snackbar.d.ts +18 -0
  39. package/dist/src/reducers/snackbar.js +30 -0
  40. package/dist/src/reducers/snackbar.js.map +1 -0
  41. package/dist/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +14 -6
  43. package/src/actions/layout.ts +233 -0
  44. package/src/actions/snackbar.ts +60 -0
  45. package/src/components/ox-floating-overlay.ts +319 -0
  46. package/src/components/ox-resize-splitter.ts +126 -0
  47. package/src/index.ts +10 -1
  48. package/src/initializer.ts +113 -0
  49. package/src/layouts/ox-aside-bar.ts +106 -0
  50. package/src/layouts/ox-footer-bar.ts +106 -0
  51. package/src/layouts/ox-header-bar.ts +103 -0
  52. package/src/layouts/ox-nav-bar.ts +108 -0
  53. package/src/layouts/ox-snack-bar.ts +108 -0
  54. package/src/reducers/layout.ts +72 -0
  55. package/src/reducers/snackbar.ts +32 -0
  56. package/dist/src/ox-layout.d.ts +0 -45
  57. package/dist/src/ox-layout.js +0 -148
  58. package/dist/src/ox-layout.js.map +0 -1
  59. package/dist/src/ox-toolbar-style.d.ts +0 -4
  60. package/dist/src/ox-toolbar-style.js +0 -207
  61. package/dist/src/ox-toolbar-style.js.map +0 -1
  62. package/dist/src/ox-toolbar.d.ts +0 -4
  63. package/dist/src/ox-toolbar.js +0 -123
  64. package/dist/src/ox-toolbar.js.map +0 -1
  65. package/dist/stories/index.stories.d.ts +0 -33
  66. package/dist/stories/index.stories.js +0 -33
  67. package/dist/stories/index.stories.js.map +0 -1
  68. package/dist/test/ox-layout.test.d.ts +0 -1
  69. package/dist/test/ox-layout.test.js +0 -24
  70. package/dist/test/ox-layout.test.js.map +0 -1
  71. package/src/ox-layout.ts +0 -191
  72. package/src/ox-toolbar-style.ts +0 -208
  73. package/src/ox-toolbar.ts +0 -135
  74. package/stories/index.stories.ts +0 -52
  75. package/test/ox-layout.test.ts +0 -35
@@ -0,0 +1,106 @@
1
+ import '../components/ox-floating-overlay.js'
2
+ import '../components/ox-resize-splitter.js'
3
+
4
+ import { css, html, LitElement } from 'lit'
5
+ import { customElement, property, state } from 'lit/decorators.js'
6
+ import { connect } from 'pwa-helpers/connect-mixin.js'
7
+
8
+ import { Viewpart, VIEWPART_LEVEL } from '../actions/layout.js'
9
+ import store from '../initializer.js'
10
+
11
+ @customElement('ox-footer-bar')
12
+ class FooterBar extends connect(store)(LitElement) {
13
+ static styles = [
14
+ css`
15
+ :host {
16
+ display: flex;
17
+ flex-flow: column-reverse nowrap;
18
+ align-items: stretch;
19
+ position: relative;
20
+ }
21
+
22
+ *[footerbar] {
23
+ display: block;
24
+ }
25
+
26
+ @media screen and (max-width: 460px) {
27
+ :host {
28
+ padding-bottom: 0;
29
+ }
30
+ }
31
+ `
32
+ ]
33
+
34
+ @property({ type: Boolean, attribute: 'fullbleed' }) fullbleed: boolean = false
35
+
36
+ @state() viewparts: { [name: string]: Viewpart } = {}
37
+
38
+ private _startHeight: number = 0
39
+
40
+ render() {
41
+ var viewparts = this.viewparts
42
+ var footerbars = Object.keys(viewparts)
43
+ .map(name => {
44
+ return {
45
+ name,
46
+ ...viewparts[name]
47
+ }
48
+ })
49
+ .filter(viewpart => viewpart.position == 'footerbar' && (!this.fullbleed || viewpart.hovering))
50
+
51
+ footerbars = [
52
+ ...footerbars.filter(viewpart => viewpart.level == VIEWPART_LEVEL.TOPMOST),
53
+ ...footerbars.filter(viewpart => viewpart.level !== VIEWPART_LEVEL.TOPMOST)
54
+ ]
55
+
56
+ return html`
57
+ ${footerbars.map(footerbar =>
58
+ !footerbar.show
59
+ ? html``
60
+ : footerbar.hovering
61
+ ? html`
62
+ <ox-floating-overlay
63
+ .backdrop=${footerbar.backdrop}
64
+ direction="up"
65
+ .hovering=${footerbar.hovering}
66
+ .name=${footerbar.name}
67
+ .title=${footerbar.title}
68
+ .help=${footerbar.help}
69
+ .size=${footerbar.size}
70
+ .closable=${footerbar.closable}
71
+ .templateProperties=${footerbar.templateProperties}
72
+ >${footerbar.template}</ox-floating-overlay
73
+ >
74
+ `
75
+ : html`
76
+ <div footerbar>${footerbar.template}</div>
77
+ ${footerbar.resizable
78
+ ? html`
79
+ <ox-resize-splitter
80
+ @splitter-dragstart=${(e: CustomEvent) => this.resizeStart(e)}
81
+ @splitter-drag=${(e: CustomEvent) => this.resizeDrag(e)}
82
+ ></ox-resize-splitter>
83
+ `
84
+ : html``}
85
+ `
86
+ )}
87
+ `
88
+ }
89
+
90
+ resizeStart(e: CustomEvent) {
91
+ this._startHeight = ((e.target as HTMLElement)?.previousElementSibling as HTMLElement).offsetHeight
92
+ }
93
+
94
+ resizeDrag(e: CustomEvent) {
95
+ var delta = e.detail
96
+
97
+ var x = ((e.target as HTMLElement)?.previousElementSibling as HTMLElement).querySelectorAll('*')
98
+ Array.from(x).forEach(ele => {
99
+ ;(ele as HTMLElement).style.height = `${this._startHeight - delta.y}px`
100
+ })
101
+ }
102
+
103
+ stateChanged(state: any) {
104
+ this.viewparts = state.layout.viewparts || {}
105
+ }
106
+ }
@@ -0,0 +1,103 @@
1
+ import '../components/ox-floating-overlay.js'
2
+ import '../components/ox-resize-splitter.js'
3
+
4
+ import { css, html, LitElement } from 'lit'
5
+ import { customElement, property, state } from 'lit/decorators.js'
6
+ import { connect } from 'pwa-helpers/connect-mixin.js'
7
+
8
+ import { Viewpart, VIEWPART_LEVEL } from '../actions/layout.js'
9
+ import store from '../initializer.js'
10
+
11
+ @customElement('ox-header-bar')
12
+ class HeaderBar extends connect(store)(LitElement) {
13
+ static styles = [
14
+ css`
15
+ :host {
16
+ display: flex;
17
+ flex-flow: column nowrap;
18
+ align-items: stretch;
19
+
20
+ position: relative;
21
+
22
+ background-color: var(--header-bar-background-color);
23
+ }
24
+
25
+ *[headerbar] {
26
+ display: block;
27
+ }
28
+ `
29
+ ]
30
+
31
+ @property({ type: Boolean, attribute: 'fullbleed' }) fullbleed: boolean = false
32
+
33
+ @state() viewparts: { [name: string]: Viewpart } = {}
34
+
35
+ private _startHeight: number = 0
36
+
37
+ render() {
38
+ var viewparts = this.viewparts
39
+ var headerbars = Object.keys(viewparts)
40
+ .map(name => {
41
+ return {
42
+ name,
43
+ ...viewparts[name]
44
+ }
45
+ })
46
+ .filter(viewpart => viewpart.position == 'headerbar' && (!this.fullbleed || viewpart.hovering))
47
+
48
+ headerbars = [
49
+ ...headerbars.filter(viewpart => viewpart.level == VIEWPART_LEVEL.TOPMOST),
50
+ ...headerbars.filter(viewpart => viewpart.level !== VIEWPART_LEVEL.TOPMOST)
51
+ ]
52
+
53
+ return html`
54
+ ${headerbars.map(headerbar =>
55
+ !headerbar.show
56
+ ? html``
57
+ : headerbar.hovering
58
+ ? html`
59
+ <ox-floating-overlay
60
+ .backdrop=${headerbar.backdrop}
61
+ direction="down"
62
+ .hovering=${headerbar.hovering}
63
+ .name=${headerbar.name}
64
+ .title=${headerbar.title}
65
+ .help=${headerbar.help}
66
+ .size=${headerbar.size}
67
+ .closable=${headerbar.closable}
68
+ .templateProperties=${headerbar.templateProperties}
69
+ >${headerbar.template}</ox-floating-overlay
70
+ >
71
+ `
72
+ : html`
73
+ <div headerbar>${headerbar.template}</div>
74
+ ${headerbar.resizable
75
+ ? html`
76
+ <ox-resize-splitter
77
+ @splitter-dragstart=${(e: CustomEvent) => this.resizeStart(e)}
78
+ @splitter-drag=${(e: CustomEvent) => this.resizeDrag(e)}
79
+ ></ox-resize-splitter>
80
+ `
81
+ : html``}
82
+ `
83
+ )}
84
+ `
85
+ }
86
+
87
+ resizeStart(e: CustomEvent) {
88
+ this._startHeight = ((e.target as HTMLElement)?.previousElementSibling as HTMLElement).offsetHeight
89
+ }
90
+
91
+ resizeDrag(e: CustomEvent) {
92
+ var delta = e.detail
93
+
94
+ var x = ((e.target as HTMLElement)?.previousElementSibling as HTMLElement).querySelectorAll('*')
95
+ Array.from(x).forEach(ele => {
96
+ ;(ele as HTMLElement).style.height = `${this._startHeight + delta.y}px`
97
+ })
98
+ }
99
+
100
+ stateChanged(state: any) {
101
+ this.viewparts = state.layout.viewparts || {}
102
+ }
103
+ }
@@ -0,0 +1,108 @@
1
+ import '../components/ox-floating-overlay.js'
2
+ import '../components/ox-resize-splitter.js'
3
+
4
+ import { css, html, LitElement } from 'lit'
5
+ import { customElement, property, state } from 'lit/decorators.js'
6
+ import { connect } from 'pwa-helpers/connect-mixin.js'
7
+
8
+ import { ScrollbarStyles } from '@operato/styles'
9
+
10
+ import { Viewpart, VIEWPART_LEVEL } from '../actions/layout.js'
11
+ import store from '../initializer.js'
12
+
13
+ @customElement('ox-nav-bar')
14
+ class NavBar extends connect(store)(LitElement) {
15
+ static styles = [
16
+ ScrollbarStyles,
17
+ css`
18
+ :host {
19
+ display: flex;
20
+ flex-flow: row nowrap;
21
+ align-items: stretch;
22
+
23
+ position: relative;
24
+
25
+ background-color: var(--nav-bar-background-color);
26
+ }
27
+
28
+ *[navbar] {
29
+ display: flex;
30
+ flex-direction: row;
31
+ }
32
+ `
33
+ ]
34
+
35
+ @property({ type: Boolean, attribute: 'fullbleed' }) fullbleed: boolean = false
36
+
37
+ @state() viewparts: { [name: string]: Viewpart } = {}
38
+
39
+ private _startWidth: number = 0
40
+
41
+ render() {
42
+ var viewparts = this.viewparts
43
+ var navbars = Object.keys(viewparts)
44
+ .map(name => {
45
+ return {
46
+ name,
47
+ ...viewparts[name]
48
+ }
49
+ })
50
+ .filter(viewpart => viewpart.position == 'navbar' && (!this.fullbleed || viewpart.hovering))
51
+
52
+ navbars = [
53
+ ...navbars.filter(viewpart => viewpart.level == VIEWPART_LEVEL.TOPMOST),
54
+ ...navbars.filter(viewpart => viewpart.level !== VIEWPART_LEVEL.TOPMOST)
55
+ ]
56
+
57
+ return html`
58
+ ${navbars.map(navbar =>
59
+ !navbar.show
60
+ ? html``
61
+ : navbar.hovering
62
+ ? html`
63
+ <ox-floating-overlay
64
+ .backdrop=${navbar.backdrop}
65
+ direction="right"
66
+ .hovering=${navbar.hovering}
67
+ .name=${navbar.name}
68
+ .title=${navbar.title}
69
+ .help=${navbar.help}
70
+ .size=${navbar.size}
71
+ .closable=${navbar.closable}
72
+ .templateProperties=${navbar.templateProperties}
73
+ >${navbar.template}</ox-floating-overlay
74
+ >
75
+ `
76
+ : html`
77
+ <div navbar>${navbar.template}</div>
78
+ ${navbar.resizable
79
+ ? html`
80
+ <ox-resize-splitter
81
+ @splitter-dragstart=${(e: CustomEvent) => this.resizeStart(e)}
82
+ @splitter-drag=${(e: CustomEvent) => this.resizeDrag(e)}
83
+ vertical
84
+ ></ox-resize-splitter>
85
+ `
86
+ : html``}
87
+ `
88
+ )}
89
+ `
90
+ }
91
+
92
+ resizeStart(e: CustomEvent) {
93
+ this._startWidth = ((e.target as HTMLElement)?.previousElementSibling as HTMLElement).offsetWidth
94
+ }
95
+
96
+ resizeDrag(e: CustomEvent) {
97
+ var delta = e.detail
98
+
99
+ var x = ((e.target as HTMLElement)?.previousElementSibling as HTMLElement).querySelectorAll('*')
100
+ Array.from(x).forEach(ele => {
101
+ ;(ele as HTMLElement).style.width = `${this._startWidth + delta.x}px`
102
+ })
103
+ }
104
+
105
+ stateChanged(state: any) {
106
+ this.viewparts = state.layout.viewparts || {}
107
+ }
108
+ }
@@ -0,0 +1,108 @@
1
+ import '@material/mwc-button'
2
+ import '@material/mwc-icon'
3
+
4
+ import { css, html, LitElement } from 'lit'
5
+ import { customElement, property } from 'lit/decorators.js'
6
+ import { connect } from 'pwa-helpers/connect-mixin.js'
7
+
8
+ import { CLOSE_SNACKBAR } from '../actions/snackbar'
9
+ import store from '../initializer.js'
10
+
11
+ @customElement('ox-snack-bar')
12
+ class SnackBar extends connect(store)(LitElement) {
13
+ static styles = css`
14
+ :host {
15
+ display: block;
16
+ position: fixed;
17
+ top: 100%;
18
+ left: 0;
19
+ right: 0;
20
+ padding: 12px;
21
+ background-color: black;
22
+ color: white;
23
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
24
+ text-align: center;
25
+ will-change: transform;
26
+ transform: translate3d(0, 0, 0);
27
+ transition-property: visibility, transform;
28
+ transition-duration: 0.2s;
29
+ visibility: hidden;
30
+ }
31
+
32
+ :host([active]) {
33
+ visibility: visible;
34
+ transform: translate3d(0, -100%, 0);
35
+ }
36
+
37
+ mwc-icon {
38
+ --mdc-icon-size: 1.2em;
39
+ vertical-align: middle;
40
+ max-width: 20px;
41
+ }
42
+
43
+ mwc-button {
44
+ display: block;
45
+ }
46
+
47
+ .info {
48
+ color: green;
49
+ }
50
+
51
+ .warn {
52
+ color: yellow;
53
+ }
54
+
55
+ .error {
56
+ color: red;
57
+ }
58
+
59
+ @media (min-width: 460px) {
60
+ :host {
61
+ width: 320px;
62
+ margin: auto;
63
+ }
64
+ }
65
+ `
66
+
67
+ @property({ type: String }) level: 'info' | 'warn' | 'error' = 'info'
68
+ @property({ type: String }) message: string = ''
69
+ @property({ type: Boolean, reflect: true }) active: boolean = false
70
+ @property({ type: Object }) action: any
71
+
72
+ render() {
73
+ return html`
74
+ <span>
75
+ <mwc-icon class=${this.level}
76
+ >${this.level == 'info'
77
+ ? html` notification_important `
78
+ : this.level == 'warn'
79
+ ? html` warning `
80
+ : this.level == 'error'
81
+ ? html` error `
82
+ : html``}</mwc-icon
83
+ >
84
+ </span>
85
+ <span>${this.message}</span>
86
+ ${this.action && this.action.label
87
+ ? html`
88
+ <mwc-button
89
+ @click=${() => {
90
+ store.dispatch({ type: CLOSE_SNACKBAR })
91
+ this.action.callback()
92
+ }}
93
+ >${this.action.label}</mwc-button
94
+ >
95
+ `
96
+ : html``}
97
+ `
98
+ }
99
+
100
+ stateChanged(state: any) {
101
+ var { level, message, snackbarOpened, action } = state.snackbar || {}
102
+
103
+ this.level = level
104
+ this.message = message
105
+ this.active = snackbarOpened
106
+ this.action = action
107
+ }
108
+ }
@@ -0,0 +1,72 @@
1
+ import { APPEND_VIEWPART, REMOVE_VIEWPART, UPDATE_VIEWPART, UPDATE_VIEWPORT_WIDTH, Viewpart } from '../actions/layout'
2
+
3
+ const INITIAL_STATE: {
4
+ viewparts: { [name: string]: Viewpart }
5
+ width: 'WIDE' | 'NARROW'
6
+ } = {
7
+ viewparts: {},
8
+ width: 'WIDE'
9
+ }
10
+
11
+ const layout = (state = INITIAL_STATE, action: any) => {
12
+ let viewparts = { ...state.viewparts }
13
+
14
+ switch (action.type) {
15
+ case APPEND_VIEWPART:
16
+ return {
17
+ ...state,
18
+ viewparts: {
19
+ ...state.viewparts,
20
+ [action.name]: {
21
+ ...action.viewpart,
22
+ position: action.position
23
+ }
24
+ }
25
+ }
26
+
27
+ case REMOVE_VIEWPART:
28
+ delete viewparts[action.name]
29
+ return {
30
+ ...state,
31
+ viewparts
32
+ }
33
+
34
+ case UPDATE_VIEWPART:
35
+ let viewpart = viewparts[action.name]
36
+ if (!viewpart) {
37
+ return state
38
+ }
39
+ let override = action.override || {}
40
+
41
+ if (viewpart.temporary && override.show === false) {
42
+ /* temporary viewpart는 show=false가 될 때, 제거되어야 한다. */
43
+ delete viewparts[action.name]
44
+ return {
45
+ ...state,
46
+ viewparts
47
+ }
48
+ } else {
49
+ return {
50
+ ...state,
51
+ viewparts: {
52
+ ...state.viewparts,
53
+ [action.name]: {
54
+ ...viewpart,
55
+ ...action.override
56
+ }
57
+ }
58
+ }
59
+ }
60
+
61
+ case UPDATE_VIEWPORT_WIDTH:
62
+ return {
63
+ ...state,
64
+ width: action.width
65
+ }
66
+
67
+ default:
68
+ return state
69
+ }
70
+ }
71
+
72
+ export default layout
@@ -0,0 +1,32 @@
1
+ import { CLOSE_SNACKBAR, OPEN_SNACKBAR, SnackbarAction } from '../actions/snackbar.js'
2
+
3
+ const INITIAL_STATE = {
4
+ snackbarOpened: false,
5
+ level: '',
6
+ message: '',
7
+ action: {}
8
+ }
9
+
10
+ const snackbar = (state = INITIAL_STATE, action: SnackbarAction) => {
11
+ switch (action.type) {
12
+ case OPEN_SNACKBAR:
13
+ return {
14
+ ...state,
15
+ snackbarOpened: true,
16
+ level: action.level || 'info',
17
+ message: action.message,
18
+ action: {
19
+ ...action.action
20
+ }
21
+ }
22
+ case CLOSE_SNACKBAR:
23
+ return {
24
+ ...state,
25
+ snackbarOpened: false
26
+ }
27
+ default:
28
+ return state
29
+ }
30
+ }
31
+
32
+ export default snackbar
@@ -1,45 +0,0 @@
1
- import { LitElement } from 'lit';
2
- export declare class OxLayout extends LitElement {
3
- static styles: import("lit").CSSResult[];
4
- _parent?: Element;
5
- render(): import("lit-html").TemplateResult<1>;
6
- protected _onfocusout: (e: FocusEvent) => void;
7
- protected _onkeydown: (e: KeyboardEvent) => void;
8
- protected _onkeyup: (e: KeyboardEvent) => void;
9
- protected _onclick: (e: MouseEvent) => void;
10
- protected _onclose: (e: Event) => void;
11
- protected _oncollapse: (e: Event) => void;
12
- protected _onwindowblur: (e: Event) => void;
13
- connectedCallback(): void;
14
- /**
15
- * Configuration for opening ox-layout
16
- *
17
- * @typedef {Object} PopupOpenOptions
18
- * @property {HTMLTemplate} template HTMLTemplate to be displayed inside the layout
19
- * @property {Number} top The position-top where the pop-up will be displayed
20
- * @property {Number} left The position-left where the pop-up will be displayed
21
- * @property {HTMLElement} parent Popup's parent element
22
- */
23
- /**
24
- * Open Popup
25
- *
26
- * @param {PopupOpenOptions}
27
- */
28
- static open({ template, top, left, right, bottom, parent }: {
29
- template: unknown;
30
- top?: number;
31
- left?: number;
32
- right?: number;
33
- bottom?: number;
34
- parent?: Element | null;
35
- }): void;
36
- open({ left, top, right, bottom, silent }: {
37
- left?: number;
38
- top?: number;
39
- right?: number;
40
- bottom?: number;
41
- silent?: boolean;
42
- }): void;
43
- guaranteeFocus(): void;
44
- close(): void;
45
- }