@zcomponent/core 0.0.6 → 0.0.8

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.
@@ -1,17 +1,26 @@
1
1
  import { Behavior, BehaviorConstructorProps } from "./behavior";
2
+ import { Component } from "./component";
2
3
  import { ContextManager } from "./context";
4
+ import { Observable } from "./observable";
3
5
  export interface ActionBehaviorConstructorProps extends BehaviorConstructorProps {
4
6
  /** @zprop
5
7
  * @zvalues events
6
8
  */
7
9
  event: string;
10
+ /**
11
+ * @zprop
12
+ * @zdefault false
13
+ */
14
+ runAtEditTime: boolean;
8
15
  }
9
- export declare abstract class ActionBehavior<ConstructorProps extends ActionBehaviorConstructorProps = ActionBehaviorConstructorProps> extends Behavior<any, ConstructorProps> {
16
+ export declare abstract class ActionBehavior<ConstructorProps extends ActionBehaviorConstructorProps = ActionBehaviorConstructorProps> extends Behavior<Component, ConstructorProps> {
10
17
  /**
11
18
  * @zprop
12
19
  * @zdefault true
13
20
  */
14
- enabled: boolean;
21
+ enabled: Observable<boolean, never>;
15
22
  constructor(props: ConstructorProps, contextManager: ContextManager);
23
+ private _updateRegistration;
24
+ private _perform;
16
25
  abstract perform(): any;
17
26
  }
@@ -1,6 +1,7 @@
1
1
  import { Behavior } from "./behavior";
2
- import { isEditTime } from "./contexts/environmentcontext";
2
+ import { EnvironmentContext, isEditTime } from "./contexts/environmentcontext";
3
3
  import { Event } from "./event";
4
+ import { Observable } from "./observable";
4
5
  export class ActionBehavior extends Behavior {
5
6
  constructor(props, contextManager) {
6
7
  super(props, contextManager);
@@ -8,15 +9,30 @@ export class ActionBehavior extends Behavior {
8
9
  * @zprop
9
10
  * @zdefault true
10
11
  */
11
- this.enabled = true;
12
- const evt = props.instance[props.event];
13
- if (evt instanceof Event && !isEditTime(contextManager)) {
14
- this.register(evt, e => {
15
- this.perform();
16
- if (e && typeof e === 'object' && typeof e['stopPropagation'] === 'function') {
17
- e['stopPropagation'].call(e);
12
+ this.enabled = new Observable(true);
13
+ this._updateRegistration = () => {
14
+ const evt = this.constructorProps.instance[this.constructorProps.event];
15
+ if (evt instanceof Event) {
16
+ if (this.enabled.value && (!isEditTime(this.contextManager) || this.constructorProps.runAtEditTime === true)) {
17
+ this.register(evt, this._perform);
18
18
  }
19
- });
20
- }
19
+ else {
20
+ this.unregister(evt, this._perform);
21
+ }
22
+ }
23
+ };
24
+ this._perform = (e) => {
25
+ if (!this.enabled.value)
26
+ return;
27
+ if (!this.instance.enabledResolved.value)
28
+ return;
29
+ this.perform();
30
+ if (e && typeof e === 'object' && typeof e['stopPropagation'] === 'function') {
31
+ e['stopPropagation'].call(e);
32
+ }
33
+ };
34
+ const env = contextManager.get(EnvironmentContext);
35
+ this.register(env.editTime, this._updateRegistration);
36
+ this.register(this.enabled, this._updateRegistration);
21
37
  }
22
38
  }
package/lib/behavior.d.ts CHANGED
@@ -7,7 +7,7 @@ export declare type ConstructorPropsOfBehavior<BehaviorType> = BehaviorType exte
7
7
  export interface BehaviorConstructorProps<InstanceType extends Component = Component> {
8
8
  instance: InstanceType;
9
9
  }
10
- export declare class Behavior<InstanceType extends Component = any, ConstructorPropsType extends BehaviorConstructorProps<InstanceType> = BehaviorConstructorProps<InstanceType>> {
10
+ export declare class Behavior<InstanceType extends Component = Component, ConstructorPropsType extends BehaviorConstructorProps<InstanceType> = BehaviorConstructorProps<InstanceType>> {
11
11
  constructorProps: ConstructorPropsType;
12
12
  contextManager: ContextManager;
13
13
  private static callSuperDispose;
@@ -17,7 +17,9 @@ export declare class Behavior<InstanceType extends Component = any, ConstructorP
17
17
  constructor(constructorProps: ConstructorPropsType, contextManager: ContextManager);
18
18
  register<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
19
19
  register<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
20
+ unregister<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
21
+ unregister<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
20
22
  dispose(): never;
21
23
  }
22
24
  export declare function shouldBehaviorRunAtDesignTime(b: BehaviorConstructor): boolean;
23
- export declare function registerBehaviorRunAtDesignTime(b: BehaviorConstructor): Set<new (props: BehaviorConstructorProps<any>, contextManager: ContextManager) => Behavior<any, BehaviorConstructorProps<any>>>;
25
+ export declare function registerBehaviorRunAtDesignTime(b: BehaviorConstructor): Set<new (props: BehaviorConstructorProps<Component<import("./component").ConstructorProps, any>>, contextManager: ContextManager) => Behavior<Component<import("./component").ConstructorProps, any>, BehaviorConstructorProps<Component<import("./component").ConstructorProps, any>>>>;
package/lib/behavior.js CHANGED
@@ -15,6 +15,13 @@ export class Behavior {
15
15
  e.withValue(fn);
16
16
  this._registered.push([e, fn]);
17
17
  }
18
+ unregister(e, fn) {
19
+ if (e instanceof Event)
20
+ e.unbindfn(fn);
21
+ else if (e instanceof Observable)
22
+ e.removeWithValue(fn);
23
+ this._registered = this._registered.filter(entry => (entry[0] !== e || entry[1] !== fn));
24
+ }
18
25
  dispose() {
19
26
  for (const entry of this._registered) {
20
27
  if (entry[0] instanceof Event)
@@ -11,7 +11,6 @@ export class PlaySound extends ActionBehavior {
11
11
  constructor(props, contextManager) {
12
12
  super(props, contextManager);
13
13
  this._elm = document.createElement('audio');
14
- this._elm.preload = 'auto';
15
14
  registerLoadable(contextManager, new Promise((resolve, reject) => {
16
15
  this._elm.addEventListener('canplaythrough', () => resolve());
17
16
  this._elm.addEventListener('error', err => {
@@ -20,6 +19,7 @@ export class PlaySound extends ActionBehavior {
20
19
  });
21
20
  }));
22
21
  this._elm.src = props.source;
22
+ this._elm.load();
23
23
  }
24
24
  perform() {
25
25
  this._elm.currentTime = 0;
@@ -3,9 +3,10 @@ import { Event } from './event';
3
3
  import { Observable } from './observable';
4
4
  export declare type ComponentConstructor<ComponentType = Component> = ComponentType extends Component<infer ConstructorPropsType> ? new (props: ConstructorPropsType, contextManager: ContextManager) => ComponentType : never;
5
5
  export declare type ConstructorPropsOfComponent<ComponentType> = ComponentType extends Component<infer R> ? R : never;
6
- export declare type ComponentChild<ComponentType extends Component> = [ComponentConstructor<ComponentType>, ConstructorPropsOfComponent<ComponentType>];
7
- export declare type ComponentChildren = ComponentChild<any>[];
6
+ export declare type ComponentChild<ComponentType extends Component> = [ComponentConstructor<ComponentType>, ConstructorPropsOfComponent<ComponentType>] | [ComponentConstructor<ComponentType>, ConstructorPropsOfComponent<ComponentType>, Observable<ComponentType | undefined>];
7
+ export declare type ComponentChildren = ComponentChild<Component>[];
8
8
  export interface ConstructorProps {
9
+ [id: string]: any;
9
10
  children?: ComponentChildren;
10
11
  }
11
12
  export interface ComponentOptions {
@@ -18,13 +19,32 @@ export declare class Component<ConstructorPropsType extends ConstructorProps = C
18
19
  root?: RootType;
19
20
  onDispose: Event<[]>;
20
21
  children: Component[];
22
+ parent?: Component;
21
23
  disposed: boolean;
22
24
  private _registered;
23
25
  constructor(constructorProps: ConstructorPropsType, contextManager: ContextManager, _options?: ComponentOptions | undefined);
24
26
  forEachRoot(fn: (root: any) => void): void;
27
+ /**
28
+ * @zprop
29
+ * @zdefault true
30
+ * @zgroup Behavior
31
+ * @zgrouppriority 10
32
+ */
33
+ enabled: Observable<boolean, never>;
34
+ enabledResolved: Observable<boolean, never>;
35
+ /**
36
+ * @zprop
37
+ * @zgroup Other
38
+ * @zgrouppriority 0
39
+ */
40
+ tags: Observable<string[], never>;
25
41
  protected _constructChildren(children?: ComponentChildren): void;
26
42
  protected register<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
27
43
  protected register<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
44
+ protected unregister<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
45
+ protected unregister<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
46
+ private _updateEnabledResolved;
47
+ private _updateTags;
28
48
  dispose(): never;
29
49
  private static callSuperDispose;
30
50
  }
package/lib/component.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { TagContext } from './contexts/tagcontext';
1
2
  import { Event } from './event';
2
3
  import { Observable } from './observable';
3
4
  export class Component {
@@ -9,8 +10,38 @@ export class Component {
9
10
  this.children = [];
10
11
  this.disposed = false;
11
12
  this._registered = [];
13
+ /**
14
+ * @zprop
15
+ * @zdefault true
16
+ * @zgroup Behavior
17
+ * @zgrouppriority 10
18
+ */
19
+ this.enabled = new Observable(true);
20
+ this.enabledResolved = new Observable(true);
21
+ /**
22
+ * @zprop
23
+ * @zgroup Other
24
+ * @zgrouppriority 0
25
+ */
26
+ this.tags = new Observable([]);
27
+ this._updateEnabledResolved = () => {
28
+ let newValue = this.enabled.value;
29
+ if (this.parent?.enabledResolved?.value === false)
30
+ newValue = false;
31
+ if (newValue !== this.enabledResolved.value) {
32
+ this.enabledResolved.value = newValue;
33
+ for (const child of this.children)
34
+ child._updateEnabledResolved();
35
+ }
36
+ };
37
+ this._updateTags = () => {
38
+ const context = this.contextManager.get(TagContext);
39
+ context.registerComponent(this, this.tags.value);
40
+ };
12
41
  if (this._options?.dontConstructChildren !== true)
13
42
  this._constructChildren(this.constructorProps.children);
43
+ this.register(this.enabled, this._updateEnabledResolved);
44
+ this.register(this.tags, this._updateTags);
14
45
  }
15
46
  forEachRoot(fn) {
16
47
  if (Array.isArray(this.root))
@@ -21,7 +52,11 @@ export class Component {
21
52
  _constructChildren(children) {
22
53
  if (Array.isArray(children)) {
23
54
  for (const child of children) {
24
- this.children.push(new child[0](child[1], this.contextManager));
55
+ const instance = new child[0](child[1], this.contextManager);
56
+ this.children.push(instance);
57
+ instance.parent = this;
58
+ if (child[2] instanceof Observable)
59
+ child[2].value = instance;
25
60
  }
26
61
  }
27
62
  }
@@ -32,6 +67,13 @@ export class Component {
32
67
  e.withValue(fn);
33
68
  this._registered.push([e, fn]);
34
69
  }
70
+ unregister(e, fn) {
71
+ if (e instanceof Event)
72
+ e.unbindfn(fn);
73
+ else if (e instanceof Observable)
74
+ e.removeWithValue(fn);
75
+ this._registered = this._registered.filter(entry => (entry[0] !== e || entry[1] !== fn));
76
+ }
35
77
  dispose() {
36
78
  this.disposed = true;
37
79
  for (const child of this.children) {
@@ -50,6 +92,7 @@ export class Component {
50
92
  this._registered = [];
51
93
  this.onDispose.emit();
52
94
  this.onDispose.clear();
95
+ this.contextManager.get(TagContext).unregisterComponent(this);
53
96
  return undefined;
54
97
  }
55
98
  }
@@ -1,5 +1,5 @@
1
- import { Component, Observable, ConstructorProps, ContextManager } from "..";
2
- export interface DefaultLoaderConstructorProps extends ConstructorProps {
1
+ import { Component, Observable, ContextManager } from "..";
2
+ export interface DefaultLoaderConstructorProps {
3
3
  /** @zprop
4
4
  * @zgroup Appearance
5
5
  * @zgrouppriority 10
@@ -7,7 +7,7 @@ export interface DefaultLoaderConstructorProps extends ConstructorProps {
7
7
  * @zvalues files *.png
8
8
  * @zvalues files *.jpg
9
9
  */
10
- backgroundImage?: string;
10
+ backgroundImage: string;
11
11
  }
12
12
  /**
13
13
  * The DefaultLoader shows a customizable loading bar while the assets of your experience are being downloaded and parsed by the browser.
@@ -16,7 +16,7 @@ export interface DefaultLoaderConstructorProps extends ConstructorProps {
16
16
  * @zicon loader
17
17
  * @zgroup Advanced
18
18
  */
19
- export declare class DefaultLoader extends Component<DefaultLoaderConstructorProps> {
19
+ export declare class DefaultLoader extends Component {
20
20
  root: HTMLDivElement;
21
21
  /** @zprop
22
22
  * @zdefault false
@@ -54,7 +54,7 @@ export declare class DefaultLoader extends Component<DefaultLoaderConstructorPro
54
54
  zIndex: Observable<number>;
55
55
  private _percentageElement;
56
56
  private _attached;
57
- constructor(props: DefaultLoaderConstructorProps, contextManager: ContextManager);
57
+ constructor(constructorProps: DefaultLoaderConstructorProps, contextManager: ContextManager);
58
58
  private _updatePercentage;
59
59
  private _updateVisibility;
60
60
  private _update;
@@ -7,8 +7,8 @@ import { Component, useCanvas, Observable, isDesignTime, useIsLoaded, useLoadPer
7
7
  * @zgroup Advanced
8
8
  */
9
9
  export class DefaultLoader extends Component {
10
- constructor(props, contextManager) {
11
- super(props, contextManager);
10
+ constructor(constructorProps, contextManager) {
11
+ super(constructorProps, contextManager);
12
12
  this.root = document.createElement('div');
13
13
  /** @zprop
14
14
  * @zdefault false
@@ -48,8 +48,8 @@ export class DefaultLoader extends Component {
48
48
  };
49
49
  this.root.innerHTML = loaderHTML;
50
50
  this.root.className = "zcomponent-defaultloader";
51
- if (props.backgroundImage) {
52
- this.root.style.backgroundImage = `url(${props.backgroundImage})`;
51
+ if (constructorProps.backgroundImage) {
52
+ this.root.style.backgroundImage = `url(${constructorProps.backgroundImage})`;
53
53
  }
54
54
  const titleElement = this.root.querySelector("#zcomponent-defaultloader-title") || document.createElement("h1");
55
55
  const subtitleElement = this.root.querySelector("#zcomponent-defaultloader-subtitle") || document.createElement("h1");
@@ -1,5 +1,5 @@
1
- import { Component, ConstructorProps, ContextManager } from "..";
2
- export interface LongLoadConstructorProps extends ConstructorProps {
1
+ import { Component, ContextManager } from "..";
2
+ export interface LongLoadConstructorProps {
3
3
  /**
4
4
  * The number of loading processes to simulate
5
5
  * @zprop
@@ -40,6 +40,6 @@ export interface LongLoadConstructorProps extends ConstructorProps {
40
40
  * @zicon settings
41
41
  * @zgroup Advanced
42
42
  */
43
- export declare class LongLoad extends Component<LongLoadConstructorProps> {
43
+ export declare class LongLoad extends Component {
44
44
  constructor(props: LongLoadConstructorProps, contextManager: ContextManager);
45
45
  }
@@ -0,0 +1,14 @@
1
+ import { Component } from "../component";
2
+ import { ContextManager } from "../context";
3
+ export interface TagContext {
4
+ registerComponent(component: Component, tags: string[]): any;
5
+ unregisterComponent(component: Component): any;
6
+ getComponentsByTag(tag: string): Set<Component>;
7
+ getComponentsByTags(tags: string[]): Set<Component>;
8
+ tagsByComponent: Map<Component, Set<string>>;
9
+ componentsByLocalTag: Map<string, Set<Component>>;
10
+ componentsByGlobalTag: Map<string, Set<Component>>;
11
+ }
12
+ export declare const TagContext: import("../context").ContextTypeWithDefault<TagContext, []>;
13
+ export declare function getComponentsByTag(mgr: ContextManager, tag: string): Set<Component<import("../component").ConstructorProps, any>>;
14
+ export declare function getComponentsByTags(mgr: ContextManager, tags: string[]): Set<Component<import("../component").ConstructorProps, any>>;
@@ -0,0 +1,65 @@
1
+ import { defineContextType } from "../context";
2
+ export const TagContext = defineContextType(ctx => {
3
+ // We have to cast here to avoid a circular dependency
4
+ const upstream = ctx.getExisting(TagContext);
5
+ const tagsByComponent = new Map();
6
+ const componentsByLocalTag = new Map();
7
+ const componentsByGlobalTag = upstream?.componentsByGlobalTag ?? new Map();
8
+ console.log();
9
+ const registerComponent = (component, tags) => {
10
+ unregisterComponent(component);
11
+ for (const tag of tags) {
12
+ const map = tag.startsWith('global:') ? componentsByGlobalTag : componentsByLocalTag;
13
+ const set = map.get(tag) ?? new Set();
14
+ set.add(component);
15
+ map.set(tag, set);
16
+ }
17
+ tagsByComponent.set(component, new Set(tags));
18
+ };
19
+ const unregisterComponent = (component) => {
20
+ let tags = tagsByComponent.get(component);
21
+ if (!tags)
22
+ return;
23
+ for (const tag of tags.values()) {
24
+ const map = tag.startsWith('global:') ? componentsByGlobalTag : componentsByLocalTag;
25
+ const entry = map.get(tag);
26
+ if (!entry)
27
+ continue;
28
+ entry.delete(component);
29
+ }
30
+ tagsByComponent.delete(component);
31
+ };
32
+ const getComponentsByTag = (tag) => {
33
+ return ((tag.startsWith('global:') ? componentsByGlobalTag : componentsByLocalTag).get(tag)) ?? new Set();
34
+ };
35
+ const getComponentsByTags = (tags) => {
36
+ if (tags.length === 0)
37
+ return new Set();
38
+ if (tags.length === 1)
39
+ return getComponentsByTag(tags[0]);
40
+ const ret = new Set();
41
+ for (const tag of tags) {
42
+ const map = tag.startsWith('global:') ? componentsByGlobalTag : componentsByLocalTag;
43
+ const entries = map.get(tag);
44
+ if (!entries)
45
+ continue;
46
+ entries.forEach(entry => ret.add(entry));
47
+ }
48
+ return ret;
49
+ };
50
+ return {
51
+ tagsByComponent,
52
+ componentsByLocalTag,
53
+ componentsByGlobalTag,
54
+ getComponentsByTag,
55
+ getComponentsByTags,
56
+ registerComponent,
57
+ unregisterComponent,
58
+ };
59
+ });
60
+ export function getComponentsByTag(mgr, tag) {
61
+ return mgr.get(TagContext).getComponentsByTag(tag);
62
+ }
63
+ export function getComponentsByTags(mgr, tags) {
64
+ return mgr.get(TagContext).getComponentsByTags(tags);
65
+ }
package/lib/index.d.ts CHANGED
@@ -9,5 +9,6 @@ export * from './contexts/loadcontext';
9
9
  export * from './contexts/cookieconsentcontext';
10
10
  export * from './contexts/analyticscontext';
11
11
  export * from './contexts/usereventcontext';
12
+ export * from './contexts/tagcontext';
12
13
  export * from './observable';
13
14
  export * from './contexts/environmentcontext';
package/lib/index.js CHANGED
@@ -9,6 +9,7 @@ export * from './contexts/loadcontext';
9
9
  export * from './contexts/cookieconsentcontext';
10
10
  export * from './contexts/analyticscontext';
11
11
  export * from './contexts/usereventcontext';
12
+ export * from './contexts/tagcontext';
12
13
  export * from './observable';
13
14
  export * from './contexts/environmentcontext';
14
15
  const link = document.createElement('link');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zcomponent/core",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -26,13 +26,12 @@
26
26
  "author": "Zappar Limited",
27
27
  "license": "Proprietary",
28
28
  "devDependencies": {
29
- "typescript": "^4.6.3",
30
29
  "@playwright/test": "^1.25.0",
31
- "parcel": "2.6.2",
32
30
  "@types/ua-parser-js": "^0.7.36",
31
+ "parcel": "^2.8.2",
32
+ "typescript": "^4.6.3",
33
33
  "ua-parser-js": "^1.0.2"
34
34
  },
35
- "dependencies": {},
36
35
  "zexports": [
37
36
  "./lib/components/**/*",
38
37
  "./lib/behaviors/**/*"