@playcanvas/web-components 0.15.0 → 0.17.0

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.
Files changed (108) hide show
  1. package/dist/app.d.cts +14 -13
  2. package/dist/app.d.ts +14 -13
  3. package/dist/async-element.d.cts +13 -13
  4. package/dist/async-element.d.ts +13 -13
  5. package/dist/components/anim-clip.d.cts +127 -0
  6. package/dist/components/anim-clip.d.ts +127 -0
  7. package/dist/components/anim-component.d.cts +235 -0
  8. package/dist/components/anim-component.d.ts +235 -0
  9. package/dist/components/{listener-component.d.cts → audio-listener-component.d.cts} +7 -5
  10. package/dist/components/{listener-component.d.ts → audio-listener-component.d.ts} +7 -5
  11. package/dist/components/button-component.d.cts +5 -1
  12. package/dist/components/button-component.d.ts +5 -1
  13. package/dist/components/camera-component.d.cts +2 -0
  14. package/dist/components/camera-component.d.ts +2 -0
  15. package/dist/components/collision-component.d.cts +5 -1
  16. package/dist/components/collision-component.d.ts +5 -1
  17. package/dist/components/component.d.cts +3 -2
  18. package/dist/components/component.d.ts +3 -2
  19. package/dist/components/element-component.d.cts +7 -0
  20. package/dist/components/element-component.d.ts +7 -0
  21. package/dist/components/gsplat-component.d.cts +2 -0
  22. package/dist/components/gsplat-component.d.ts +2 -0
  23. package/dist/components/joint-component.d.cts +2 -0
  24. package/dist/components/joint-component.d.ts +2 -0
  25. package/dist/components/{layoutchild-component.d.cts → layout-child-component.d.cts} +3 -1
  26. package/dist/components/{layoutchild-component.d.ts → layout-child-component.d.ts} +3 -1
  27. package/dist/components/{layoutgroup-component.d.cts → layout-group-component.d.cts} +3 -1
  28. package/dist/components/{layoutgroup-component.d.ts → layout-group-component.d.ts} +3 -1
  29. package/dist/components/light-component.d.cts +2 -0
  30. package/dist/components/light-component.d.ts +2 -0
  31. package/dist/components/{particlesystem-component.d.cts → particle-system-component.d.cts} +3 -1
  32. package/dist/components/{particlesystem-component.d.ts → particle-system-component.d.ts} +3 -1
  33. package/dist/components/render-component.d.cts +2 -0
  34. package/dist/components/render-component.d.ts +2 -0
  35. package/dist/components/{rigidbody-component.d.cts → rigid-body-component.d.cts} +3 -1
  36. package/dist/components/{rigidbody-component.d.ts → rigid-body-component.d.ts} +3 -1
  37. package/dist/components/screen-component.d.cts +2 -0
  38. package/dist/components/screen-component.d.ts +2 -0
  39. package/dist/components/script-component.d.cts +23 -12
  40. package/dist/components/script-component.d.ts +23 -12
  41. package/dist/components/{script.d.cts → script-instance.d.cts} +7 -7
  42. package/dist/components/{script.d.ts → script-instance.d.ts} +7 -7
  43. package/dist/components/{scrollview-component.d.cts → scroll-view-component.d.cts} +3 -1
  44. package/dist/components/{scrollview-component.d.ts → scroll-view-component.d.ts} +3 -1
  45. package/dist/components/scrollbar-component.d.cts +2 -0
  46. package/dist/components/scrollbar-component.d.ts +2 -0
  47. package/dist/components/sound-component.d.cts +3 -1
  48. package/dist/components/sound-component.d.ts +3 -1
  49. package/dist/components/sound-slot.d.cts +2 -2
  50. package/dist/components/sound-slot.d.ts +2 -2
  51. package/dist/custom-elements.json +3154 -2005
  52. package/dist/entity-base.d.cts +6 -5
  53. package/dist/entity-base.d.ts +6 -5
  54. package/dist/entity-owner.d.cts +118 -0
  55. package/dist/entity-owner.d.ts +118 -0
  56. package/dist/entity.d.cts +8 -101
  57. package/dist/entity.d.ts +8 -101
  58. package/dist/index.d.cts +26 -21
  59. package/dist/index.d.ts +26 -21
  60. package/dist/model.d.cts +67 -24
  61. package/dist/model.d.ts +67 -24
  62. package/dist/pwc.cjs +1766 -619
  63. package/dist/pwc.cjs.map +1 -1
  64. package/dist/pwc.js +1766 -619
  65. package/dist/pwc.js.map +1 -1
  66. package/dist/pwc.min.js +1 -1
  67. package/dist/pwc.min.js.map +1 -1
  68. package/dist/pwc.min.mjs +1 -1
  69. package/dist/pwc.min.mjs.map +1 -1
  70. package/dist/pwc.mjs +1762 -618
  71. package/dist/pwc.mjs.map +1 -1
  72. package/dist/vscode.html-custom-data.json +203 -89
  73. package/dist/{module.d.cts → wasm.d.cts} +6 -6
  74. package/dist/{module.d.ts → wasm.d.ts} +6 -6
  75. package/dist/web-types.json +556 -273
  76. package/package.json +7 -7
  77. package/src/app.ts +45 -35
  78. package/src/async-element.ts +14 -14
  79. package/src/components/anim-clip.ts +395 -0
  80. package/src/components/anim-component.ts +719 -0
  81. package/src/components/{listener-component.ts → audio-listener-component.ts} +8 -6
  82. package/src/components/button-component.ts +5 -1
  83. package/src/components/camera-component.ts +2 -0
  84. package/src/components/collision-component.ts +5 -1
  85. package/src/components/component.ts +4 -3
  86. package/src/components/element-component.ts +7 -0
  87. package/src/components/gsplat-component.ts +2 -0
  88. package/src/components/joint-component.ts +2 -0
  89. package/src/components/{layoutchild-component.ts → layout-child-component.ts} +4 -2
  90. package/src/components/{layoutgroup-component.ts → layout-group-component.ts} +4 -2
  91. package/src/components/light-component.ts +2 -0
  92. package/src/components/{particlesystem-component.ts → particle-system-component.ts} +4 -2
  93. package/src/components/render-component.ts +2 -0
  94. package/src/components/{rigidbody-component.ts → rigid-body-component.ts} +4 -2
  95. package/src/components/screen-component.ts +2 -0
  96. package/src/components/script-component.ts +63 -42
  97. package/src/components/{script.ts → script-instance.ts} +14 -14
  98. package/src/components/{scrollview-component.ts → scroll-view-component.ts} +4 -2
  99. package/src/components/scrollbar-component.ts +2 -0
  100. package/src/components/sound-component.ts +4 -2
  101. package/src/components/sound-slot.ts +4 -4
  102. package/src/entity-base.ts +6 -5
  103. package/src/entity-owner.ts +298 -0
  104. package/src/entity.ts +15 -270
  105. package/src/index.ts +32 -24
  106. package/src/model.ts +159 -79
  107. package/src/node.ts +9 -5
  108. package/src/{module.ts → wasm.ts} +8 -8
@@ -25,10 +25,12 @@ const visibilities = new Map<'always' | 'when-required', number>([
25
25
 
26
26
  /**
27
27
  * The ScrollViewComponentElement interface provides properties and methods for manipulating
28
- * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-scrollview/ | `<pc-scrollview>`} elements.
28
+ * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-scroll-view/ | `<pc-scroll-view>`} elements.
29
29
  * The ScrollViewComponentElement interface also inherits the properties and methods of the
30
30
  * {@link HTMLElement} interface.
31
31
  *
32
+ * Engine component: {@link ScrollViewComponent} (`scrollview`).
33
+ *
32
34
  * @category Components
33
35
  */
34
36
  class ScrollViewComponentElement extends ComponentElement {
@@ -437,6 +439,6 @@ class ScrollViewComponentElement extends ComponentElement {
437
439
  }
438
440
  }
439
441
 
440
- customElements.define('pc-scrollview', ScrollViewComponentElement);
442
+ customElements.define('pc-scroll-view', ScrollViewComponentElement);
441
443
 
442
444
  export { ScrollViewComponentElement };
@@ -16,6 +16,8 @@ const orientations = new Map<'horizontal' | 'vertical', number>([
16
16
  * The ScrollbarComponentElement interface also inherits the properties and methods of the
17
17
  * {@link HTMLElement} interface.
18
18
  *
19
+ * Engine component: {@link ScrollbarComponent} (`scrollbar`).
20
+ *
19
21
  * @category Components
20
22
  */
21
23
  class ScrollbarComponentElement extends ComponentElement {
@@ -6,10 +6,12 @@ import { ComponentElement } from './component';
6
6
 
7
7
  /**
8
8
  * The SoundComponentElement interface provides properties and methods for manipulating
9
- * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-sounds/ | `<pc-sounds>`} elements.
9
+ * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-sound/ | `<pc-sound>`} elements.
10
10
  * The SoundComponentElement interface also inherits the properties and methods of the
11
11
  * {@link HTMLElement} interface.
12
12
  *
13
+ * Engine component: {@link SoundComponent} (`sound`).
14
+ *
13
15
  * @category Components
14
16
  */
15
17
  class SoundComponentElement extends ComponentElement {
@@ -227,6 +229,6 @@ class SoundComponentElement extends ComponentElement {
227
229
  }
228
230
  }
229
231
 
230
- customElements.define('pc-sounds', SoundComponentElement);
232
+ customElements.define('pc-sound', SoundComponentElement);
231
233
 
232
234
  export { SoundComponentElement };
@@ -8,7 +8,7 @@ import { SoundComponentElement } from './sound-component';
8
8
 
9
9
  /**
10
10
  * The SoundSlotElement interface provides properties and methods for manipulating
11
- * `<pc-sound>` elements. The SoundSlotElement interface also inherits the properties and
11
+ * `<pc-sound-slot>` elements. The SoundSlotElement interface also inherits the properties and
12
12
  * methods of the {@link AsyncElement} interface.
13
13
  */
14
14
  class SoundSlotElement extends AsyncElement {
@@ -31,7 +31,7 @@ class SoundSlotElement extends AsyncElement {
31
31
  private _volume = 1;
32
32
 
33
33
  /**
34
- * The `<pc-sounds>` this slot was added to, captured at connect time.
34
+ * The `<pc-sound>` this slot was added to, captured at connect time.
35
35
  *
36
36
  * `disconnectedCallback` cannot rediscover it: by the time the element is disconnected its
37
37
  * `parentElement` is already `null`, so a lookup would both fail to find the component and
@@ -106,7 +106,7 @@ class SoundSlotElement extends AsyncElement {
106
106
  const soundElement = this.parentElement as SoundComponentElement;
107
107
 
108
108
  if (!(soundElement instanceof SoundComponentElement)) {
109
- console.warn('pc-sound must be a direct child of a pc-sounds element');
109
+ console.warn('pc-sound-slot must be a direct child of a pc-sound element');
110
110
  return null;
111
111
  }
112
112
 
@@ -324,6 +324,6 @@ class SoundSlotElement extends AsyncElement {
324
324
  }
325
325
  }
326
326
 
327
- customElements.define('pc-sound', SoundSlotElement);
327
+ customElements.define('pc-sound-slot', SoundSlotElement);
328
328
 
329
329
  export { SoundSlotElement };
@@ -17,11 +17,12 @@ export const POINTER_ATTRIBUTES = [
17
17
  ] as const;
18
18
 
19
19
  /**
20
- * The base class for elements that front an engine {@link Entity}: `<pc-entity>`, which creates
21
- * one, and `<pc-node>`, which binds to one inside a model's instantiated hierarchy. It carries
22
- * what both need — the `entity` contract, registration with the owning application (which joins
23
- * picked scene nodes back to elements by identity, never by name), and the pointer listener
24
- * bookkeeping that lets the application lazily attach its canvas handlers.
20
+ * The base class for elements that front an engine {@link Entity}: `<pc-entity>` and
21
+ * `<pc-model>`, which create one, and `<pc-node>`, which binds to one inside a model's
22
+ * instantiated hierarchy. It carries what all of them need — the `entity` contract, registration
23
+ * with the owning application (which joins picked scene nodes back to elements by identity,
24
+ * never by name), and the pointer listener bookkeeping that lets the application lazily attach
25
+ * its canvas handlers.
25
26
  */
26
27
  class EntityBaseElement extends AsyncElement {
27
28
  protected _entity: Entity | null = null;
@@ -0,0 +1,298 @@
1
+ import type { AppBase } from 'playcanvas';
2
+ import { Entity, Vec3 } from 'playcanvas';
3
+
4
+ import { EntityBaseElement } from './entity-base';
5
+
6
+ /**
7
+ * Creates and parents the entities of every descendant entity-owning element of `root`, in two
8
+ * passes so that no parent's existence depends on document order. Called wherever a subtree could
9
+ * not build itself: an element inserted into an application that is already running, and a
10
+ * `<pc-node>` whose children waited for it to bind.
11
+ *
12
+ * Descendants that are not yet custom elements are skipped, because there is nothing useful to do
13
+ * for them and reaching for `_createEntity` would throw. A subtree cloned from a `<template>`
14
+ * arrives entirely unupgraded — template content lives in an inert document, where custom element
15
+ * definitions are never looked up — and appending the clone upgrades its elements in tree order,
16
+ * an element before its descendants. So a sweep from an element's own `connectedCallback` sees
17
+ * plain `HTMLElement`s below it. Each becomes an entity-owning element moments later and its own
18
+ * `connectedCallback` creates and parents it, by which time the ancestor it parents under has its
19
+ * entity — the same guarantee tree order gives this sweep.
20
+ *
21
+ * @param root - The element whose descendant entities to build.
22
+ * @param app - The application to create the entities in.
23
+ * @internal
24
+ */
25
+ export const buildDescendantEntities = (root: Element, app: AppBase) => {
26
+ const children = Array.from(root.querySelectorAll('pc-entity, pc-model')).filter(
27
+ (child): child is EntityOwnerElement => child instanceof EntityOwnerElement
28
+ );
29
+ children.forEach((child) => child._createEntity(app));
30
+ children.forEach((child) => child._buildHierarchy(app));
31
+ };
32
+
33
+ /**
34
+ * The base class for elements that create and own their backing entity: `<pc-entity>` and
35
+ * `<pc-model>`, whose host entity carries the same authored properties. It carries the cached
36
+ * property state, entity creation and parenting, and the reset that follows the entity's
37
+ * destruction. `<pc-node>` sits outside this class: it borrows an entity a model instantiated,
38
+ * and its properties are nullable overrides rather than owned values.
39
+ */
40
+ class EntityOwnerElement extends EntityBaseElement {
41
+ /**
42
+ * Whether the entity is enabled.
43
+ */
44
+ private _enabled = true;
45
+
46
+ /**
47
+ * The name of the entity.
48
+ */
49
+ private _name = 'Untitled';
50
+
51
+ /**
52
+ * The position of the entity.
53
+ */
54
+ private _position = new Vec3();
55
+
56
+ /**
57
+ * The rotation of the entity.
58
+ */
59
+ private _rotation = new Vec3();
60
+
61
+ /**
62
+ * The scale of the entity.
63
+ */
64
+ private _scale = new Vec3(1, 1, 1);
65
+
66
+ /**
67
+ * The tags of the entity.
68
+ */
69
+ private _tags: string[] = [];
70
+
71
+ /**
72
+ * Whether the hierarchy has been built for this entity — set once {@link _buildHierarchy} has
73
+ * parented it. Read by subclasses that gate work on the entity being in the scene graph.
74
+ */
75
+ protected _built = false;
76
+
77
+ /**
78
+ * Creates the backing entity. Called by the containing `<pc-app>` element during its boot
79
+ * sweep, and on connection for elements inserted while the application is already running.
80
+ *
81
+ * @param app - The application to create the entity in.
82
+ * @internal
83
+ */
84
+ _createEntity(app: AppBase) {
85
+ // Guard against double creation. When a subtree is inserted at runtime (e.g. cloning a
86
+ // `<template>`), an ancestor's connectedCallback eagerly creates descendant entities; the
87
+ // descendants' own connectedCallbacks would otherwise create them a second time.
88
+ if (this._entity) {
89
+ return;
90
+ }
91
+
92
+ // Seed from the cached fields rather than re-reading the attributes. Every observed
93
+ // attribute is routed through its property setter by attributeChangedCallback, so the field
94
+ // already holds the parsed attribute value - and it also holds anything assigned through the
95
+ // property API before the app booted, which reading the attribute back would discard.
96
+ const entity = new Entity(this._name, app);
97
+ this._entity = entity;
98
+
99
+ entity.enabled = this._enabled;
100
+ entity.setLocalPosition(this._position);
101
+ entity.setLocalEulerAngles(this._rotation);
102
+ entity.setLocalScale(this._scale);
103
+
104
+ if (this._tags.length > 0) {
105
+ entity.tags.add(this._tags);
106
+ }
107
+
108
+ // Register with the owning application and hook the entity's destruction. The engine
109
+ // fires 'destroy' for every entity in a destroyed subtree, so the element learns of its
110
+ // entity's death no matter who causes it: this element, an ancestor, the whole
111
+ // application, or a user script calling entity.destroy().
112
+ this._registerEntity(entity);
113
+ entity.once('destroy', this._onEntityDestroy, this);
114
+ }
115
+
116
+ /**
117
+ * Handles the destruction of the backing entity. Resets the element so a later re-insertion
118
+ * starts clean: `_built` must be cleared alongside `_entity`, or _buildHierarchy would bail
119
+ * and a re-created entity would never be parented. Readiness is re-armed for the same
120
+ * reason — with the entity gone, a resolved ready promise would resume its awaiters against
121
+ * a null `entity`.
122
+ *
123
+ * @param entity - The entity that was destroyed.
124
+ */
125
+ protected _onEntityDestroy(entity: Entity) {
126
+ this._unregisterEntity(entity);
127
+ this._entity = null;
128
+ this._built = false;
129
+ this._resetReady();
130
+ }
131
+
132
+ /**
133
+ * Parents the backing entity: under the entity of the nearest ancestor `<pc-entity>`,
134
+ * `<pc-model>` or `<pc-node>` when there is one, and under the application root otherwise.
135
+ * Called by the containing `<pc-app>` element once a sweep has created every entity, so a
136
+ * parent's existence never depends on document order.
137
+ *
138
+ * @param app - The application whose root adopts parentless entities.
139
+ * @internal
140
+ */
141
+ _buildHierarchy(app: AppBase) {
142
+ if (!this.entity || this._built) return;
143
+
144
+ const closestEntity = this.closestEntity;
145
+
146
+ // A host element without an entity is an unresolved `<pc-node>`: building now would
147
+ // mis-anchor this entity to the application root while the host is still resolving.
148
+ // Stay unbuilt - the host drives this subtree itself once it binds.
149
+ if (closestEntity && !closestEntity.entity) {
150
+ return;
151
+ }
152
+
153
+ // An owner that exists but is not yet parented is itself deferred behind an unresolved
154
+ // node further up. Building beneath it would announce readiness for an entity that is
155
+ // not in the scene graph; stay unbuilt with it - the node's bind sweeps the whole
156
+ // subtree, ancestors before descendants.
157
+ if (closestEntity instanceof EntityOwnerElement && !closestEntity._built) {
158
+ return;
159
+ }
160
+
161
+ this._built = true;
162
+
163
+ if (closestEntity?.entity) {
164
+ closestEntity.entity.addChild(this.entity);
165
+ } else {
166
+ app.root.addChild(this.entity);
167
+ }
168
+
169
+ this._onBuilt();
170
+ }
171
+
172
+ /**
173
+ * Called by {@link _buildHierarchy} once the backing entity has been parented — exactly once
174
+ * per build cycle. The default announces readiness, which is what a parented `<pc-entity>`
175
+ * means; `<pc-model>` overrides it to start loading content instead, because its readiness
176
+ * tracks the content settling rather than the host entering the scene graph.
177
+ */
178
+ protected _onBuilt() {
179
+ this._onReady();
180
+ }
181
+
182
+ /**
183
+ * Sets the enabled state of the entity.
184
+ * @param value - Whether the entity is enabled.
185
+ */
186
+ set enabled(value) {
187
+ this._enabled = value;
188
+ if (this.entity) {
189
+ this.entity.enabled = value;
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Gets the enabled state of the entity.
195
+ * @returns Whether the entity is enabled.
196
+ */
197
+ get enabled() {
198
+ return this._enabled;
199
+ }
200
+
201
+ /**
202
+ * Sets the name of the entity.
203
+ * @param value - The name of the entity.
204
+ */
205
+ set name(value) {
206
+ this._name = value;
207
+ if (this.entity) {
208
+ this.entity.name = value;
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Gets the name of the entity.
214
+ * @returns The name of the entity.
215
+ */
216
+ get name() {
217
+ return this._name;
218
+ }
219
+
220
+ /**
221
+ * Sets the position of the entity.
222
+ * @param value - The position of the entity.
223
+ */
224
+ set position(value) {
225
+ this._position = value;
226
+ if (this.entity) {
227
+ this.entity.setLocalPosition(this._position);
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Gets the position of the entity.
233
+ * @returns The position of the entity.
234
+ */
235
+ get position() {
236
+ return this._position;
237
+ }
238
+
239
+ /**
240
+ * Sets the rotation of the entity.
241
+ * @param value - The rotation of the entity.
242
+ */
243
+ set rotation(value) {
244
+ this._rotation = value;
245
+ if (this.entity) {
246
+ this.entity.setLocalEulerAngles(this._rotation);
247
+ }
248
+ }
249
+
250
+ /**
251
+ * Gets the rotation of the entity.
252
+ * @returns The rotation of the entity.
253
+ */
254
+ get rotation() {
255
+ return this._rotation;
256
+ }
257
+
258
+ /**
259
+ * Sets the scale of the entity.
260
+ * @param value - The scale of the entity.
261
+ */
262
+ set scale(value) {
263
+ this._scale = value;
264
+ if (this.entity) {
265
+ this.entity.setLocalScale(this._scale);
266
+ }
267
+ }
268
+
269
+ /**
270
+ * Gets the scale of the entity.
271
+ * @returns The scale of the entity.
272
+ */
273
+ get scale() {
274
+ return this._scale;
275
+ }
276
+
277
+ /**
278
+ * Sets the tags of the entity.
279
+ * @param value - The tags of the entity.
280
+ */
281
+ set tags(value) {
282
+ this._tags = value;
283
+ if (this.entity) {
284
+ this.entity.tags.clear();
285
+ this.entity.tags.add(this._tags);
286
+ }
287
+ }
288
+
289
+ /**
290
+ * Gets the tags of the entity.
291
+ * @returns The tags of the entity.
292
+ */
293
+ get tags() {
294
+ return this._tags;
295
+ }
296
+ }
297
+
298
+ export { EntityOwnerElement };