@playcanvas/web-components 0.11.1 → 0.12.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.
@@ -0,0 +1,67 @@
1
+ import type { Entity } from 'playcanvas';
2
+ import type { AppElement } from './app';
3
+ import { AsyncElement } from './async-element';
4
+ /**
5
+ * The attribute names of the inline `onpointer*` event handlers, shared by every element that
6
+ * fronts an engine entity. Spread into `observedAttributes` by subclasses.
7
+ * @ignore
8
+ */
9
+ declare const POINTER_ATTRIBUTES: readonly ["onpointerenter", "onpointerleave", "onpointerdown", "onpointerup", "onpointermove"];
10
+ /**
11
+ * The base class for elements that front an engine {@link Entity}: `<pc-entity>`, which creates
12
+ * one, and `<pc-node>`, which binds to one inside a model's instantiated hierarchy. It carries
13
+ * what both need — the `entity` contract, registration with the owning application (which joins
14
+ * picked scene nodes back to elements by identity, never by name), and the pointer listener
15
+ * bookkeeping that lets the application lazily attach its canvas handlers.
16
+ */
17
+ declare class EntityBaseElement extends AsyncElement {
18
+ protected _entity: Entity | null;
19
+ /**
20
+ * The application element this entity is registered with, cached at registration time so the
21
+ * entity can be unregistered even once this element has left the DOM.
22
+ */
23
+ protected _appElement: AppElement | null;
24
+ /**
25
+ * The pointer event listeners for the entity.
26
+ */
27
+ private _listeners;
28
+ /**
29
+ * The event types for which an inline `onpointer*` attribute is currently present.
30
+ */
31
+ private _inlineHandlerTypes;
32
+ /**
33
+ * The PlayCanvas entity instance. `null` until the element is ready, and again once the
34
+ * entity is gone — await {@link whenReady} or the element's `ready()` promise before
35
+ * accessing it.
36
+ * @returns The entity instance, or `null`.
37
+ */
38
+ get entity(): Entity | null;
39
+ /**
40
+ * Registers `entity` as this element's backing entity with the owning application, which
41
+ * joins engine nodes back to elements by identity (never by name).
42
+ *
43
+ * @param entity - The entity to register.
44
+ */
45
+ protected _registerEntity(entity: Entity): void;
46
+ /**
47
+ * Removes the registration for `entity`.
48
+ *
49
+ * @param entity - The entity to unregister.
50
+ */
51
+ protected _unregisterEntity(entity: Entity): void;
52
+ /**
53
+ * Tracks whether an inline `onpointer*` attribute is present. The browser itself compiles and
54
+ * runs these attributes — they are standard `GlobalEventHandlers`, so setting one replaces
55
+ * the previous handler and removing it removes the handler, exactly like `onclick` on any
56
+ * HTML element. But because they bypass {@link addEventListener}, the connect/disconnect
57
+ * bookkeeping that lets the application lazily attach its canvas pointer handlers must be
58
+ * kept in sync here.
59
+ *
60
+ * @param name - The attribute name (e.g. 'onpointerdown').
61
+ * @param value - The attribute value, or `null` when the attribute has been removed.
62
+ */
63
+ protected _updateInlineHandler(name: string, value: string | null): void;
64
+ addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
65
+ removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
66
+ }
67
+ export { EntityBaseElement, POINTER_ATTRIBUTES };
package/dist/entity.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Entity, Vec3 } from 'playcanvas';
2
- import { AsyncElement } from './async-element';
1
+ import { Vec3 } from 'playcanvas';
2
+ import { EntityBaseElement } from './entity-base';
3
3
  /**
4
4
  * The EntityElement interface provides properties and methods for manipulating
5
5
  * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-entity/ | `<pc-entity>`} elements.
@@ -24,7 +24,7 @@ import { AsyncElement } from './async-element';
24
24
  * @fires {PointerEvent} pointerdown - Fired when a pointer button is pressed over the entity.
25
25
  * @fires {PointerEvent} pointerup - Fired when a pointer button is released over the entity.
26
26
  */
27
- declare class EntityElement extends AsyncElement {
27
+ declare class EntityElement extends EntityBaseElement {
28
28
  /**
29
29
  * Whether the entity is enabled.
30
30
  */
@@ -49,31 +49,10 @@ declare class EntityElement extends AsyncElement {
49
49
  * The tags of the entity.
50
50
  */
51
51
  private _tags;
52
- /**
53
- * The pointer event listeners for the entity.
54
- */
55
- private _listeners;
56
- /**
57
- * The event types for which an inline `onpointer*` attribute is currently present.
58
- */
59
- private _inlineHandlerTypes;
60
52
  /**
61
53
  * Whether the hierarchy has been built for this entity.
62
54
  */
63
55
  private _built;
64
- private _entity;
65
- /**
66
- * The application element this entity is registered with, cached at creation time so the
67
- * entity can be unregistered even once this element has left the DOM.
68
- */
69
- private _appElement;
70
- /**
71
- * The PlayCanvas entity instance. `null` until the element is ready, and again once it has
72
- * been removed from the document — await {@link whenReady} or the element's `ready()`
73
- * promise before accessing it.
74
- * @returns The entity instance, or `null`.
75
- */
76
- get entity(): Entity | null;
77
56
  /**
78
57
  * Handles the destruction of the backing entity. Resets the element so a later re-insertion
79
58
  * starts clean: `_built` must be cleared alongside `_entity`, or _buildHierarchy would bail
@@ -146,21 +125,7 @@ declare class EntityElement extends AsyncElement {
146
125
  * @returns The tags of the entity.
147
126
  */
148
127
  get tags(): string[];
149
- /**
150
- * Tracks whether an inline `onpointer*` attribute is present. The browser itself compiles and
151
- * runs these attributes — they are standard `GlobalEventHandlers`, so setting one replaces
152
- * the previous handler and removing it removes the handler, exactly like `onclick` on any
153
- * HTML element. But because they bypass {@link addEventListener}, the connect/disconnect
154
- * bookkeeping that lets the application lazily attach its canvas pointer handlers must be
155
- * kept in sync here.
156
- *
157
- * @param name - The attribute name (e.g. 'onpointerdown').
158
- * @param value - The attribute value, or `null` when the attribute has been removed.
159
- */
160
- private _updateInlineHandler;
161
128
  static get observedAttributes(): string[];
162
129
  attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null): void;
163
- addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
164
- removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
165
130
  }
166
131
  export { EntityElement };
package/dist/index.d.ts CHANGED
@@ -31,8 +31,10 @@ import { ScriptElement } from './components/script';
31
31
  import { SoundComponentElement } from './components/sound-component';
32
32
  import { SoundSlotElement } from './components/sound-slot';
33
33
  import { GSplatComponentElement } from './components/gsplat-component';
34
+ import { EntityBaseElement } from './entity-base';
34
35
  import { MaterialElement } from './material';
35
36
  import { ModelElement } from './model';
37
+ import { NodeElement } from './node';
36
38
  import { SceneElement } from './scene';
37
39
  import { SkyElement } from './sky';
38
40
  import type { ScriptAttributesChangeEvent, ScriptEnableChangeEvent, ScriptNameChangeEvent } from './components/script-component';
@@ -58,6 +60,7 @@ declare global {
58
60
  'pc-material': MaterialElement;
59
61
  'pc-model': ModelElement;
60
62
  'pc-module': ModuleElement;
63
+ 'pc-node': NodeElement;
61
64
  'pc-particles': ParticleSystemComponentElement;
62
65
  'pc-render': RenderComponentElement;
63
66
  'pc-rigidbody': RigidBodyComponentElement;
@@ -72,5 +75,5 @@ declare global {
72
75
  'pc-sounds': SoundComponentElement;
73
76
  }
74
77
  }
75
- export { AsyncElement, ModuleElement, AppElement, EntityElement, AssetElement, ButtonComponentElement, CameraComponentElement, CollisionComponentElement, ComponentElement, ElementComponentElement, LayoutChildComponentElement, LayoutGroupComponentElement, ParticleSystemComponentElement, LightComponentElement, ListenerComponentElement, RenderComponentElement, RigidBodyComponentElement, ScreenComponentElement, ScrollbarComponentElement, ScrollViewComponentElement, ScriptComponentElement, ScriptElement, SoundComponentElement, SoundSlotElement, GSplatComponentElement, MaterialElement, ModelElement, SceneElement, SkyElement, whenReady };
78
+ export { AsyncElement, ModuleElement, AppElement, EntityElement, AssetElement, ButtonComponentElement, CameraComponentElement, CollisionComponentElement, ComponentElement, ElementComponentElement, LayoutChildComponentElement, LayoutGroupComponentElement, ParticleSystemComponentElement, LightComponentElement, ListenerComponentElement, RenderComponentElement, RigidBodyComponentElement, ScreenComponentElement, ScrollbarComponentElement, ScrollViewComponentElement, ScriptComponentElement, ScriptElement, SoundComponentElement, SoundSlotElement, GSplatComponentElement, EntityBaseElement, MaterialElement, ModelElement, NodeElement, SceneElement, SkyElement, whenReady };
76
79
  export type { AsyncElementTagName } from './async-element';
@@ -160,7 +160,8 @@ declare class MaterialElement extends HTMLElement {
160
160
  private _setMap;
161
161
  /**
162
162
  * @param slot - The material property to write.
163
- * @param texture - The loaded texture.
163
+ * @param texture - The loaded texture, applied with its sampler state untouched - anisotropy
164
+ * and friends belong to the `pc-asset`'s texture options.
164
165
  */
165
166
  private _applyMap;
166
167
  /**
package/dist/model.d.ts CHANGED
@@ -5,6 +5,21 @@ import { AsyncElement } from './async-element';
5
5
  * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-model/ | `<pc-model>`} elements.
6
6
  * The ModelElement interface also inherits the properties and methods of the
7
7
  * {@link HTMLElement} interface.
8
+ *
9
+ * The element becomes ready once its container asset has loaded and the instantiated hierarchy has
10
+ * been added to the scene — `entity` is non-null by then. A failed load also settles readiness,
11
+ * with `entity` remaining `null`: readiness means the load settled, not that it succeeded — listen
12
+ * for `error`, or check `entity`, to tell the outcomes apart. Changing `asset` re-arms readiness
13
+ * and instantiates anew, so a `ready()` obtained after the change resolves against the new
14
+ * hierarchy. A `pc-model` outside a `pc-app`, or referencing an unknown asset id, warns and never
15
+ * becomes ready.
16
+ *
17
+ * @fires {Event} load - Fired each time a container asset finishes instantiating, including
18
+ * re-instantiation after `asset` changes. Does not bubble — listen on this element, or use a
19
+ * capture-phase listener on an ancestor.
20
+ * @fires {ErrorEvent} error - Fired when the container asset fails to load, with the engine's
21
+ * error in `message`. Does not bubble. The element still becomes ready — readiness means the load
22
+ * settled, not that it succeeded.
8
23
  */
9
24
  declare class ModelElement extends AsyncElement {
10
25
  private _asset;
@@ -17,11 +32,12 @@ declare class ModelElement extends AsyncElement {
17
32
  */
18
33
  private _loadGeneration;
19
34
  /**
20
- * The pending asset-load subscription of the current load, if it is waiting for its asset.
21
- * Held so that whatever supersedes the load can detach the handler from the asset, rather
22
- * than leave it registered until the asset loads (or forever, if it never does).
35
+ * The pending asset subscriptions of the current load, if it is waiting for its asset. Held
36
+ * so that whatever supersedes the load can detach the handlers from the asset, rather than
37
+ * leave them registered until the asset settles (or forever, if it never does).
23
38
  */
24
39
  private _loadHandle;
40
+ private _errorHandle;
25
41
  /**
26
42
  * The root entity of the instantiated model. `null` until the container asset has loaded
27
43
  * and been instantiated, and again once the element has been removed from the document.
@@ -30,7 +46,13 @@ declare class ModelElement extends AsyncElement {
30
46
  get entity(): Entity | null;
31
47
  connectedCallback(): void;
32
48
  disconnectedCallback(): void;
33
- private _detachLoadHandler;
49
+ private _detachLoadHandlers;
50
+ /**
51
+ * Resolves readiness and dispatches the `load` event. Called once the instantiated hierarchy
52
+ * has been parented — readiness means "in the scene graph", matching `pc-entity`, so a ready
53
+ * model's entity always has world transforms.
54
+ */
55
+ private _announceLoad;
34
56
  private _instantiate;
35
57
  private _loadModel;
36
58
  private _unloadModel;
package/dist/node.d.ts ADDED
@@ -0,0 +1,253 @@
1
+ import { Vec3 } from 'playcanvas';
2
+ import { EntityBaseElement } from './entity-base';
3
+ /**
4
+ * The binding states a `<pc-node>` element moves through. `pending` while the host has not yet
5
+ * instantiated (or no `name` is assigned), `bound` once a node has been resolved and decorated,
6
+ * `missing`/`ambiguous`/`duplicate` when resolution failed — each accompanied by a warning
7
+ * naming the cause.
8
+ */
9
+ type NodeBindingState = 'pending' | 'bound' | 'missing' | 'ambiguous' | 'duplicate';
10
+ /**
11
+ * The NodeElement interface provides properties and methods for manipulating
12
+ * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-node/ | `<pc-node>`}
13
+ * elements. The NodeElement interface also inherits the properties and methods of the
14
+ * {@link HTMLElement} interface.
15
+ *
16
+ * A `pc-node` is an override element: where `pc-entity` creates an entity, `pc-node` binds to a
17
+ * node a `pc-model` loaded and declares overrides against the authored asset — components to
18
+ * add, properties to change, content to attach. Attributes present apply as overrides; attributes
19
+ * absent leave authored values untouched, and removing an attribute (or assigning `null` to the
20
+ * matching property) restores the authored value.
21
+ *
22
+ * `name` selects among the host model's nodes (first match in depth-first order), nesting a
23
+ * `pc-node` inside another scopes the search to that subtree, and `index` picks among identically
24
+ * named matches. When `name` matches more than one node and no `index` is given, the element
25
+ * warns and binds nothing.
26
+ *
27
+ * The element becomes ready once bound, and never while unresolved — a missing or ambiguous
28
+ * name warns and records the failure in `state`, readiness stays unresolved, and descendants
29
+ * wait with it.
30
+ *
31
+ * The pointer events below are dispatched by the containing `<pc-app>` element when the pointer
32
+ * intersects the bound node's geometry, exactly as for `<pc-entity>`.
33
+ *
34
+ * @attribute {string} name - The name of the node to bind, resolved within the nearest ancestor
35
+ * `pc-model` (or `pc-node`) once it has instantiated.
36
+ * @attribute {number} index - Which match to bind when `name` matches more than one node,
37
+ * 0-based in depth-first order. Optional for a unique match; required for an ambiguous one.
38
+ * @attribute {boolean} enabled - Overrides the node's enabled state.
39
+ * @attribute {string} position - Overrides the node's local position, as an "x y z" triple.
40
+ * @attribute {string} rotation - Overrides the node's local rotation (Euler angles), as an
41
+ * "x y z" triple.
42
+ * @attribute {string} scale - Overrides the node's local scale, as an "x y z" triple.
43
+ * @attribute {string} tags - Overrides the node's tags, separated by spaces or commas.
44
+ * @attribute {string} onpointerenter - Script to run when the pointer moves onto the node.
45
+ * @attribute {string} onpointerleave - Script to run when the pointer moves off the node.
46
+ * @attribute {string} onpointermove - Script to run when the pointer moves over the node.
47
+ * @attribute {string} onpointerdown - Script to run when a pointer button is pressed over the
48
+ * node.
49
+ * @attribute {string} onpointerup - Script to run when a pointer button is released over the
50
+ * node.
51
+ * @fires {PointerEvent} pointerenter - Fired when the pointer moves onto the node.
52
+ * @fires {PointerEvent} pointerleave - Fired when the pointer moves off the node.
53
+ * @fires {PointerEvent} pointermove - Fired when the pointer moves over the node.
54
+ * @fires {PointerEvent} pointerdown - Fired when a pointer button is pressed over the node.
55
+ * @fires {PointerEvent} pointerup - Fired when a pointer button is released over the node.
56
+ */
57
+ declare class NodeElement extends EntityBaseElement {
58
+ private _name;
59
+ private _index;
60
+ private _state;
61
+ private _path;
62
+ /**
63
+ * The element whose entity roots this element's search: the nearest ancestor `pc-node`, or
64
+ * failing that the nearest ancestor `pc-model`. Resolved on connection.
65
+ */
66
+ private _host;
67
+ /**
68
+ * The listener following the host's binding cycles. Both host kinds announce each cycle
69
+ * with a `ready` event — `pc-model` on every instantiation, `pc-node` on every bind.
70
+ */
71
+ private _hostListener;
72
+ /**
73
+ * The subscription to the bound entity's destruction, detached on unbind so a retargeted
74
+ * element cannot be reset by the eventual death of a node it no longer fronts.
75
+ */
76
+ private _destroyHandle;
77
+ /** The authored values displaced by this element's overrides, captured per property. */
78
+ private _authored;
79
+ private _enabled;
80
+ private _position;
81
+ private _rotation;
82
+ private _scale;
83
+ private _tags;
84
+ /**
85
+ * The binding state: `pending` until the host instantiates and `name` resolves, `bound`
86
+ * once decorated, `missing`/`ambiguous`/`duplicate` when resolution failed (each also
87
+ * warns). Useful for asserting a document's bindings programmatically.
88
+ * @returns The binding state.
89
+ */
90
+ get state(): NodeBindingState;
91
+ /**
92
+ * The path of the bound node below the search root, `/`-separated, or `null` while not
93
+ * bound.
94
+ * @returns The bound node's path, or `null`.
95
+ */
96
+ get path(): string | null;
97
+ connectedCallback(): void;
98
+ disconnectedCallback(): void;
99
+ /**
100
+ * Re-resolves the binding against the host's current hierarchy: on connection, on a `name`
101
+ * or `index` change, and on every host cycle (a model [re]instantiating, an enclosing
102
+ * `pc-node` [re]binding). When re-resolution yields the entity already bound, the binding
103
+ * is retained untouched — a redundant edit must not flicker overrides through a revert.
104
+ */
105
+ private _rebind;
106
+ /**
107
+ * Resolves `name` (and `index`) to an entity under `hostEntity`, warning and recording the
108
+ * failure state when it cannot.
109
+ *
110
+ * @param hostEntity - The root of the search.
111
+ * @returns The resolved entity, or `null`.
112
+ */
113
+ private _resolve;
114
+ /**
115
+ * Binds `target`: registers it (making it a pick target), hooks its destruction, applies
116
+ * this element's overrides, announces readiness and builds the deferred child subtree.
117
+ *
118
+ * @param target - The entity to bind.
119
+ * @param hostEntity - The search root, for the path.
120
+ */
121
+ private _bind;
122
+ /**
123
+ * Dissolves the current binding, restoring every authored value this element's overrides
124
+ * displaced and removing the decorations this binding hosts: attachment entities are
125
+ * destroyed (re-created against the next binding) and component decorations are removed
126
+ * from the abandoned node. Both sweeps are scoped by `closestEntity`, so a still-bound
127
+ * nested `pc-node` keeps its own decorations. Safe to call in any state.
128
+ */
129
+ private _unbind;
130
+ /**
131
+ * Handles the destruction of the bound entity - its model unloading, reloading, or a script
132
+ * destroying it. There is nothing to revert on a destroyed entity; the element returns to
133
+ * pending and the host's next cycle re-resolves it.
134
+ */
135
+ private _onEntityDestroy;
136
+ /**
137
+ * Creates and parents the entities of child `pc-entity` elements - the attachment points.
138
+ * Mirrors the runtime-insertion path in EntityElement.connectedCallback: children were
139
+ * deferred while this host was unresolved (or reset when a previous binding dissolved), and
140
+ * build here once it binds.
141
+ */
142
+ private _buildChildren;
143
+ /**
144
+ * Applies every override that is explicitly set, capturing the authored value it displaces.
145
+ */
146
+ private _applyOverrides;
147
+ /**
148
+ * Restores every authored value this element's overrides displaced. The override values
149
+ * themselves are kept - they re-apply on the next binding.
150
+ */
151
+ private _revertOverrides;
152
+ /**
153
+ * Renders the path of `node` below `root`, for the `path` property and the resolution
154
+ * warnings.
155
+ *
156
+ * @param node - The node to describe.
157
+ * @param root - The search root.
158
+ * @returns The `/`-separated path.
159
+ */
160
+ private _pathOf;
161
+ /**
162
+ * Describes the search root for warnings: the model's asset id, or the enclosing node's
163
+ * name.
164
+ * @returns The description.
165
+ */
166
+ private _describeHost;
167
+ /**
168
+ * Finds the node name nearest to the missing `name`, for the miss warning. The names are
169
+ * already in hand from resolution, so the suggestion is nearly free.
170
+ *
171
+ * @param hostEntity - The root of the search.
172
+ * @returns The closest name within an edit distance of 2, or `null`.
173
+ */
174
+ private _closestName;
175
+ /**
176
+ * Sets the name of the node to bind. A change retargets: the current binding's overrides
177
+ * revert and the new name resolves afresh. `name` on a `pc-node` is never a rename of the
178
+ * authored node - it is only ever a reference.
179
+ * @param value - The node name.
180
+ */
181
+ set name(value: string);
182
+ /**
183
+ * Gets the name of the node to bind.
184
+ * @returns The node name.
185
+ */
186
+ get name(): string;
187
+ /**
188
+ * Sets which match to bind when `name` matches more than one node, 0-based in depth-first
189
+ * order. A change retargets, like `name`. `null` means unset - required when the name is
190
+ * ambiguous, optional otherwise.
191
+ * @param value - The match index, or `null`.
192
+ */
193
+ set index(value: number | null);
194
+ /**
195
+ * Gets which match to bind.
196
+ * @returns The match index, or `null` when unset.
197
+ */
198
+ get index(): number | null;
199
+ /**
200
+ * Sets the enabled override. `null` clears it, restoring the authored state.
201
+ * @param value - The enabled state, or `null`.
202
+ */
203
+ set enabled(value: boolean | null);
204
+ /**
205
+ * Gets the enabled override.
206
+ * @returns The enabled state, or `null` while no override is set.
207
+ */
208
+ get enabled(): boolean | null;
209
+ /**
210
+ * Sets the local position override. `null` clears it, restoring the authored position.
211
+ * @param value - The position, or `null`.
212
+ */
213
+ set position(value: Vec3 | null);
214
+ /**
215
+ * Gets the local position override.
216
+ * @returns The position, or `null` while no override is set.
217
+ */
218
+ get position(): Vec3 | null;
219
+ /**
220
+ * Sets the local rotation override, as Euler angles in degrees. `null` clears it, restoring
221
+ * the authored rotation.
222
+ * @param value - The rotation, or `null`.
223
+ */
224
+ set rotation(value: Vec3 | null);
225
+ /**
226
+ * Gets the local rotation override.
227
+ * @returns The rotation, or `null` while no override is set.
228
+ */
229
+ get rotation(): Vec3 | null;
230
+ /**
231
+ * Sets the local scale override. `null` clears it, restoring the authored scale.
232
+ * @param value - The scale, or `null`.
233
+ */
234
+ set scale(value: Vec3 | null);
235
+ /**
236
+ * Gets the local scale override.
237
+ * @returns The scale, or `null` while no override is set.
238
+ */
239
+ get scale(): Vec3 | null;
240
+ /**
241
+ * Sets the tags override. `null` clears it, restoring the authored tags.
242
+ * @param value - The tags, or `null`.
243
+ */
244
+ set tags(value: string[] | null);
245
+ /**
246
+ * Gets the tags override.
247
+ * @returns The tags, or `null` while no override is set.
248
+ */
249
+ get tags(): string[] | null;
250
+ static get observedAttributes(): string[];
251
+ attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null): void;
252
+ }
253
+ export { NodeElement };