canvasengine 2.0.0-beta.20 → 2.0.0-beta.21

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/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export * from '@signe/reactive';
4
4
  import { BehaviorSubject, Subscription, Subject, Observable } from 'rxjs';
5
5
  export { isObservable } from 'rxjs';
6
6
  import * as PIXI from 'pixi.js';
7
- import { FederatedPointerEvent, ObservablePoint, Graphics as Graphics$1, Geometry, Shader, Texture, TextStyle, Application, Matrix } from 'pixi.js';
7
+ import { FederatedPointerEvent, ObservablePoint, Graphics as Graphics$1, Geometry, Shader, Texture, TextStyle, ApplicationOptions, Application, Matrix } from 'pixi.js';
8
8
  import * as howler from 'howler';
9
9
  export { howler as Howl };
10
10
  export { Howler } from 'howler';
@@ -982,6 +982,8 @@ interface NineSliceSpriteProps extends DisplayObjectProps {
982
982
  }
983
983
  declare function NineSliceSprite(props: NineSliceSpriteProps): Element<ComponentInstance>;
984
984
 
985
+ declare const DOMContainer: ComponentFunction<any>;
986
+
985
987
  interface DOMContainerProps extends DisplayObjectProps {
986
988
  element: string | {
987
989
  value: HTMLElement;
@@ -997,9 +999,9 @@ interface DOMContainerProps extends DisplayObjectProps {
997
999
  value?: string | Record<string, string | number>;
998
1000
  };
999
1001
  };
1000
- sortableChildren?: boolean;
1002
+ onBeforeDestroy?: OnHook;
1001
1003
  }
1002
- declare const DOMContainer: ComponentFunction<DOMContainerProps>;
1004
+ declare const DOMElement: ComponentFunction<DOMContainerProps>;
1003
1005
 
1004
1006
  interface Listen<T = any> {
1005
1007
  config: T | undefined;
@@ -1059,7 +1061,7 @@ declare function on(triggerSignal: any, callback: (config: any) => void | Promis
1059
1061
  * @returns A Promise that resolves to the rendered canvas element.
1060
1062
  * @throws {Error} If the provided element is not a Canvas component.
1061
1063
  */
1062
- declare const bootstrapCanvas: (rootElement: HTMLElement | null, canvas: ComponentFunction<any>) => Promise<{
1064
+ declare const bootstrapCanvas: (rootElement: HTMLElement | null, canvas: ComponentFunction<any>, options?: ApplicationOptions) => Promise<{
1063
1065
  canvasElement: Element<ComponentInstance>;
1064
1066
  app: Application<PIXI.Renderer>;
1065
1067
  }>;
@@ -1220,6 +1222,7 @@ declare function isFunction(val: unknown): boolean;
1220
1222
  * ```
1221
1223
  */
1222
1224
  declare function isObject(val: unknown): boolean;
1225
+ declare function isObservable(val: unknown): boolean;
1223
1226
  /**
1224
1227
  * Sets a value in an object using a dot notation path
1225
1228
  * @param {Record<string, any>} obj - Target object
@@ -1273,13 +1276,14 @@ declare const utils_get: typeof get;
1273
1276
  declare const utils_isBrowser: typeof isBrowser;
1274
1277
  declare const utils_isFunction: typeof isFunction;
1275
1278
  declare const utils_isObject: typeof isObject;
1279
+ declare const utils_isObservable: typeof isObservable;
1276
1280
  declare const utils_isPromise: typeof isPromise;
1277
1281
  declare const utils_log: typeof log;
1278
1282
  declare const utils_preciseNow: typeof preciseNow;
1279
1283
  declare const utils_set: typeof set;
1280
1284
  declare const utils_setObservablePoint: typeof setObservablePoint;
1281
1285
  declare namespace utils {
1282
- export { utils_arrayEquals as arrayEquals, utils_calculateDistance as calculateDistance, utils_error as error, utils_fps2ms as fps2ms, utils_get as get, utils_isBrowser as isBrowser, utils_isFunction as isFunction, utils_isObject as isObject, utils_isPromise as isPromise, utils_log as log, utils_preciseNow as preciseNow, utils_set as set, utils_setObservablePoint as setObservablePoint };
1286
+ export { utils_arrayEquals as arrayEquals, utils_calculateDistance as calculateDistance, utils_error as error, utils_fps2ms as fps2ms, utils_get as get, utils_isBrowser as isBrowser, utils_isFunction as isFunction, utils_isObject as isObject, utils_isObservable as isObservable, utils_isPromise as isPromise, utils_log as log, utils_preciseNow as preciseNow, utils_set as set, utils_setObservablePoint as setObservablePoint };
1283
1287
  }
1284
1288
 
1285
- export { type AnimateOptions, type AnimatedSignal, type AnimatedState, Canvas, Circle, type ComponentFunction, type ComponentInstance, Container, DOMContainer, DisplayObject, EVENTS, Easing, type Element, Ellipse, Graphics, Mesh, NineSliceSprite, ParticlesEmitter, type Props, RadialGradient, Rect, Scene, Sprite, Svg, Text, TilingSprite, Triangle, utils as Utils, Video, Viewport, animatedSequence, animatedSignal, bootstrapCanvas, cond, createComponent, currentSubscriptionsTracker, h, isAnimatedSignal, isElement, isPrimitive, isTrigger, loop, mount, mountTracker, on, registerComponent, tick, trigger, useDefineProps, useProps };
1289
+ export { type AnimateOptions, type AnimatedSignal, type AnimatedState, Canvas, Circle, type ComponentFunction, type ComponentInstance, Container, DOMContainer, DOMElement, DisplayObject, EVENTS, Easing, type Element, Ellipse, Graphics, Mesh, NineSliceSprite, type OnHook, ParticlesEmitter, type Props, RadialGradient, Rect, Scene, Sprite, Svg, Text, TilingSprite, Triangle, utils as Utils, Video, Viewport, animatedSequence, animatedSignal, bootstrapCanvas, cond, createComponent, currentSubscriptionsTracker, h, isAnimatedSignal, isElement, isPrimitive, isTrigger, loop, mount, mountTracker, on, registerComponent, tick, trigger, useDefineProps, useProps };
package/dist/index.js CHANGED
@@ -38,12 +38,14 @@ __export(utils_exports, {
38
38
  isBrowser: () => isBrowser,
39
39
  isFunction: () => isFunction,
40
40
  isObject: () => isObject,
41
+ isObservable: () => isObservable,
41
42
  isPromise: () => isPromise,
42
43
  log: () => log,
43
44
  preciseNow: () => preciseNow,
44
45
  set: () => set,
45
46
  setObservablePoint: () => setObservablePoint
46
47
  });
48
+ import { Observable } from "rxjs";
47
49
  function isBrowser() {
48
50
  return typeof window !== "undefined";
49
51
  }
@@ -101,6 +103,9 @@ function isFunction(val) {
101
103
  function isObject(val) {
102
104
  return typeof val == "object" && val != null && !Array.isArray(val) && val.constructor === Object;
103
105
  }
106
+ function isObservable(val) {
107
+ return val instanceof Observable;
108
+ }
104
109
  function set(obj, path, value, onlyPlainObject = false) {
105
110
  if (Object(obj) !== obj) return obj;
106
111
  if (typeof path === "string") {
@@ -964,12 +969,13 @@ import { isSignal as isSignal2, signal as signal2 } from "@signe/reactive";
964
969
  // src/engine/reactive.ts
965
970
  import { isComputed, isSignal, signal } from "@signe/reactive";
966
971
  import {
967
- Observable,
972
+ Observable as Observable2,
968
973
  Subject,
969
974
  defer,
970
975
  from,
971
976
  map,
972
- of
977
+ of,
978
+ share
973
979
  } from "rxjs";
974
980
  var components = {};
975
981
  var isElement = (value) => {
@@ -1124,7 +1130,7 @@ function createComponent(tag, props) {
1124
1130
  if (isPromise(child)) {
1125
1131
  child = await child;
1126
1132
  }
1127
- if (child instanceof Observable) {
1133
+ if (child instanceof Observable2) {
1128
1134
  child.subscribe(
1129
1135
  ({
1130
1136
  elements: comp,
@@ -1171,7 +1177,7 @@ function loop(itemsSubject, createElementFn) {
1171
1177
  let elementMap = /* @__PURE__ */ new Map();
1172
1178
  let isFirstSubscription = true;
1173
1179
  const isArraySignal = (signal10) => Array.isArray(signal10());
1174
- return new Observable((subscriber) => {
1180
+ return new Observable2((subscriber) => {
1175
1181
  const subscription = isArraySignal(itemsSubject) ? itemsSubject.observable.subscribe((change) => {
1176
1182
  if (isFirstSubscription) {
1177
1183
  isFirstSubscription = false;
@@ -1324,7 +1330,7 @@ function cond(condition, createElementFn) {
1324
1330
  let element = null;
1325
1331
  if (isSignal(condition)) {
1326
1332
  const signalCondition = condition;
1327
- return new Observable((subscriber) => {
1333
+ return new Observable2((subscriber) => {
1328
1334
  return signalCondition.observable.subscribe((bool) => {
1329
1335
  if (bool) {
1330
1336
  let _el = createElementFn();
@@ -1354,7 +1360,7 @@ function cond(condition, createElementFn) {
1354
1360
  });
1355
1361
  }
1356
1362
  });
1357
- });
1363
+ }).pipe(share());
1358
1364
  } else {
1359
1365
  if (condition) {
1360
1366
  let _el = createElementFn();
@@ -3830,6 +3836,9 @@ function NineSliceSprite(props) {
3830
3836
 
3831
3837
  // src/components/DOMContainer.ts
3832
3838
  import { DOMContainer as PixiDOMContainer } from "pixi.js";
3839
+
3840
+ // src/components/DOMElement.ts
3841
+ import { isSignal as isSignal6 } from "@signe/reactive";
3833
3842
  var EVENTS4 = [
3834
3843
  "click",
3835
3844
  "mouseover",
@@ -3869,34 +3878,91 @@ var EVENTS4 = [
3869
3878
  "selectall",
3870
3879
  "selectnone"
3871
3880
  ];
3872
- var CanvasDOMContainer = class extends DisplayObject(PixiDOMContainer) {
3881
+ var CanvasDOMElement = class {
3873
3882
  constructor() {
3874
- super(...arguments);
3875
- this.disableLayout = true;
3876
3883
  this.eventListeners = /* @__PURE__ */ new Map();
3884
+ this.onBeforeDestroy = null;
3885
+ this.valueSignal = null;
3886
+ this.isFormElementType = false;
3887
+ }
3888
+ /**
3889
+ * Checks if the element is a form element that supports the value attribute
3890
+ * @param elementType - The element type string from props
3891
+ * @returns true if the element is a form element with value support
3892
+ */
3893
+ isFormElement(elementType) {
3894
+ const formElements = ["input", "textarea", "select"];
3895
+ return formElements.includes(elementType.toLowerCase());
3877
3896
  }
3878
3897
  onInit(props) {
3879
- super.onInit(props);
3880
- if (props.element === void 0) {
3881
- throw new Error("DOMContainer: element is required");
3882
- }
3883
3898
  if (typeof props.element === "string") {
3884
3899
  this.element = document.createElement(props.element);
3900
+ this.isFormElementType = this.isFormElement(props.element);
3885
3901
  } else {
3886
3902
  this.element = props.element.value;
3903
+ this.isFormElementType = this.isFormElement(this.element.tagName);
3904
+ }
3905
+ if (props.onBeforeDestroy || props["on-before-destroy"]) {
3906
+ this.onBeforeDestroy = props.onBeforeDestroy || props["on-before-destroy"];
3887
3907
  }
3888
3908
  for (const event of EVENTS4) {
3889
3909
  if (props.attrs?.[event]) {
3890
3910
  const eventHandler = (e) => {
3891
- props.attrs[event]?.(e);
3911
+ if (event === "submit" && this.element.tagName.toLowerCase() === "form") {
3912
+ e.preventDefault();
3913
+ const formData = new FormData(this.element);
3914
+ const formObject = {};
3915
+ formData.forEach((value, key) => {
3916
+ if (formObject[key]) {
3917
+ if (Array.isArray(formObject[key])) {
3918
+ formObject[key].push(value);
3919
+ } else {
3920
+ formObject[key] = [formObject[key], value];
3921
+ }
3922
+ } else {
3923
+ formObject[key] = value;
3924
+ }
3925
+ });
3926
+ props.attrs[event]?.(e, formObject);
3927
+ } else {
3928
+ props.attrs[event]?.(e);
3929
+ }
3892
3930
  };
3893
3931
  this.eventListeners.set(event, eventHandler);
3894
3932
  this.element.addEventListener(event, eventHandler, false);
3895
3933
  }
3896
3934
  }
3935
+ if (props.children) {
3936
+ for (const child of props.children) {
3937
+ if (isObservable(child)) {
3938
+ child.subscribe(({ elements }) => {
3939
+ for (const element of elements) {
3940
+ this.element.appendChild(element.componentInstance.element);
3941
+ }
3942
+ });
3943
+ } else {
3944
+ this.element.appendChild(child.componentInstance.element);
3945
+ }
3946
+ }
3947
+ }
3948
+ this.onUpdate(props);
3949
+ }
3950
+ onMount(context) {
3951
+ const props = context.propObservables;
3952
+ const attrs = props.attrs;
3953
+ if (this.isFormElementType && attrs?.value && isSignal6(attrs.value)) {
3954
+ this.valueSignal = attrs.value;
3955
+ this.element.value = this.valueSignal();
3956
+ const inputHandler = (e) => {
3957
+ const target = e.target;
3958
+ this.valueSignal.set(target.value);
3959
+ };
3960
+ this.eventListeners.set("input", inputHandler);
3961
+ this.element.addEventListener("input", inputHandler, false);
3962
+ }
3897
3963
  }
3898
3964
  onUpdate(props) {
3899
- super.onUpdate(props);
3965
+ if (!this.element) return;
3900
3966
  for (const [key, value] of Object.entries(props.attrs || {})) {
3901
3967
  if (key === "class") {
3902
3968
  const classList = value.items || value.value || value;
@@ -3923,6 +3989,16 @@ var CanvasDOMContainer = class extends DisplayObject(PixiDOMContainer) {
3923
3989
  }
3924
3990
  }
3925
3991
  }
3992
+ } else if (key === "value" && this.isFormElementType) {
3993
+ if (isSignal6(value)) {
3994
+ const currentValue = this.element.value;
3995
+ const signalValue = value();
3996
+ if (currentValue !== signalValue) {
3997
+ this.element.value = signalValue;
3998
+ }
3999
+ } else {
4000
+ this.element.value = value;
4001
+ }
3926
4002
  } else if (!EVENTS4.includes(key)) {
3927
4003
  this.element.setAttribute(key, value);
3928
4004
  }
@@ -3930,21 +4006,37 @@ var CanvasDOMContainer = class extends DisplayObject(PixiDOMContainer) {
3930
4006
  if (props.textContent) {
3931
4007
  this.element.textContent = props.textContent;
3932
4008
  }
3933
- if (props.sortableChildren !== void 0) {
3934
- this.sortableChildren = props.sortableChildren;
3935
- }
3936
4009
  }
3937
4010
  async onDestroy(parent, afterDestroy) {
3938
4011
  if (this.element) {
4012
+ if (this.onBeforeDestroy) {
4013
+ await this.onBeforeDestroy();
4014
+ }
3939
4015
  for (const [event, handler] of this.eventListeners) {
3940
4016
  this.element.removeEventListener(event, handler, false);
3941
4017
  }
3942
4018
  this.eventListeners.clear();
4019
+ this.element.remove();
4020
+ if (afterDestroy) {
4021
+ afterDestroy();
4022
+ }
3943
4023
  }
3944
- const _afterDestroyCallback = async () => {
3945
- afterDestroy();
3946
- };
3947
- await super.onDestroy(parent, _afterDestroyCallback);
4024
+ }
4025
+ };
4026
+ registerComponent("DOMElement", CanvasDOMElement);
4027
+ var DOMElement = (props) => {
4028
+ return createComponent("DOMElement", props);
4029
+ };
4030
+
4031
+ // src/components/DOMContainer.ts
4032
+ var CanvasDOMContainer = class extends DisplayObject(PixiDOMContainer) {
4033
+ constructor() {
4034
+ super(...arguments);
4035
+ this.disableLayout = true;
4036
+ }
4037
+ onInit(props) {
4038
+ const div = h(DOMElement, { element: "div" }, props.children);
4039
+ this.element = div.componentInstance.element;
3948
4040
  }
3949
4041
  };
3950
4042
  registerComponent("DOMContainer", CanvasDOMContainer);
@@ -3955,17 +4047,22 @@ var DOMContainer = (props) => {
3955
4047
  // src/engine/bootstrap.ts
3956
4048
  import "@pixi/layout";
3957
4049
  import { Application as Application3 } from "pixi.js";
3958
- var bootstrapCanvas = async (rootElement, canvas) => {
4050
+ var bootstrapCanvas = async (rootElement, canvas, options) => {
3959
4051
  const app = new Application3();
3960
4052
  await app.init({
3961
4053
  resizeTo: rootElement,
3962
- autoStart: false
4054
+ autoStart: false,
4055
+ ...options ?? {}
3963
4056
  });
3964
4057
  const canvasElement = await h(canvas);
3965
4058
  if (canvasElement.tag != "Canvas") {
3966
4059
  throw new Error("Canvas is required");
3967
4060
  }
3968
4061
  canvasElement.render(rootElement, app);
4062
+ const { backgroundColor } = useProps(canvasElement.props, {
4063
+ backgroundColor: "black"
4064
+ });
4065
+ app.renderer.background.color = backgroundColor();
3969
4066
  return {
3970
4067
  canvasElement,
3971
4068
  app
@@ -4097,13 +4194,14 @@ var RadialGradient = class {
4097
4194
  };
4098
4195
 
4099
4196
  // src/index.ts
4100
- import { isObservable } from "rxjs";
4197
+ import { isObservable as isObservable2 } from "rxjs";
4101
4198
  import * as Howl3 from "howler";
4102
4199
  export {
4103
4200
  Canvas2 as Canvas,
4104
4201
  Circle,
4105
4202
  Container4 as Container,
4106
4203
  DOMContainer,
4204
+ DOMElement,
4107
4205
  DisplayObject,
4108
4206
  EVENTS2 as EVENTS,
4109
4207
  Easing,
@@ -4134,7 +4232,7 @@ export {
4134
4232
  h,
4135
4233
  isAnimatedSignal,
4136
4234
  isElement,
4137
- isObservable,
4235
+ isObservable2 as isObservable,
4138
4236
  isPrimitive,
4139
4237
  isTrigger,
4140
4238
  loop,