@operato/shell 2.0.0-alpha.0 → 2.0.0-alpha.100
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 +248 -0
- package/demo/index.html +14 -3
- package/dist/src/actions/busy.js.map +1 -1
- package/dist/src/actions/route.d.ts +27 -4
- package/dist/src/actions/route.js +35 -6
- package/dist/src/actions/route.js.map +1 -1
- package/dist/src/app/app-style.js +12 -4
- package/dist/src/app/app-style.js.map +1 -1
- package/dist/src/app/app.d.ts +10 -5
- package/dist/src/app/app.js +27 -15
- package/dist/src/app/app.js.map +1 -1
- package/dist/src/app/pages/page-404.d.ts +1 -1
- package/dist/src/app/pages/page-404.js +5 -5
- package/dist/src/app/pages/page-404.js.map +1 -1
- package/dist/src/app/pages/page-view.d.ts +58 -0
- package/dist/src/app/pages/page-view.js +52 -1
- package/dist/src/app/pages/page-view.js.map +1 -1
- package/dist/src/custom-alert.d.ts +23 -0
- package/dist/src/custom-alert.js +26 -0
- package/dist/src/custom-alert.js.map +1 -0
- package/dist/src/entries/public/home.d.ts +2 -3
- package/dist/src/entries/public/home.js +17 -16
- package/dist/src/entries/public/home.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/store.js +8 -0
- package/dist/src/store.js.map +1 -1
- package/dist/stories/app.stories.d.ts +22 -0
- package/dist/stories/app.stories.js +38 -0
- package/dist/stories/app.stories.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +19 -19
- package/src/actions/busy.ts +1 -1
- package/src/actions/route.ts +35 -6
- package/src/app/app-style.ts +12 -4
- package/src/app/app.ts +49 -16
- package/src/app/pages/page-404.ts +5 -5
- package/src/app/pages/page-view.ts +63 -1
- package/src/custom-alert.ts +43 -0
- package/src/entries/public/home.ts +17 -16
- package/src/index.ts +1 -0
- package/src/store.ts +9 -0
- package/stories/app.stories.ts +51 -0
- package/themes/app-theme.css +145 -0
- package/yarn-error.log +4 -5
package/src/actions/route.ts
CHANGED
@@ -4,12 +4,17 @@ import { HOMEPAGE, UPDATE_PAGE } from '../actions/const'
|
|
4
4
|
import { store } from '../store'
|
5
5
|
|
6
6
|
/**
|
7
|
+
* Navigate to a page using one of two methods:
|
8
|
+
* 1. Using a page link: <a href='page'>goto page</a> (equivalent to route(page))
|
9
|
+
* 2. Using the navigate('page') function.
|
10
|
+
*
|
7
11
|
* 페이지를 이동하는 방법으로는 다음 두가지가 있다.
|
8
12
|
* 1. page link를 사용하는 방법 <a href='page'>goto page</a>
|
9
13
|
* 이 방법은 route(page)와 동일하다.
|
10
14
|
* 2. navigate('page')를 사용하는 방법
|
11
15
|
*
|
12
|
-
* @param
|
16
|
+
* @param location - The path of the page to navigate to.
|
17
|
+
* @param replace - Optional. If true, replaces the current page in the browser's history.
|
13
18
|
*/
|
14
19
|
export const navigate = (location: string, replace?: boolean) => {
|
15
20
|
if (replace) history.replaceState(history.state, '', location)
|
@@ -18,6 +23,12 @@ export const navigate = (location: string, replace?: boolean) => {
|
|
18
23
|
window.dispatchEvent(new Event('popstate'))
|
19
24
|
}
|
20
25
|
|
26
|
+
/**
|
27
|
+
* Navigate to a page with optional query parameters, and dispatch a Redux action to load the page.
|
28
|
+
*
|
29
|
+
* @param pathInfo - Object containing pathname, search, and optional params.
|
30
|
+
* @param dispatch - Redux dispatch function.
|
31
|
+
*/
|
21
32
|
export const navigateWithSilence =
|
22
33
|
({ pathname: path, search, params }: { pathname: string; search?: string; params?: { [key: string]: any } }) =>
|
23
34
|
(dispatch: any) => {
|
@@ -42,7 +53,13 @@ export const navigateWithSilence =
|
|
42
53
|
dispatch(loadPage(page, id, params))
|
43
54
|
}
|
44
55
|
|
45
|
-
|
56
|
+
/**
|
57
|
+
* Preload a page by performing any necessary preprocessing before loading.
|
58
|
+
*
|
59
|
+
* @param page - The page to preload.
|
60
|
+
* @returns - The new page path or routing result after preprocessing.
|
61
|
+
*/
|
62
|
+
const _preLoadPage = async (page: any) => {
|
46
63
|
/*
|
47
64
|
* _preLoadPage 에서는 page를 load하기 전처리를 수행한다.
|
48
65
|
* 예를 들면, page dynamic import 또는 page re-routing
|
@@ -53,8 +70,8 @@ const _preLoadPage = (page: any) => {
|
|
53
70
|
var modules = state.app.modules
|
54
71
|
if (modules) {
|
55
72
|
for (let i = modules.length - 1; i >= 0; i--) {
|
56
|
-
let
|
57
|
-
let _page =
|
73
|
+
let module = modules[i]
|
74
|
+
let _page = module.route && (await module.route(page, module))
|
58
75
|
if (_page) {
|
59
76
|
return _page
|
60
77
|
}
|
@@ -62,8 +79,15 @@ const _preLoadPage = (page: any) => {
|
|
62
79
|
}
|
63
80
|
}
|
64
81
|
|
65
|
-
|
66
|
-
|
82
|
+
/**
|
83
|
+
* Load a page by dispatching a Redux action, and handle page navigation if necessary.
|
84
|
+
*
|
85
|
+
* @param page - The page to load.
|
86
|
+
* @param id - The associated resource ID.
|
87
|
+
* @param params - Additional parameters to pass to the page.
|
88
|
+
*/
|
89
|
+
export const loadPage = (page: string, id: string, params: { [key: string]: any }) => async (dispatch: any) => {
|
90
|
+
var newPage = await _preLoadPage(page)
|
67
91
|
|
68
92
|
if (page !== newPage && newPage.indexOf('/') == 0) {
|
69
93
|
dispatch(
|
@@ -83,6 +107,11 @@ export const loadPage = (page: string, id: string, params: { [key: string]: any
|
|
83
107
|
})
|
84
108
|
}
|
85
109
|
|
110
|
+
/**
|
111
|
+
* Route to a given URL by creating a link element and triggering a click event.
|
112
|
+
*
|
113
|
+
* @param url - The URL to route to.
|
114
|
+
*/
|
86
115
|
export const route = (url: string) => {
|
87
116
|
const link = document.createElement('a')
|
88
117
|
|
package/src/app/app-style.ts
CHANGED
@@ -63,16 +63,24 @@ export const AppStyle = css`
|
|
63
63
|
z-index: 1000;
|
64
64
|
}
|
65
65
|
|
66
|
-
/* Wide layout */
|
67
|
-
@media (min-width: 460px) {
|
68
|
-
}
|
69
|
-
|
70
66
|
@media print {
|
71
67
|
:host {
|
72
68
|
width: 100%;
|
73
69
|
height: 100%;
|
74
70
|
min-height: 100vh;
|
75
71
|
min-height: 100dvh;
|
72
|
+
|
73
|
+
max-width: unset;
|
74
|
+
width: unset;
|
75
|
+
height: unset;
|
76
|
+
height: unset;
|
77
|
+
}
|
78
|
+
|
79
|
+
main {
|
80
|
+
/* important for printing!!! */
|
81
|
+
display: block;
|
82
|
+
flex: unset;
|
83
|
+
overflow: visible;
|
76
84
|
}
|
77
85
|
|
78
86
|
ox-page-header-bar {
|
package/src/app/app.ts
CHANGED
@@ -23,7 +23,21 @@ export class ThingsApp extends connect(store)(LitElement) {
|
|
23
23
|
|
24
24
|
static moduleInitialized: MODULES_STATE = MODULES_STATE.NOT_INITIALIZED
|
25
25
|
static modules: Array<any> = []
|
26
|
-
|
26
|
+
|
27
|
+
/*
|
28
|
+
모든 모듈의 routes 리스트가 수집될 때까지, routeToPage(..) 를 hold 시키기 위해서 ThingsApp.pages를 Promise로 정의한다.
|
29
|
+
*/
|
30
|
+
static pagesResolver: (
|
31
|
+
value:
|
32
|
+
| {
|
33
|
+
[path: string]: string
|
34
|
+
}
|
35
|
+
| PromiseLike<{
|
36
|
+
[path: string]: string
|
37
|
+
}>
|
38
|
+
) => void
|
39
|
+
static pages: Promise<{ [path: string]: string }>
|
40
|
+
|
27
41
|
static callbacks: Array<any> = []
|
28
42
|
static contextPath?: string
|
29
43
|
|
@@ -86,13 +100,13 @@ export class ThingsApp extends connect(store)(LitElement) {
|
|
86
100
|
).then(module => {
|
87
101
|
var modules: {
|
88
102
|
name: string
|
89
|
-
bootstrap: any
|
103
|
+
bootstrap: (m?: any /* self */) => void
|
90
104
|
}[] = module.modules
|
91
105
|
|
92
106
|
/* lifecycle - bootstrapping */
|
93
107
|
modules.forEach(async (m, idx) => {
|
94
108
|
try {
|
95
|
-
m.bootstrap && (await m.bootstrap())
|
109
|
+
m.bootstrap && (await m.bootstrap(m))
|
96
110
|
} catch (e) {
|
97
111
|
console.error(`[${idx} BOOTSTRAP ERROR -${m.name}]`, e)
|
98
112
|
}
|
@@ -114,7 +128,13 @@ export class ThingsApp extends connect(store)(LitElement) {
|
|
114
128
|
var { contextPath } = getPathInfo(pathname)
|
115
129
|
|
116
130
|
/* 페이지를 나가기 전에 옮기지 않도록 개입할 기회를 준다 */
|
117
|
-
if (
|
131
|
+
if (
|
132
|
+
lastPathName &&
|
133
|
+
lastPathName != pathname &&
|
134
|
+
this.activePage &&
|
135
|
+
this.activePage.canDeactivate &&
|
136
|
+
!(await this.activePage.canDeactivate())
|
137
|
+
) {
|
118
138
|
history.back()
|
119
139
|
return
|
120
140
|
}
|
@@ -146,7 +166,7 @@ export class ThingsApp extends connect(store)(LitElement) {
|
|
146
166
|
super.disconnectedCallback()
|
147
167
|
}
|
148
168
|
|
149
|
-
routeToPage() {
|
169
|
+
async routeToPage() {
|
150
170
|
const activePages = this.renderRoot.querySelectorAll('main > .page[active]')
|
151
171
|
activePages.forEach(page => {
|
152
172
|
page.removeAttribute('active')
|
@@ -156,7 +176,7 @@ export class ThingsApp extends connect(store)(LitElement) {
|
|
156
176
|
|
157
177
|
if (!this.activePage) {
|
158
178
|
/* 해당 route에 연결된 page가 없는 경우에 main 섹션에 해당 element를 추가해준다. */
|
159
|
-
const tagname = ThingsApp.pages[this.page!]
|
179
|
+
const tagname = (await ThingsApp.pages)[this.page!]
|
160
180
|
if (tagname) {
|
161
181
|
const el = document.createElement(tagname) as PageView
|
162
182
|
el.setAttribute('class', 'page')
|
@@ -219,19 +239,32 @@ export class ThingsApp extends connect(store)(LitElement) {
|
|
219
239
|
ThingsApp.callbacks = state.route.callbacks
|
220
240
|
}
|
221
241
|
|
222
|
-
static registerPages() {
|
242
|
+
static async registerPages() {
|
243
|
+
ThingsApp.pages = new Promise<{ [path: string]: string }>(resolve => (ThingsApp.pagesResolver = resolve))
|
244
|
+
|
223
245
|
var reversedModules = [...ThingsApp.modules].reverse()
|
224
|
-
|
246
|
+
const pages: { [path: string]: string } = {}
|
225
247
|
|
226
248
|
/* 모듈 참조 순서 역순으로 page를 추가한다. (for overidable) */
|
227
|
-
|
228
|
-
m.routes
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
249
|
+
for (const m of reversedModules) {
|
250
|
+
if (!m.routes) {
|
251
|
+
continue
|
252
|
+
}
|
253
|
+
|
254
|
+
/*
|
255
|
+
각 모듈의 routes가 모두 완성될 때까지 ThingsApp.pages 구성을 지연한다.
|
256
|
+
각 모듈의 routes를 동적으로도 구성할 수 있도록 하기 위해서이다.
|
257
|
+
*/
|
258
|
+
const routes = await m.routes
|
259
|
+
|
260
|
+
routes.forEach((route: any) => {
|
261
|
+
if (!pages[route.page]) {
|
262
|
+
pages[route.page] = route.tagname
|
263
|
+
}
|
264
|
+
})
|
265
|
+
}
|
266
|
+
|
267
|
+
ThingsApp.pagesResolver(pages)
|
235
268
|
}
|
236
269
|
|
237
270
|
setBase() {
|
@@ -17,8 +17,8 @@ export class Page404 extends PageView {
|
|
17
17
|
text-align: center;
|
18
18
|
color: var(--secondary-color);
|
19
19
|
}
|
20
|
-
|
21
|
-
--
|
20
|
+
md-icon {
|
21
|
+
--md-icon-size: 120px;
|
22
22
|
color: var(--status-danger-color);
|
23
23
|
text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.1);
|
24
24
|
}
|
@@ -28,9 +28,9 @@ export class Page404 extends PageView {
|
|
28
28
|
text-transform: capitalize;
|
29
29
|
}
|
30
30
|
@media only screen and (max-width: 460px) {
|
31
|
-
|
31
|
+
md-icon {
|
32
32
|
padding-top: 25%;
|
33
|
-
--
|
33
|
+
--md-icon-size: 90px;
|
34
34
|
}
|
35
35
|
h2 {
|
36
36
|
font-size: 2em;
|
@@ -47,7 +47,7 @@ export class Page404 extends PageView {
|
|
47
47
|
render() {
|
48
48
|
return html`
|
49
49
|
<section>
|
50
|
-
<
|
50
|
+
<md-icon>error_outline</md-icon>
|
51
51
|
<h2>page not found!</h2>
|
52
52
|
The page you requested cannot be found.
|
53
53
|
</section>
|
@@ -22,12 +22,26 @@ function diff(after: any, before: any): any {
|
|
22
22
|
return changed && changes
|
23
23
|
}
|
24
24
|
|
25
|
+
/**
|
26
|
+
* PageView is a base class for creating page elements with lifecycle management.
|
27
|
+
* Subclasses can extend PageView to define custom behavior and handle page lifecycle events.
|
28
|
+
*/
|
25
29
|
export class PageView extends LitElement {
|
30
|
+
/**
|
31
|
+
* Determines whether the page can be deactivated. Subclasses can override this method
|
32
|
+
* to implement custom deactivation logic.
|
33
|
+
* @returns A Promise that resolves to true if the page can be deactivated, or false otherwise.
|
34
|
+
*/
|
26
35
|
async canDeactivate(): Promise<boolean> {
|
27
36
|
return Promise.resolve(true)
|
28
37
|
}
|
29
38
|
|
30
|
-
|
39
|
+
/**
|
40
|
+
* Determines whether the page should update. This method is called whenever there are
|
41
|
+
* changes to the page's properties.
|
42
|
+
* @param changes - A map of changed property values.
|
43
|
+
* @returns True if the page should update, or false otherwise.
|
44
|
+
*/
|
31
45
|
shouldUpdate(changes: PropertyValues<this>) {
|
32
46
|
var active = String(this.active) == 'true'
|
33
47
|
var { active: oldActive = false } = this._oldLifecycleInfo$ || {}
|
@@ -50,13 +64,31 @@ export class PageView extends LitElement {
|
|
50
64
|
return active
|
51
65
|
}
|
52
66
|
|
67
|
+
/**
|
68
|
+
* Indicates whether the page is currently active.
|
69
|
+
*/
|
53
70
|
@property({ type: Boolean }) active: boolean = false
|
71
|
+
|
72
|
+
/**
|
73
|
+
* Stores information about the page's lifecycle.
|
74
|
+
*/
|
54
75
|
@property({ type: Object }) lifecycle: any
|
76
|
+
|
77
|
+
/**
|
78
|
+
* The context path for the page.
|
79
|
+
*/
|
55
80
|
@property({ type: String, attribute: 'context-path' }) contextPath?: string
|
56
81
|
|
57
82
|
_oldLifecycleInfo$: any
|
58
83
|
|
59
84
|
/* lifecycle */
|
85
|
+
|
86
|
+
/**
|
87
|
+
* Handles page updates and lifecycle events. Subclasses can override this method
|
88
|
+
* to implement custom logic for initializing, updating, and disposing of the page.
|
89
|
+
* @param changes - A map of changed properties.
|
90
|
+
* @param force - If true, forces an update of the page.
|
91
|
+
*/
|
60
92
|
async pageUpdate(changes: any = {}, force: boolean = false) {
|
61
93
|
var before = this._oldLifecycleInfo$ || {}
|
62
94
|
|
@@ -113,6 +145,9 @@ export class PageView extends LitElement {
|
|
113
145
|
}
|
114
146
|
}
|
115
147
|
|
148
|
+
/**
|
149
|
+
* Resets the page. Subclasses can override this method to perform custom reset logic.
|
150
|
+
*/
|
116
151
|
async pageReset() {
|
117
152
|
var { initialized } = this._oldLifecycleInfo$ || {}
|
118
153
|
|
@@ -122,14 +157,35 @@ export class PageView extends LitElement {
|
|
122
157
|
}
|
123
158
|
}
|
124
159
|
|
160
|
+
/**
|
161
|
+
* Disposes of the page. Subclasses can override this method to perform custom disposal logic.
|
162
|
+
*/
|
125
163
|
async pageDispose() {
|
126
164
|
await this.pageUpdate({
|
127
165
|
initialized: false
|
128
166
|
})
|
129
167
|
}
|
130
168
|
|
169
|
+
/**
|
170
|
+
* Initializes the page. Subclasses can override this method to perform custom initialization logic.
|
171
|
+
* @param pageInfo - Information about the page's state.
|
172
|
+
*/
|
131
173
|
pageInitialized(pageInfo: any) {}
|
174
|
+
|
175
|
+
/**
|
176
|
+
* Handles page updates and changes in properties.
|
177
|
+
* Subclasses can override this method to implement custom update logic.
|
178
|
+
* @param changes - A map of changed properties.
|
179
|
+
* @param after - The current state of the page.
|
180
|
+
* @param before - The previous state of the page.
|
181
|
+
*/
|
132
182
|
pageUpdated(changes: any, after: any, before: any) {}
|
183
|
+
|
184
|
+
/**
|
185
|
+
* Handles the disposal of the page. Subclasses can override this method
|
186
|
+
* to implement custom disposal logic.
|
187
|
+
* @param pageInfo - Information about the page's state.
|
188
|
+
*/
|
133
189
|
pageDisposed(pageInfo: any) {}
|
134
190
|
|
135
191
|
/* context */
|
@@ -140,6 +196,12 @@ export class PageView extends LitElement {
|
|
140
196
|
})
|
141
197
|
}
|
142
198
|
|
199
|
+
/**
|
200
|
+
* Updates the context of the page. Subclasses can override the `context` getter
|
201
|
+
* to provide specific context information for the page. The context will be updated
|
202
|
+
* using the `updateContext` method inherited from PageView.
|
203
|
+
* @param override - An optional object with context properties to override.
|
204
|
+
*/
|
143
205
|
get context() {
|
144
206
|
return {}
|
145
207
|
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import { OxPrompt } from '@operato/popup'
|
2
|
+
|
3
|
+
const TYPES_ICON: { [type: string]: string } = {
|
4
|
+
success: 'verified',
|
5
|
+
error: 'error',
|
6
|
+
warning: 'warning',
|
7
|
+
info: 'info',
|
8
|
+
question: 'question_mark'
|
9
|
+
}
|
10
|
+
|
11
|
+
export async function CustomAlert({
|
12
|
+
type,
|
13
|
+
icon,
|
14
|
+
title,
|
15
|
+
text,
|
16
|
+
confirmButton,
|
17
|
+
cancelButton,
|
18
|
+
callback
|
19
|
+
}: {
|
20
|
+
type?: 'info' | 'success' | 'error' | 'warning' | 'question'
|
21
|
+
icon?: string
|
22
|
+
title?: string
|
23
|
+
text?: string
|
24
|
+
confirmButton?: { color?: string; text: string }
|
25
|
+
cancelButton?: { color?: string; text: string }
|
26
|
+
callback?: (val: { isConfirmed: boolean; isDismissed: boolean; value: boolean }) => any
|
27
|
+
}) {
|
28
|
+
const result = await OxPrompt.open({
|
29
|
+
type: type || 'info',
|
30
|
+
icon: (icon && TYPES_ICON[icon]) || icon,
|
31
|
+
title,
|
32
|
+
text,
|
33
|
+
confirmButton,
|
34
|
+
cancelButton
|
35
|
+
})
|
36
|
+
|
37
|
+
const val = { isConfirmed: result, isDismissed: !result, value: result }
|
38
|
+
if (callback && typeof callback === 'function') {
|
39
|
+
callback(val)
|
40
|
+
} else {
|
41
|
+
return val
|
42
|
+
}
|
43
|
+
}
|
@@ -1,5 +1,4 @@
|
|
1
|
-
import '@material/
|
2
|
-
import '@material/mwc-button'
|
1
|
+
import '@material/web/icon/icon.js'
|
3
2
|
|
4
3
|
import { css, html, LitElement } from 'lit'
|
5
4
|
import { customElement } from 'lit/decorators.js'
|
@@ -13,7 +12,7 @@ export class HomePage extends LitElement {
|
|
13
12
|
display: block;
|
14
13
|
position: relative;
|
15
14
|
|
16
|
-
--
|
15
|
+
--md-theme-primary: white;
|
17
16
|
}
|
18
17
|
|
19
18
|
[home] {
|
@@ -30,17 +29,19 @@ export class HomePage extends LitElement {
|
|
30
29
|
color: #fff;
|
31
30
|
text-align: center;
|
32
31
|
font-size: 20px;
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
32
|
+
|
33
|
+
strong {
|
34
|
+
display: block;
|
35
|
+
font-size: 2.5rem;
|
36
|
+
}
|
37
|
+
|
38
|
+
img {
|
39
|
+
width: 450px;
|
40
|
+
max-width: 90%;
|
41
|
+
display: block;
|
42
|
+
margin: auto;
|
43
|
+
margin-top: 20px;
|
44
|
+
}
|
44
45
|
}
|
45
46
|
|
46
47
|
@media screen and (max-width: 460px) {
|
@@ -64,10 +65,10 @@ export class HomePage extends LitElement {
|
|
64
65
|
}
|
65
66
|
|
66
67
|
render() {
|
67
|
-
var {
|
68
|
+
var { title, description } = this.applicationMeta
|
68
69
|
|
69
70
|
return html`
|
70
|
-
<
|
71
|
+
<md-icon home @click=${() => (window.location.href = '/')}>home</md-icon>
|
71
72
|
|
72
73
|
<div message>
|
73
74
|
<strong>${title}</strong>
|
package/src/index.ts
CHANGED
package/src/store.ts
CHANGED
@@ -14,6 +14,15 @@ declare global {
|
|
14
14
|
// See https://github.com/zalmoxisus/redux-devtools-extension for more information.
|
15
15
|
const devCompose = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
|
16
16
|
|
17
|
+
// Only for providing test environment - combineReducers 에서 process.env.NODE_ENV를 접근하기 때문에.
|
18
|
+
if (typeof window.process == 'undefined') {
|
19
|
+
window.process = {
|
20
|
+
env: {
|
21
|
+
NODE_ENV: JSON.stringify('development')
|
22
|
+
}
|
23
|
+
} as any
|
24
|
+
}
|
25
|
+
|
17
26
|
export const store: Store<unknown, Action<any>> & LazyStore = createStore(
|
18
27
|
state => state,
|
19
28
|
devCompose(lazyReducerEnhancer(combineReducers), applyMiddleware(thunk))
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import '@material/web/icon/icon.js'
|
2
|
+
|
3
|
+
import { css, html, render, TemplateResult } from 'lit'
|
4
|
+
import '../src/app/app.js'
|
5
|
+
|
6
|
+
export default {
|
7
|
+
title: 'things-app',
|
8
|
+
component: 'things-app',
|
9
|
+
argTypes: {
|
10
|
+
label: { control: 'string' }
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
interface Story<T> {
|
15
|
+
(args: T): TemplateResult
|
16
|
+
args?: Partial<T>
|
17
|
+
argTypes?: Record<string, unknown>
|
18
|
+
}
|
19
|
+
|
20
|
+
interface ArgTypes {
|
21
|
+
label?: string
|
22
|
+
}
|
23
|
+
|
24
|
+
const Template: Story<ArgTypes> = ({ label = '' }: ArgTypes) => html`
|
25
|
+
<link href="/themes/app-theme.css" rel="stylesheet" />
|
26
|
+
<link
|
27
|
+
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL@20..48,100..700,0..1"
|
28
|
+
rel="stylesheet"
|
29
|
+
/>
|
30
|
+
<link
|
31
|
+
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL@20..48,100..700,0..1"
|
32
|
+
rel="stylesheet"
|
33
|
+
/>
|
34
|
+
<link
|
35
|
+
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp:opsz,wght,FILL@20..48,100..700,0..1"
|
36
|
+
rel="stylesheet"
|
37
|
+
/>
|
38
|
+
|
39
|
+
<style>
|
40
|
+
body {
|
41
|
+
background-color: white;
|
42
|
+
}
|
43
|
+
</style>
|
44
|
+
|
45
|
+
<things-app></things-app>
|
46
|
+
`
|
47
|
+
|
48
|
+
export const Regular = Template.bind({})
|
49
|
+
Regular.args = {
|
50
|
+
label: 'common header styles'
|
51
|
+
}
|