@operato/context 8.0.0-alpha.8 → 8.0.0-beta.1

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 (35) hide show
  1. package/CHANGELOG.md +181 -0
  2. package/dist/src/layouts/ox-context-page-toolbar.js +2 -0
  3. package/dist/src/layouts/ox-context-page-toolbar.js.map +1 -1
  4. package/dist/src/tools/ox-page-action-context-bar.js +2 -0
  5. package/dist/src/tools/ox-page-action-context-bar.js.map +1 -1
  6. package/dist/src/tools/ox-page-title-bar.js +1 -0
  7. package/dist/src/tools/ox-page-title-bar.js.map +1 -1
  8. package/dist/src/tools/ox-title-bar.js +3 -2
  9. package/dist/src/tools/ox-title-bar.js.map +1 -1
  10. package/dist/tsconfig.tsbuildinfo +1 -1
  11. package/package.json +16 -16
  12. package/themes/calendar-theme.css +3 -1
  13. package/.editorconfig +0 -29
  14. package/.storybook/main.js +0 -3
  15. package/.storybook/preview.js +0 -52
  16. package/.storybook/server.mjs +0 -8
  17. package/src/index.ts +0 -1
  18. package/src/layouts/ox-context-page-toolbar.ts +0 -119
  19. package/src/layouts/ox-context-toolbar.ts +0 -208
  20. package/src/styles/ox-context-toolbar-overlay-style.ts +0 -58
  21. package/src/tools/ox-page-action-context-bar.ts +0 -220
  22. package/src/tools/ox-page-action-overlay-template.ts +0 -111
  23. package/src/tools/ox-page-title-bar.ts +0 -124
  24. package/src/tools/ox-title-bar.ts +0 -120
  25. package/stories/ox-context-page-toolbar-select-buttons.stories.ts +0 -166
  26. package/stories/ox-context-page-toolbar-select.stories.ts +0 -129
  27. package/stories/ox-context-page-toolbar.stories.ts +0 -130
  28. package/stories/ox-context-toolbar-complex.stories.ts +0 -181
  29. package/stories/ox-context-toolbar-cooldown.stories.ts +0 -112
  30. package/stories/ox-context-toolbar-empty.stories.ts +0 -111
  31. package/stories/ox-context-toolbar-overflow.stories.ts +0 -165
  32. package/stories/ox-context-toolbar.stories.ts +0 -221
  33. package/tsconfig.json +0 -24
  34. package/web-dev-server.config.mjs +0 -27
  35. package/web-test-runner.config.mjs +0 -41
@@ -1,111 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import '@material/web/chips/assist-chip.js'
3
-
4
- import { css, html, LitElement } from 'lit'
5
- import { customElement, property, query, state } from 'lit/decorators.js'
6
- import { connect } from 'pwa-helpers'
7
-
8
- import { store } from '@operato/shell'
9
- import { ButtonContainerStyles, ScrollbarStyles } from '@operato/styles'
10
- import { sleep } from '@operato/utils'
11
-
12
- import { ContextToolbarOverlayStyle } from '../styles/ox-context-toolbar-overlay-style.js'
13
-
14
- @customElement('ox-page-action-overlay-template')
15
- export class PageActionOverlayTemplate extends connect(store)(LitElement) {
16
- static get styles() {
17
- return [
18
- ScrollbarStyles,
19
- ButtonContainerStyles,
20
- ContextToolbarOverlayStyle,
21
- css`
22
- :host {
23
- display: flex;
24
- flex-wrap: wrap;
25
- gap: var(--spacing-small);
26
- align-items: center;
27
- }
28
-
29
- :host *:focus {
30
- outline: none;
31
- }
32
-
33
- md-icon[working] {
34
- animation: rotate 1s linear infinite;
35
- }
36
-
37
- md-assist-chip[icon-only] {
38
- --md-assist-chip-trailing-space: 0;
39
- }
40
-
41
- @keyframes rotate {
42
- from {
43
- transform: rotate(0deg);
44
- }
45
- to {
46
- transform: rotate(360deg);
47
- }
48
- }
49
- `
50
- ]
51
- }
52
-
53
- @state() private actions: any[] = []
54
-
55
- render() {
56
- return html`
57
- ${this.actions.map(($action, idx) => {
58
- let { type, title, icon, action, select, href, emphasis } = $action as any
59
- let { raised, danger } = emphasis || {}
60
-
61
- return type == 'text'
62
- ? html` <span>${title}</span> `
63
- : type == 'select' || (select && select.length > 0)
64
- ? html`
65
- <select @change=${action}>
66
- ${select.map((option: any) => html` <option>${option}</option> `)}
67
- </select>
68
- `
69
- : type == 'link'
70
- ? html` <a href=${href}>${title}</a> `
71
- : html`
72
- <md-assist-chip
73
- ?icon-only=${type == 'icon' || !title}
74
- ?elevated=${raised}
75
- ?danger=${danger}
76
- label=${title}
77
- @click=${async (e: MouseEvent) => {
78
- /* all actions should be bloked for a second */
79
- const button = e.currentTarget as any
80
- const iconElement = button.querySelector('[slot="icon"]')
81
- if (iconElement) {
82
- iconElement.textContent = 'refresh'
83
- iconElement.setAttribute('working', true)
84
- }
85
- button.disabled = true
86
-
87
- try {
88
- await action()
89
- } finally {
90
- await sleep(1000) /* waiting for additionla 1 second */
91
-
92
- /* because icon can be changed after sleep, don't use closure 'icon'. */
93
- if (iconElement) {
94
- iconElement.textContent = this.actions[idx]?.icon
95
- iconElement.removeAttribute('working')
96
- }
97
- button.disabled = false
98
- }
99
- }}
100
- >
101
- <md-icon slot="icon">${icon || 'done_all'}</md-icon>
102
- </md-assist-chip>
103
- `
104
- })}
105
- `
106
- }
107
-
108
- stateChanged(state: any) {
109
- this.actions = state.route?.context?.actions?.filter((action: any) => !!action) || []
110
- }
111
- }
@@ -1,124 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import '@operato/input/ox-input-search.js'
3
-
4
- import { css, html, LitElement } from 'lit'
5
- import { customElement, state } from 'lit/decorators.js'
6
- import { connect } from 'pwa-helpers'
7
-
8
- import { openHelp } from '@operato/help'
9
- import { store } from '@operato/shell'
10
- import { isMobileDevice } from '@operato/utils'
11
-
12
- @customElement('ox-page-title-bar')
13
- export class PageTitleBar extends connect(store)(LitElement) {
14
- static styles = [
15
- css`
16
- :host {
17
- display: flex;
18
- align-items: center;
19
-
20
- --help-icon-color: var(--md-sys-color-on-surface);
21
- --help-icon-hover-color: var(--md-sys-color-on-surface-variant);
22
- --help-icon-opacity: 0.2;
23
- --help-icon-size: 20px;
24
-
25
- --md-icon-size: 20px;
26
-
27
- --input-search-padding: var(--spacing-small);
28
- --input-search-font: normal 14px var(--theme-font);
29
- }
30
-
31
- [titler] {
32
- display: flex;
33
- padding: var(--spacing-small);
34
- padding-top: var(--spacing-medium);
35
- font: var(--context-toolbar-title);
36
- color: var(--title-text-color);
37
- }
38
-
39
- [titler] > * {
40
- align-self: center;
41
- }
42
-
43
- [help] {
44
- opacity: var(--help-icon-opacity);
45
- font-size: var(--help-icon-size);
46
- color: var(--help-icon-color);
47
- }
48
-
49
- [help]:hover {
50
- cursor: help;
51
- opacity: var(--help-icon-hover-opacity);
52
- color: var(--help-icon-hover-color);
53
- }
54
-
55
- [search] [help] {
56
- color: var(--md-sys-color-on-secondary-container);
57
- }
58
-
59
- [search] {
60
- display: flex;
61
- justify-content: space-between;
62
- align-items: center;
63
-
64
- align-self: center;
65
- color: var(--md-sys-color-primary);
66
- background-color: var(--md-sys-color-on-primary);
67
- border-radius: var(--md-sys-shape-corner-full);
68
- margin-left: auto;
69
- padding: 0 var(--spacing-medium);
70
- }
71
-
72
- [search] > * {
73
- align-self: center;
74
- }
75
- `
76
- ]
77
-
78
- @state() private context: any
79
-
80
- mobile = isMobileDevice()
81
-
82
- render() {
83
- var { search, filter, title, help } = this.context || ({} as any)
84
- var { value = '', handler: searchHandler, placeholder = '', autofocus = true } = search || ({} as any)
85
- const { handler: filterHandler } = filter || ({} as any)
86
- const { icon, text = title } = typeof title === 'object' ? title : ({} as any)
87
- const searchable = typeof searchHandler == 'function'
88
- const filterable = typeof filterHandler == 'function'
89
-
90
- if (this.mobile && searchable && title) {
91
- placeholder ||= title
92
- title = ''
93
- }
94
-
95
- return html`
96
- ${title ? html` <div titler>${icon ? html`<md-icon>${icon}</md-icon>&nbsp;` : html``}${text}</div> ` : html``}
97
- ${help && title ? html` &nbsp;<md-icon @click=${(e: MouseEvent) => openHelp(help)} help>help</md-icon> ` : html``}
98
- ${searchable || filterable
99
- ? html`
100
- <div search>
101
- ${searchable
102
- ? html` <ox-input-search
103
- .placeholder=${placeholder}
104
- .value=${value || ''}
105
- ?autofocus=${autofocus}
106
- @change=${(e: Event) => {
107
- searchHandler((e.target as any).value)
108
- }}
109
- ></ox-input-search>`
110
- : html``}
111
- ${!title && help && searchable
112
- ? html`<md-icon @click=${(e: MouseEvent) => openHelp(help)} help>help</md-icon>`
113
- : html``}
114
- ${filterable ? html`<md-icon @click=${(e: MouseEvent) => filterHandler()}>unfold_more</md-icon>` : html``}
115
- </div>
116
- `
117
- : html``}
118
- `
119
- }
120
-
121
- stateChanged(state: any) {
122
- this.context = state.route.context
123
- }
124
- }
@@ -1,120 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import '@operato/input/ox-input-search.js'
3
-
4
- import { css, html, LitElement } from 'lit'
5
- import { customElement, state } from 'lit/decorators.js'
6
- import { connect } from 'pwa-helpers'
7
-
8
- import { openHelp } from '@operato/help'
9
- import { store } from '@operato/shell'
10
-
11
- @customElement('ox-title-bar')
12
- export class TitleBar extends connect(store)(LitElement) {
13
- static styles = [
14
- css`
15
- :host {
16
- display: flex;
17
- align-items: center;
18
-
19
- --help-icon-color: var(--md-sys-color-primary);
20
- --help-icon-hover-color: var(--md-sys-color-primary);
21
- --help-icon-opacity: 0.2;
22
- --help-icon-size: 20px;
23
-
24
- --md-icon-size: 20px;
25
-
26
- --input-search-padding: var(--spacing-medium);
27
- --input-search-focus-border-bottom: none;
28
- --input-search-font: normal 16px var(--theme-font);
29
- }
30
-
31
- [titler] {
32
- display: flex;
33
- font: var(--context-toolbar-title);
34
- }
35
-
36
- [titler] > * {
37
- align-self: center;
38
- }
39
-
40
- [help] {
41
- opacity: var(--help-icon-opacity);
42
- font-size: var(--help-icon-size);
43
- color: var(--help-icon-color);
44
- }
45
-
46
- [help]:hover {
47
- cursor: help;
48
- opacity: var(--help-icon-hover-opacity);
49
- color: var(--help-icon-hover-color);
50
- }
51
-
52
- [search] {
53
- display: flex;
54
- justify-content: space-between;
55
- align-items: center;
56
-
57
- align-self: center;
58
- color: var(--md-sys-color-primary);
59
- background-color: var(--md-sys-color-on-primary);
60
- border-radius: var(--md-sys-shape-corner-full);
61
- padding: 0 var(--spacing-medium);
62
- }
63
-
64
- [search] > * {
65
- align-self: center;
66
- }
67
-
68
- ox-input-search {
69
- color: var(--md-sys-color-primary);
70
- background-color: transparent;
71
- border-radius: var(--md-sys-shape-corner-full);
72
- }
73
- `
74
- ]
75
-
76
- @state() private context: any
77
-
78
- render() {
79
- var { search, filter, title, help } = this.context || ({} as any)
80
- var { value = '', handler: searchHandler, placeholder = '', autofocus = true } = search || ({} as any)
81
- const { handler: filterHandler } = filter || ({} as any)
82
- const { icon, text = title } = typeof title === 'object' ? title : ({} as any)
83
- const searchable = typeof searchHandler == 'function'
84
- const filterable = typeof filterHandler == 'function'
85
-
86
- if (searchable && title) {
87
- placeholder ||= text
88
- title = ''
89
- }
90
-
91
- return html`
92
- ${title ? html` <div titler>${icon ? html`<md-icon>${icon}</md-icon>&nbsp;` : html``}${text}</div> ` : html``}
93
- ${help && title ? html` &nbsp;<md-icon @click=${(e: MouseEvent) => openHelp(help)} help>help</md-icon> ` : html``}
94
- ${searchable || filterable
95
- ? html`
96
- <div search>
97
- ${searchable
98
- ? html` <ox-input-search
99
- .placeholder=${placeholder}
100
- .value=${value || ''}
101
- ?autofocus=${autofocus}
102
- @change=${(e: Event) => {
103
- searchHandler((e.target as any).value)
104
- }}
105
- ></ox-input-search>`
106
- : html``}
107
- ${!title && help && searchable
108
- ? html`<md-icon @click=${(e: MouseEvent) => openHelp(help)} help>help</md-icon>`
109
- : html``}
110
- ${filterable ? html`<md-icon @click=${(e: MouseEvent) => filterHandler()}>tune</md-icon>` : html``}
111
- </div>
112
- `
113
- : html``}
114
- `
115
- }
116
-
117
- stateChanged(state: any) {
118
- this.context = state.route.context
119
- }
120
- }
@@ -1,166 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import '../src/layouts/ox-context-page-toolbar.js'
3
- import '../src/tools/ox-page-action-context-bar.js'
4
- import '@operato/input/ox-input-select-buttons.js'
5
- import { CommonHeaderStyles } from '@operato/styles'
6
- import { TOOL_POSITION } from '@operato/layout'
7
-
8
- import '@operato/styles'
9
-
10
- import { css, html, render, TemplateResult } from 'lit'
11
- import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles'
12
-
13
- export default {
14
- title: 'ox-context-page-toolbar select buttons',
15
- component: 'ox-context-page-toolbar',
16
- argTypes: {
17
- label: { control: 'string' }
18
- }
19
- }
20
-
21
- interface Story<T> {
22
- (args: T): TemplateResult
23
- args?: Partial<T>
24
- argTypes?: Record<string, unknown>
25
- }
26
-
27
- interface ArgTypes {
28
- label?: string
29
- }
30
-
31
- const Template: Story<ArgTypes> = ({ label = '' }: ArgTypes) => html`
32
- <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet" />
33
-
34
- <link href="/themes/light.css" rel="stylesheet" />
35
- <link href="/themes/dark.css" rel="stylesheet" />
36
- <link href="/themes/spacing.css" rel="stylesheet" />
37
-
38
- <link
39
- href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL@20..48,100..700,0..1"
40
- rel="stylesheet"
41
- />
42
- <link
43
- href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL@20..48,100..700,0..1"
44
- rel="stylesheet"
45
- />
46
- <link
47
- href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp:opsz,wght,FILL@20..48,100..700,0..1"
48
- rel="stylesheet"
49
- />
50
-
51
- <style>
52
- ${MDTypeScaleStyles.cssText}
53
- </style>
54
-
55
- <style>
56
- .container {
57
- height: 500px;
58
- text-align: center;
59
- padding: 20px;
60
- background-color: var(--md-sys-color-primary-container);
61
- color: var(--md-sys-color-on-primary-container);
62
-
63
- padding: 20px;
64
- }
65
-
66
- ox-buttons-radio {
67
- padding: 20px;
68
- }
69
- </style>
70
-
71
- <div class="container md-typescale-body-large-prominent">
72
- <div class="header">
73
- <div class="title">${label}</div>
74
-
75
- <div class="filters">
76
- <label>Filter-X</label><input type="text" name="name" />
77
- <ox-input-select-buttons
78
- @change=${(e: Event) => {
79
- console.log((e.target as HTMLInputElement).value)
80
- }}
81
- name="wearables"
82
- .value=${'Gloves'}
83
- .options=${[
84
- { display: 'SHOOSE', value: 'Shoose' },
85
- { display: 'CHOTHES', value: 'Clothes' },
86
- { display: 'GLOVES', value: 'Gloves' }
87
- ]}
88
- multiple
89
- ></ox-input-select-buttons>
90
- </div>
91
-
92
- <ox-context-page-toolbar
93
- class="actions"
94
- .tools=${[
95
- {
96
- position: TOOL_POSITION.FRONT,
97
- template: html` <md-icon>download</md-icon> `,
98
- context: 'exportable'
99
- },
100
- {
101
- position: TOOL_POSITION.FRONT,
102
- template: html` <md-icon>upload</md-icon> `,
103
- context: 'importable'
104
- },
105
- {
106
- position: TOOL_POSITION.CENTER,
107
- template: html`<ox-page-action-context-bar
108
- .actions=${[
109
- {
110
- title: 'save',
111
- action: () => {},
112
- icon: 'save'
113
- },
114
- {
115
- title: 'copy',
116
- action: () => {},
117
- icon: 'content_copy',
118
- emphasis: {
119
- outlined: true
120
- }
121
- },
122
- {
123
- title: 'edit',
124
- action: () => {},
125
- icon: 'content_copy',
126
- emphasis: {
127
- outlined: true
128
- }
129
- },
130
- {
131
- title: 'hoppaang',
132
- action: () => {},
133
- icon: '',
134
- emphasis: {
135
- outlined: true
136
- }
137
- },
138
- {
139
- title: 'delete',
140
- action: () => {},
141
- icon: 'delete',
142
- emphasis: {
143
- danger: true,
144
- filled: true
145
- }
146
- }
147
- ]}
148
- ></ox-page-action-context-bar>`
149
- }
150
- ]}
151
- .context=${{
152
- exportable: true,
153
- importable: true,
154
- toolbar: false
155
- }}
156
- }
157
- >
158
- </ox-context-page-toolbar>
159
- </div>
160
- </div>
161
- `
162
-
163
- export const Regular = Template.bind({})
164
- Regular.args = {
165
- label: 'common header styles'
166
- }
@@ -1,129 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import '../src/layouts/ox-context-page-toolbar.js'
3
- import '../src/tools/ox-page-action-context-bar.js'
4
- import { TOOL_POSITION } from '@operato/layout'
5
- import { sleep } from '@operato/utils'
6
-
7
- import '@operato/styles'
8
-
9
- import { css, html, render, TemplateResult } from 'lit'
10
- import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles'
11
-
12
- export default {
13
- title: 'ox-context-page-toolbar-select',
14
- component: 'ox-context-page-toolbar',
15
- argTypes: {
16
- label: { control: 'string' }
17
- }
18
- }
19
-
20
- interface Story<T> {
21
- (args: T): TemplateResult
22
- args?: Partial<T>
23
- argTypes?: Record<string, unknown>
24
- }
25
-
26
- interface ArgTypes {
27
- label?: string
28
- }
29
-
30
- const Template: Story<ArgTypes> = ({ label = '' }: ArgTypes) => html`
31
- <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet" />
32
-
33
- <link href="/themes/light.css" rel="stylesheet" />
34
- <link href="/themes/dark.css" rel="stylesheet" />
35
- <link href="/themes/spacing.css" rel="stylesheet" />
36
-
37
- <link
38
- href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL@20..48,100..700,0..1"
39
- rel="stylesheet"
40
- />
41
- <link
42
- href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL@20..48,100..700,0..1"
43
- rel="stylesheet"
44
- />
45
- <link
46
- href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp:opsz,wght,FILL@20..48,100..700,0..1"
47
- rel="stylesheet"
48
- />
49
-
50
- <style>
51
- ${MDTypeScaleStyles.cssText}
52
- </style>
53
-
54
- <style>
55
- .container {
56
- height: 500px;
57
- text-align: center;
58
- padding: 20px;
59
- background-color: var(--md-sys-color-primary-container);
60
- color: var(--md-sys-color-on-primary-container);
61
-
62
- padding: 20px;
63
- }
64
-
65
- ox-buttons-radio {
66
- padding: 20px;
67
- }
68
- </style>
69
-
70
- <div class="container md-typescale-body-large-prominent">
71
- <div class="header">
72
- <div class="title">${label}</div>
73
-
74
- <div class="filters"><label>Filter</label><input type="text" /></div>
75
-
76
- <ox-context-page-toolbar
77
- class="actions"
78
- .tools=${[
79
- {
80
- position: TOOL_POSITION.FRONT,
81
- template: html` <md-icon>download</md-icon> `,
82
- context: 'exportable'
83
- },
84
- {
85
- position: TOOL_POSITION.FRONT,
86
- template: html` <md-icon>upload</md-icon> `,
87
- context: 'importable'
88
- },
89
- {
90
- position: TOOL_POSITION.CENTER,
91
- template: html`<ox-page-action-context-bar
92
- .actions=${[
93
- {
94
- type: 'icon',
95
- title: 'favorite',
96
- icon: 'favorite',
97
- action: async () => {
98
- await sleep(1000)
99
- }
100
- },
101
- {
102
- title: 'smile',
103
- action: () => {},
104
- select: ['', 'delete', 'hahaha', 'hohoho']
105
- },
106
- {
107
- title: 'save',
108
- action: () => {},
109
- icon: 'save'
110
- }
111
- ]}
112
- ></ox-page-action-context-bar>`
113
- }
114
- ]}
115
- .context=${{
116
- exportable: true,
117
- importable: true,
118
- toolbar: false
119
- }}
120
- >
121
- </ox-context-page-toolbar>
122
- </div>
123
- </div>
124
- `
125
-
126
- export const Regular = Template.bind({})
127
- Regular.args = {
128
- label: 'common header styles'
129
- }