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 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): OverlayType {
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<T, TT extends ThemeType> extends TerrierPart<T, TT, TerrierApp<TT, Theme<TT>>, Theme<TT>> {
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<TT extends ThemeType> extends Dropdown<Array<Action<TT>>, TT> {
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<TT extends ThemeType>(root: HTMLElement, app: TerrierApp<TT, Theme<TT>>, containerClass: string) {
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<TT extends ThemeType>(app: TerrierApp<TT, Theme<TT>>, state: LightboxState) {
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<TT extends ThemeType> extends Part<LightboxState & {app: TerrierApp<TT, Theme<TT>>}> {
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 {PartParent, PartTag} from "tuff-core/parts"
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<T, TT extends ThemeType> extends ContentPart<T, TT> {
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<TT extends ThemeType> extends TerrierPart<{}, TT, TerrierApp<TT, Theme<TT>>, Theme<TT>> {
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: ModalPart<unknown, TT>[] = []
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<ModalType extends ModalPart<StateType, TT>, StateType>(constructor: { new(p: PartParent, id: string, state: StateType): ModalType; }, state: StateType): ModalType {
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): PartType {
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
@@ -4,7 +4,7 @@
4
4
  "files": [
5
5
  "*"
6
6
  ],
7
- "version": "4.0.18",
7
+ "version": "4.0.20",
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "https://github.com/Terrier-Tech/terrier-engine"
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<TState, TThemeType extends ThemeType> extends TerrierPart<
123
+ export abstract class ContentPart<
124
124
  TState,
125
- TThemeType,
126
- TerrierApp<TThemeType, Theme<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') as Dropdown<DropdownStateType, TThemeType>
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<T, TT extends ThemeType> extends ContentPart<T, TT> {
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<TT>>()
315
+ private _breadcrumbs = Array<Action<TThemeType>>()
311
316
 
312
- addBreadcrumb(crumb: Action<TT>) {
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<TT>) {
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<TT> = {
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<TT extends ThemeType> extends PagePart<NoState, TT> {
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<T, TT extends ThemeType> extends ContentPart<T, TT> {
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]