terrier-engine 4.0.18 → 4.0.20
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/app.ts +7 -10
- package/dropdowns.ts +11 -2
- package/lightbox.ts +15 -3
- package/modals.ts +15 -5
- package/overlays.ts +2 -1
- package/package.json +1 -1
- package/parts.ts +30 -16
package/app.ts
CHANGED
|
@@ -18,13 +18,9 @@ Logger.level = 'info'
|
|
|
18
18
|
*/
|
|
19
19
|
export abstract class TerrierApp<
|
|
20
20
|
TThemeType extends ThemeType,
|
|
21
|
+
TSelf extends TerrierApp<TThemeType, TSelf, TTheme>,
|
|
21
22
|
TTheme extends Theme<TThemeType>
|
|
22
|
-
> extends TerrierPart<
|
|
23
|
-
{theme: TTheme},
|
|
24
|
-
TThemeType,
|
|
25
|
-
TerrierApp<TThemeType, TTheme>,
|
|
26
|
-
TTheme
|
|
27
|
-
> {
|
|
23
|
+
> extends TerrierPart<{theme: TTheme}, TThemeType, TSelf, TTheme> {
|
|
28
24
|
|
|
29
25
|
_theme!: TTheme
|
|
30
26
|
|
|
@@ -48,7 +44,7 @@ export abstract class TerrierApp<
|
|
|
48
44
|
update(root: HTMLElement) {
|
|
49
45
|
log.info(`Update`, root)
|
|
50
46
|
Tooltips.init(root)
|
|
51
|
-
Lightbox.init(root, this, 'body-content')
|
|
47
|
+
Lightbox.init<TThemeType, TSelf, TTheme>(root, this as unknown as TSelf, 'body-content')
|
|
52
48
|
}
|
|
53
49
|
|
|
54
50
|
|
|
@@ -57,7 +53,8 @@ export abstract class TerrierApp<
|
|
|
57
53
|
makeOverlay<OverlayType extends Part<StateType>, StateType>(
|
|
58
54
|
constructor: { new(p: PartParent, id: string, state: StateType): OverlayType; },
|
|
59
55
|
state: StateType,
|
|
60
|
-
layer: OverlayLayer
|
|
56
|
+
layer: OverlayLayer
|
|
57
|
+
): OverlayType {
|
|
61
58
|
return this.overlayPart.makeLayer(constructor, state, layer)
|
|
62
59
|
}
|
|
63
60
|
|
|
@@ -76,9 +73,9 @@ export abstract class TerrierApp<
|
|
|
76
73
|
|
|
77
74
|
/// Modals
|
|
78
75
|
|
|
79
|
-
showModal<ModalType extends ModalPart<StateType, TThemeType>, StateType>(constructor: { new(p: PartParent, id: string, state: StateType): ModalType; }, state: StateType): ModalType {
|
|
76
|
+
showModal<ModalType extends ModalPart<StateType, TThemeType, TSelf, TTheme>, StateType>(constructor: { new(p: PartParent, id: string, state: StateType): ModalType; }, state: StateType): ModalType {
|
|
80
77
|
const modalStack =
|
|
81
|
-
(this.overlayPart.parts.modal as ModalStackPart<TThemeType>)
|
|
78
|
+
(this.overlayPart.parts.modal as ModalStackPart<TThemeType, TSelf, TTheme, ModalType>)
|
|
82
79
|
?? this.makeOverlay(ModalStackPart, {}, 'modal')
|
|
83
80
|
const modal = modalStack.pushModal(constructor, state)
|
|
84
81
|
modalStack.dirty()
|
package/dropdowns.ts
CHANGED
|
@@ -16,7 +16,12 @@ const clearDropdownKey = untypedKey()
|
|
|
16
16
|
* Abstract base class for dropdown parts.
|
|
17
17
|
* Subclasses must implement the `renderContent()` method to render the dropdown content.
|
|
18
18
|
*/
|
|
19
|
-
export abstract class Dropdown<
|
|
19
|
+
export abstract class Dropdown<
|
|
20
|
+
TState,
|
|
21
|
+
TThemeType extends ThemeType,
|
|
22
|
+
TApp extends TerrierApp<TThemeType, TApp, TTheme>,
|
|
23
|
+
TTheme extends Theme<TThemeType>
|
|
24
|
+
> extends TerrierPart<TState, TThemeType, TApp, TTheme> {
|
|
20
25
|
|
|
21
26
|
parentPart?: StatelessPart
|
|
22
27
|
|
|
@@ -79,7 +84,11 @@ export abstract class Dropdown<T, TT extends ThemeType> extends TerrierPart<T, T
|
|
|
79
84
|
/**
|
|
80
85
|
* A concrete dropdown part that shows a list of actions.
|
|
81
86
|
*/
|
|
82
|
-
export class ActionsDropdown<
|
|
87
|
+
export class ActionsDropdown<
|
|
88
|
+
TThemeType extends ThemeType,
|
|
89
|
+
TApp extends TerrierApp<TThemeType, TApp, TTheme>,
|
|
90
|
+
TTheme extends Theme<TThemeType>
|
|
91
|
+
> extends Dropdown<Array<Action<TThemeType>>, TThemeType, TApp, TTheme> {
|
|
83
92
|
|
|
84
93
|
|
|
85
94
|
get parentClasses(): Array<string> {
|
package/lightbox.ts
CHANGED
|
@@ -16,7 +16,11 @@ const log = new Logger('Lightbox')
|
|
|
16
16
|
* @param app
|
|
17
17
|
* @param containerClass
|
|
18
18
|
*/
|
|
19
|
-
function init<
|
|
19
|
+
function init<
|
|
20
|
+
TT extends ThemeType,
|
|
21
|
+
TApp extends TerrierApp<TT, TApp, TTheme>,
|
|
22
|
+
TTheme extends Theme<TT>
|
|
23
|
+
>(root: HTMLElement, app: TApp, containerClass: string) {
|
|
20
24
|
log.info("Init", root)
|
|
21
25
|
root.addEventListener("click", evt => {
|
|
22
26
|
if (!(evt.target instanceof HTMLElement) || evt.target.tagName != 'IMG') {
|
|
@@ -49,13 +53,21 @@ function init<TT extends ThemeType>(root: HTMLElement, app: TerrierApp<TT, Theme
|
|
|
49
53
|
|
|
50
54
|
type LightboxState = { src: string }
|
|
51
55
|
|
|
52
|
-
function showPart<
|
|
56
|
+
function showPart<
|
|
57
|
+
TT extends ThemeType,
|
|
58
|
+
TApp extends TerrierApp<TT,TApp, TTheme>,
|
|
59
|
+
TTheme extends Theme<TT>
|
|
60
|
+
>(app: TApp, state: LightboxState) {
|
|
53
61
|
app.makeOverlay(LightboxPart, {app,...state}, 'lightbox')
|
|
54
62
|
}
|
|
55
63
|
|
|
56
64
|
const closeKey = untypedKey()
|
|
57
65
|
|
|
58
|
-
class LightboxPart<
|
|
66
|
+
class LightboxPart<
|
|
67
|
+
TT extends ThemeType,
|
|
68
|
+
TApp extends TerrierApp<TT, TApp, TTheme>,
|
|
69
|
+
TTheme extends Theme<TT>
|
|
70
|
+
> extends Part<LightboxState & {app: TApp}> {
|
|
59
71
|
|
|
60
72
|
async init() {
|
|
61
73
|
this.onClick(closeKey, _ => {
|
package/modals.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Logger } from "tuff-core/logging"
|
|
2
2
|
import { untypedKey } from "tuff-core/messages"
|
|
3
3
|
import {ContentPart, TerrierPart} from "./parts"
|
|
4
|
-
import {
|
|
4
|
+
import {PartConstructor, PartTag} from "tuff-core/parts"
|
|
5
5
|
import Theme, {ThemeType} from "./theme";
|
|
6
6
|
import {TerrierApp} from "./app";
|
|
7
7
|
|
|
@@ -17,7 +17,12 @@ const log = new Logger('Modals')
|
|
|
17
17
|
* Since it extends ContentPart, all of the same title/action methods
|
|
18
18
|
* available for pages can be used in modals as well.
|
|
19
19
|
*/
|
|
20
|
-
export abstract class ModalPart<
|
|
20
|
+
export abstract class ModalPart<
|
|
21
|
+
TState,
|
|
22
|
+
TThemeType extends ThemeType,
|
|
23
|
+
TApp extends TerrierApp<TThemeType, TApp, TTheme>,
|
|
24
|
+
TTheme extends Theme<TThemeType>
|
|
25
|
+
> extends ContentPart<TState, TThemeType, TApp, TTheme> {
|
|
21
26
|
|
|
22
27
|
|
|
23
28
|
get parentClasses(): Array<string> {
|
|
@@ -68,7 +73,12 @@ export abstract class ModalPart<T, TT extends ThemeType> extends ContentPart<T,
|
|
|
68
73
|
*/
|
|
69
74
|
export const modalPopKey = untypedKey()
|
|
70
75
|
|
|
71
|
-
export class ModalStackPart<
|
|
76
|
+
export class ModalStackPart<
|
|
77
|
+
TThemeType extends ThemeType,
|
|
78
|
+
TApp extends TerrierApp<TThemeType, TApp, TTheme>,
|
|
79
|
+
TTheme extends Theme<TThemeType>,
|
|
80
|
+
TModal extends ModalPart<any, TThemeType, TApp, TTheme>
|
|
81
|
+
> extends TerrierPart<{}, TThemeType, TApp, TTheme> {
|
|
72
82
|
|
|
73
83
|
displayClass: 'show' | 'hide' = 'show'
|
|
74
84
|
|
|
@@ -77,7 +87,7 @@ export class ModalStackPart<TT extends ThemeType> extends TerrierPart<{}, TT, Te
|
|
|
77
87
|
this.listenMessage(modalPopKey, _ => this.pop())
|
|
78
88
|
}
|
|
79
89
|
|
|
80
|
-
modals:
|
|
90
|
+
modals: TModal[] = []
|
|
81
91
|
|
|
82
92
|
/**
|
|
83
93
|
* Pops the last modal off the stack and removes itself if it's empty.
|
|
@@ -114,7 +124,7 @@ export class ModalStackPart<TT extends ThemeType> extends TerrierPart<{}, TT, Te
|
|
|
114
124
|
* @param constructor the modal class
|
|
115
125
|
* @param state the modal's state
|
|
116
126
|
*/
|
|
117
|
-
pushModal<
|
|
127
|
+
pushModal<StateType>(constructor: PartConstructor<TModal, StateType>, state: StateType): TModal {
|
|
118
128
|
log.info(`Making modal`, constructor.name)
|
|
119
129
|
const modal = this.makePart(constructor, state)
|
|
120
130
|
this.modals.push(modal)
|
package/overlays.ts
CHANGED
|
@@ -30,7 +30,8 @@ export class OverlayPart extends Part<NoState> {
|
|
|
30
30
|
makeLayer<PartType extends Part<StateType>, StateType>(
|
|
31
31
|
constructor: { new(p: PartParent, id: string, state: StateType): PartType; },
|
|
32
32
|
state: StateType,
|
|
33
|
-
layer: OverlayLayer
|
|
33
|
+
layer: OverlayLayer
|
|
34
|
+
): PartType {
|
|
34
35
|
const part = this.makePart(constructor, state)
|
|
35
36
|
this.clearLayer(layer)
|
|
36
37
|
this.parts[layer] = part
|
package/package.json
CHANGED
package/parts.ts
CHANGED
|
@@ -29,7 +29,7 @@ export type ActionLevel = keyof PanelActions<any>
|
|
|
29
29
|
export abstract class TerrierPart<
|
|
30
30
|
TState,
|
|
31
31
|
TThemeType extends ThemeType,
|
|
32
|
-
TApp extends TerrierApp<TThemeType, TTheme>,
|
|
32
|
+
TApp extends TerrierApp<TThemeType, TApp, TTheme>,
|
|
33
33
|
TTheme extends Theme<TThemeType>
|
|
34
34
|
> extends Part<TState> {
|
|
35
35
|
|
|
@@ -120,12 +120,12 @@ export abstract class TerrierPart<
|
|
|
120
120
|
/**
|
|
121
121
|
* Base class for all Parts that render some main content, like pages, panels, and modals.
|
|
122
122
|
*/
|
|
123
|
-
export abstract class ContentPart<
|
|
123
|
+
export abstract class ContentPart<
|
|
124
124
|
TState,
|
|
125
|
-
TThemeType,
|
|
126
|
-
TerrierApp<TThemeType,
|
|
127
|
-
Theme<TThemeType>
|
|
128
|
-
> {
|
|
125
|
+
TThemeType extends ThemeType,
|
|
126
|
+
TApp extends TerrierApp<TThemeType, TApp, TTheme>,
|
|
127
|
+
TTheme extends Theme<TThemeType>
|
|
128
|
+
> extends TerrierPart<TState, TThemeType, TApp, TTheme> {
|
|
129
129
|
|
|
130
130
|
/**
|
|
131
131
|
* All ContentParts must implement this to render their actual content.
|
|
@@ -253,14 +253,14 @@ export abstract class ContentPart<TState, TThemeType extends ThemeType> extends
|
|
|
253
253
|
* @param state the dropdown's state
|
|
254
254
|
* @param target the target element around which to show the dropdown
|
|
255
255
|
*/
|
|
256
|
-
makeDropdown<DropdownType extends Dropdown<DropdownStateType, TThemeType>, DropdownStateType>(
|
|
256
|
+
makeDropdown<DropdownType extends Dropdown<DropdownStateType, TThemeType, TApp, TTheme>, DropdownStateType>(
|
|
257
257
|
constructor: {new(p: PartParent, id: string, state: DropdownStateType): DropdownType;},
|
|
258
258
|
state: DropdownStateType,
|
|
259
259
|
target: EventTarget | null) {
|
|
260
260
|
if (!(target && target instanceof HTMLElement)) {
|
|
261
261
|
throw "Trying to show a dropdown without an element target!"
|
|
262
262
|
}
|
|
263
|
-
const dropdown = this.app.makeOverlay(constructor, state, 'dropdown')
|
|
263
|
+
const dropdown = this.app.makeOverlay(constructor, state, 'dropdown')
|
|
264
264
|
dropdown.parentPart = this
|
|
265
265
|
dropdown.anchor(target)
|
|
266
266
|
this.app.lastDropdownTarget = target
|
|
@@ -276,7 +276,7 @@ export abstract class ContentPart<TState, TThemeType extends ThemeType> extends
|
|
|
276
276
|
* @param state the dropdown's state
|
|
277
277
|
* @param target the target element around which to show the dropdown
|
|
278
278
|
*/
|
|
279
|
-
toggleDropdown<DropdownType extends Dropdown<DropdownStateType, TThemeType>, DropdownStateType>(
|
|
279
|
+
toggleDropdown<DropdownType extends Dropdown<DropdownStateType, TThemeType, TApp, TTheme>, DropdownStateType>(
|
|
280
280
|
constructor: { new(p: PartParent, id: string, state: DropdownStateType): DropdownType; },
|
|
281
281
|
state: DropdownStateType,
|
|
282
282
|
target: EventTarget | null) {
|
|
@@ -303,13 +303,18 @@ export type ContentWidth = "normal" | "wide"
|
|
|
303
303
|
/**
|
|
304
304
|
* A part that renders content to a full page.
|
|
305
305
|
*/
|
|
306
|
-
export abstract class PagePart<
|
|
306
|
+
export abstract class PagePart<
|
|
307
|
+
TState,
|
|
308
|
+
TThemeType extends ThemeType,
|
|
309
|
+
TApp extends TerrierApp<TThemeType, TApp, TTheme>,
|
|
310
|
+
TTheme extends Theme<TThemeType>
|
|
311
|
+
> extends ContentPart<TState, TThemeType, TApp, TTheme> {
|
|
307
312
|
|
|
308
313
|
/// Breadcrumbs
|
|
309
314
|
|
|
310
|
-
private _breadcrumbs = Array<Action<
|
|
315
|
+
private _breadcrumbs = Array<Action<TThemeType>>()
|
|
311
316
|
|
|
312
|
-
addBreadcrumb(crumb: Action<
|
|
317
|
+
addBreadcrumb(crumb: Action<TThemeType>) {
|
|
313
318
|
this._breadcrumbs.push(crumb)
|
|
314
319
|
}
|
|
315
320
|
|
|
@@ -359,7 +364,7 @@ export abstract class PagePart<T, TT extends ThemeType> extends ContentPart<T, T
|
|
|
359
364
|
})
|
|
360
365
|
}
|
|
361
366
|
|
|
362
|
-
protected renderActions(parent: PartTag, level: ActionLevel, options?: RenderActionOptions<
|
|
367
|
+
protected renderActions(parent: PartTag, level: ActionLevel, options?: RenderActionOptions<TThemeType>) {
|
|
363
368
|
parent.div(`.${level}-actions`, actions => {
|
|
364
369
|
this.app.theme.renderActions(actions, this.getActions(level), options)
|
|
365
370
|
})
|
|
@@ -372,7 +377,7 @@ export abstract class PagePart<T, TT extends ThemeType> extends ContentPart<T, T
|
|
|
372
377
|
const crumbs = Array.from(this._breadcrumbs)
|
|
373
378
|
|
|
374
379
|
// add a breadcrumb for the page title
|
|
375
|
-
const titleCrumb: Action<
|
|
380
|
+
const titleCrumb: Action<TThemeType> = {
|
|
376
381
|
title: this._title,
|
|
377
382
|
icon: this._icon || undefined,
|
|
378
383
|
}
|
|
@@ -394,7 +399,11 @@ export abstract class PagePart<T, TT extends ThemeType> extends ContentPart<T, T
|
|
|
394
399
|
/**
|
|
395
400
|
* Default page part if the router can't find the path.
|
|
396
401
|
*/
|
|
397
|
-
export class NotFoundRoute<
|
|
402
|
+
export class NotFoundRoute<
|
|
403
|
+
TT extends ThemeType,
|
|
404
|
+
TApp extends TerrierApp<TT, TApp, TTheme>,
|
|
405
|
+
TTheme extends Theme<TT>
|
|
406
|
+
> extends PagePart<NoState, TT, TApp, TTheme> {
|
|
398
407
|
async init() {
|
|
399
408
|
this.setTitle("Page Not Found")
|
|
400
409
|
}
|
|
@@ -414,7 +423,12 @@ export class NotFoundRoute<TT extends ThemeType> extends PagePart<NoState, TT> {
|
|
|
414
423
|
/**
|
|
415
424
|
* A part that renders content inside a panel.
|
|
416
425
|
*/
|
|
417
|
-
export abstract class PanelPart<
|
|
426
|
+
export abstract class PanelPart<
|
|
427
|
+
TState,
|
|
428
|
+
TThemeType extends ThemeType,
|
|
429
|
+
TApp extends TerrierApp<TThemeType, TApp, TTheme>,
|
|
430
|
+
TTheme extends Theme<TThemeType>
|
|
431
|
+
> extends ContentPart<TState, TThemeType, TApp, TTheme> {
|
|
418
432
|
|
|
419
433
|
getLoadingContainer() {
|
|
420
434
|
return this.element?.getElementsByClassName('tt-panel')[0]
|