@playcanvas/web-components 0.13.1 → 0.14.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.
package/dist/colors.d.cts CHANGED
@@ -1 +1 @@
1
- export declare const CSS_COLORS: Record<string, string>;
1
+ export {};
package/dist/colors.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const CSS_COLORS: Record<string, string>;
1
+ export {};
@@ -1777,6 +1777,30 @@
1777
1777
  "name": "AsyncElementTagName",
1778
1778
  "module": "./async-element"
1779
1779
  }
1780
+ },
1781
+ {
1782
+ "kind": "js",
1783
+ "name": "HierarchyMaterial",
1784
+ "declaration": {
1785
+ "name": "HierarchyMaterial",
1786
+ "module": "./model"
1787
+ }
1788
+ },
1789
+ {
1790
+ "kind": "js",
1791
+ "name": "HierarchyNode",
1792
+ "declaration": {
1793
+ "name": "HierarchyNode",
1794
+ "module": "./model"
1795
+ }
1796
+ },
1797
+ {
1798
+ "kind": "js",
1799
+ "name": "MaterialOverrides",
1800
+ "declaration": {
1801
+ "name": "MaterialOverrides",
1802
+ "module": "./node"
1803
+ }
1780
1804
  }
1781
1805
  ]
1782
1806
  },
@@ -2715,6 +2739,22 @@
2715
2739
  }
2716
2740
  }
2717
2741
  },
2742
+ {
2743
+ "kind": "field",
2744
+ "name": "name",
2745
+ "description": "Gets the name of the material - the label shown wherever materials surface by name, such\nas profilers, GPU captures and the assignments `pc-model.hierarchy()` reports. Purely a\nlabel: element references resolve through `id`.",
2746
+ "parameters": [
2747
+ {
2748
+ "description": "The material name.",
2749
+ "name": "value"
2750
+ }
2751
+ ],
2752
+ "return": {
2753
+ "type": {
2754
+ "text": ""
2755
+ }
2756
+ }
2757
+ },
2718
2758
  {
2719
2759
  "kind": "field",
2720
2760
  "name": "normalMap",
@@ -3657,6 +3697,14 @@
3657
3697
  "default": "0",
3658
3698
  "description": "The UV channel the metalness map samples."
3659
3699
  },
3700
+ {
3701
+ "name": "name",
3702
+ "type": {
3703
+ "text": "string"
3704
+ },
3705
+ "fieldName": "name",
3706
+ "description": "The name of the material - the label shown wherever materials surface by name, such as profilers, GPU captures and the assignments `pc-model.hierarchy()` reports."
3707
+ },
3660
3708
  {
3661
3709
  "name": "normal-map",
3662
3710
  "type": {
@@ -3937,6 +3985,10 @@
3937
3985
  "kind": "javascript-module",
3938
3986
  "path": "src/model.ts",
3939
3987
  "declarations": [
3988
+ {
3989
+ "kind": "variable",
3990
+ "name": "index"
3991
+ },
3940
3992
  {
3941
3993
  "kind": "class",
3942
3994
  "description": "The ModelElement interface provides properties and methods for manipulating\n[`<pc-model>`](https://developer.playcanvas.com/user-manual/web-components/tags/pc-model/) elements.\nThe ModelElement interface also inherits the properties and methods of the\nHTMLElement interface.\n\nThe element becomes ready once its container asset has loaded and the instantiated hierarchy has\nbeen added to the scene — `entity` is non-null by then. A failed load also settles readiness,\nwith `entity` remaining `null`: readiness means the load settled, not that it succeeded — listen\nfor `error`, or check `entity`, to tell the outcomes apart. Changing `asset` re-arms readiness\nand instantiates anew, so a `ready()` obtained after the change resolves against the new\nhierarchy. A `pc-model` outside a `pc-app`, or referencing an unknown asset id, warns and never\nbecomes ready.\n",
@@ -4011,6 +4063,16 @@
4011
4063
  },
4012
4064
  "readonly": true
4013
4065
  },
4066
+ {
4067
+ "kind": "method",
4068
+ "name": "hierarchy",
4069
+ "return": {
4070
+ "type": {
4071
+ "text": ""
4072
+ }
4073
+ },
4074
+ "description": "Returns a snapshot of the instantiated node tree, or `null` while there is none (the\ncontainer asset has not loaded, or the element has left the document). One call grounds a\nsession — a browser console, a test, an agent — in the vocabulary `pc-node` binding\nresolves against: the instantiated names (HierarchyNode.name), paths, match\nindices, attached component types and the material assignments of render components\n(HierarchyNode.materials). `String(...)` of the result, or of any node in it,\nis the printable form.\n\nThe snapshot is plain data, computed afresh each call: it does not follow later changes\nto the hierarchy, and mutating it changes nothing."
4075
+ },
4014
4076
  {
4015
4077
  "kind": "method",
4016
4078
  "name": "ready",
@@ -4087,6 +4149,22 @@
4087
4149
  "name": "ModelElement",
4088
4150
  "module": "src/model.ts"
4089
4151
  }
4152
+ },
4153
+ {
4154
+ "kind": "js",
4155
+ "name": "HierarchyMaterial",
4156
+ "declaration": {
4157
+ "name": "HierarchyMaterial",
4158
+ "module": "src/model.ts"
4159
+ }
4160
+ },
4161
+ {
4162
+ "kind": "js",
4163
+ "name": "HierarchyNode",
4164
+ "declaration": {
4165
+ "name": "HierarchyNode",
4166
+ "module": "src/model.ts"
4167
+ }
4090
4168
  }
4091
4169
  ]
4092
4170
  },
@@ -4350,6 +4428,25 @@
4350
4428
  }
4351
4429
  }
4352
4430
  },
4431
+ {
4432
+ "kind": "field",
4433
+ "name": "materialOverrides",
4434
+ "description": "Gets the material overrides.",
4435
+ "parameters": [
4436
+ {
4437
+ "description": "The mapping, or `null`.",
4438
+ "name": "value"
4439
+ }
4440
+ ],
4441
+ "type": {
4442
+ "text": "MaterialOverrides | null"
4443
+ },
4444
+ "return": {
4445
+ "type": {
4446
+ "text": ""
4447
+ }
4448
+ }
4449
+ },
4353
4450
  {
4354
4451
  "kind": "field",
4355
4452
  "name": "name",
@@ -4582,6 +4679,14 @@
4582
4679
  "description": "Which match to bind when `name` matches more than one node, 0-based in depth-first order. Optional for a unique match; required for an ambiguous one.",
4583
4680
  "fieldName": "index"
4584
4681
  },
4682
+ {
4683
+ "name": "material-overrides",
4684
+ "type": {
4685
+ "text": "string"
4686
+ },
4687
+ "description": "Overrides material assignments on the bound node's render component, as a JSON object from selector to `pc-material` id — for example `{\"name:CarPaint\": \"candy-red\", \"index:7\": \"smoked-glass\"}`. A `name:X` key selects every mesh instance whose baseline material is named `X`; an `index:N` key selects mesh instance `N` and wins over a name rule for the same instance. Assignments no rule matches keep their baseline materials, and removing the attribute restores all of them. Use `pc-model.hierarchy()` to discover the names and indices a node offers.",
4688
+ "fieldName": "materialOverrides"
4689
+ },
4585
4690
  {
4586
4691
  "name": "name",
4587
4692
  "type": {
@@ -4687,6 +4792,14 @@
4687
4792
  "name": "NodeElement",
4688
4793
  "module": "src/node.ts"
4689
4794
  }
4795
+ },
4796
+ {
4797
+ "kind": "js",
4798
+ "name": "MaterialOverrides",
4799
+ "declaration": {
4800
+ "name": "MaterialOverrides",
4801
+ "module": "src/node.ts"
4802
+ }
4690
4803
  }
4691
4804
  ]
4692
4805
  },
@@ -1,12 +1,6 @@
1
1
  import type { Entity } from 'playcanvas';
2
2
  import type { AppElement } from './app.cjs';
3
3
  import { AsyncElement } from './async-element.cjs';
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
4
  /**
11
5
  * The base class for elements that front an engine {@link Entity}: `<pc-entity>`, which creates
12
6
  * one, and `<pc-node>`, which binds to one inside a model's instantiated hierarchy. It carries
@@ -64,4 +58,4 @@ declare class EntityBaseElement extends AsyncElement {
64
58
  addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
65
59
  removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
66
60
  }
67
- export { EntityBaseElement, POINTER_ATTRIBUTES };
61
+ export { EntityBaseElement };
@@ -1,12 +1,6 @@
1
1
  import type { Entity } from 'playcanvas';
2
2
  import type { AppElement } from './app.js';
3
3
  import { AsyncElement } from './async-element.js';
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
4
  /**
11
5
  * The base class for elements that front an engine {@link Entity}: `<pc-entity>`, which creates
12
6
  * one, and `<pc-node>`, which binds to one inside a model's instantiated hierarchy. It carries
@@ -64,4 +58,4 @@ declare class EntityBaseElement extends AsyncElement {
64
58
  addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void;
65
59
  removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void;
66
60
  }
67
- export { EntityBaseElement, POINTER_ATTRIBUTES };
61
+ export { EntityBaseElement };
package/dist/index.d.cts CHANGED
@@ -77,3 +77,5 @@ declare global {
77
77
  }
78
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 };
79
79
  export type { AsyncElementTagName } from './async-element.cjs';
80
+ export type { HierarchyMaterial, HierarchyNode } from './model.cjs';
81
+ export type { MaterialOverrides } from './node.cjs';
package/dist/index.d.ts CHANGED
@@ -77,3 +77,5 @@ declare global {
77
77
  }
78
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 };
79
79
  export type { AsyncElementTagName } from './async-element.js';
80
+ export type { HierarchyMaterial, HierarchyNode } from './model.js';
81
+ export type { MaterialOverrides } from './node.js';
@@ -1,35 +1 @@
1
- /**
2
- * The slim progress bar `<pc-app>` shows while it boots and preloads. An implementation detail of
3
- * AppElement rather than a custom element, so its shape can change without a breaking change.
4
- *
5
- * All styling is inline, so the library injects no stylesheet. The colors and height resolve CSS
6
- * custom properties — `--pc-loading-bar-color`, `--pc-loading-bar-background` and
7
- * `--pc-loading-bar-height` — so a page can theme the bar from `pc-app` or `:root`.
8
- */
9
- declare class LoadingBar {
10
- private _track;
11
- private _fill;
12
- private _sweep;
13
- private _removal;
14
- /**
15
- * Creates the bar and appends it to `parent`, starting in the indeterminate state.
16
- * @param parent - The element to append the bar to.
17
- */
18
- constructor(parent: HTMLElement);
19
- /**
20
- * Reflects preload progress, switching the bar from indeterminate to determinate on the first
21
- * call.
22
- * @param loaded - The number of assets that have finished loading.
23
- * @param total - The number of assets being preloaded.
24
- */
25
- progress(loaded: number, total: number): void;
26
- /**
27
- * Fills the bar, fades it out and removes it. Idempotent.
28
- */
29
- complete(): void;
30
- /**
31
- * Removes the bar immediately, cancelling any pending fade. Idempotent.
32
- */
33
- destroy(): void;
34
- }
35
- export { LoadingBar };
1
+ export {};
@@ -1,35 +1 @@
1
- /**
2
- * The slim progress bar `<pc-app>` shows while it boots and preloads. An implementation detail of
3
- * AppElement rather than a custom element, so its shape can change without a breaking change.
4
- *
5
- * All styling is inline, so the library injects no stylesheet. The colors and height resolve CSS
6
- * custom properties — `--pc-loading-bar-color`, `--pc-loading-bar-background` and
7
- * `--pc-loading-bar-height` — so a page can theme the bar from `pc-app` or `:root`.
8
- */
9
- declare class LoadingBar {
10
- private _track;
11
- private _fill;
12
- private _sweep;
13
- private _removal;
14
- /**
15
- * Creates the bar and appends it to `parent`, starting in the indeterminate state.
16
- * @param parent - The element to append the bar to.
17
- */
18
- constructor(parent: HTMLElement);
19
- /**
20
- * Reflects preload progress, switching the bar from indeterminate to determinate on the first
21
- * call.
22
- * @param loaded - The number of assets that have finished loading.
23
- * @param total - The number of assets being preloaded.
24
- */
25
- progress(loaded: number, total: number): void;
26
- /**
27
- * Fills the bar, fades it out and removes it. Idempotent.
28
- */
29
- complete(): void;
30
- /**
31
- * Removes the bar immediately, cancelling any pending fade. Idempotent.
32
- */
33
- destroy(): void;
34
- }
35
- export { LoadingBar };
1
+ export {};
@@ -91,6 +91,7 @@ declare class MaterialElement extends HTMLElement {
91
91
  private _metalnessMapRotation;
92
92
  private _metalnessMapTiling;
93
93
  private _metalnessMapUv;
94
+ private _name;
94
95
  private _normalMap;
95
96
  private _normalMapOffset;
96
97
  private _normalMapRotation;
@@ -706,6 +707,18 @@ declare class MaterialElement extends HTMLElement {
706
707
  * @returns The UV channel.
707
708
  */
708
709
  get metalnessMapUv(): number;
710
+ /**
711
+ * Sets the name of the material.
712
+ * @param value - The material name.
713
+ */
714
+ set name(value: string);
715
+ /**
716
+ * Gets the name of the material - the label shown wherever materials surface by name, such
717
+ * as profilers, GPU captures and the assignments `pc-model.hierarchy()` reports. Purely a
718
+ * label: element references resolve through `id`.
719
+ * @returns The material name.
720
+ */
721
+ get name(): string;
709
722
  /**
710
723
  * Sets the id of the `pc-asset` to use as the normal map.
711
724
  * @param value - The asset id.
@@ -91,6 +91,7 @@ declare class MaterialElement extends HTMLElement {
91
91
  private _metalnessMapRotation;
92
92
  private _metalnessMapTiling;
93
93
  private _metalnessMapUv;
94
+ private _name;
94
95
  private _normalMap;
95
96
  private _normalMapOffset;
96
97
  private _normalMapRotation;
@@ -706,6 +707,18 @@ declare class MaterialElement extends HTMLElement {
706
707
  * @returns The UV channel.
707
708
  */
708
709
  get metalnessMapUv(): number;
710
+ /**
711
+ * Sets the name of the material.
712
+ * @param value - The material name.
713
+ */
714
+ set name(value: string);
715
+ /**
716
+ * Gets the name of the material - the label shown wherever materials surface by name, such
717
+ * as profilers, GPU captures and the assignments `pc-model.hierarchy()` reports. Purely a
718
+ * label: element references resolve through `id`.
719
+ * @returns The material name.
720
+ */
721
+ get name(): string;
709
722
  /**
710
723
  * Sets the id of the `pc-asset` to use as the normal map.
711
724
  * @param value - The asset id.
package/dist/model.d.cts CHANGED
@@ -1,5 +1,60 @@
1
1
  import type { Entity } from 'playcanvas';
2
2
  import { AsyncElement } from './async-element.cjs';
3
+ /**
4
+ * One material assignment of a {@link HierarchyNode} with a render component: a mesh instance's
5
+ * position within the component and the runtime name of its current material.
6
+ */
7
+ type HierarchyMaterial = {
8
+ /** The mesh instance's position in the render component's `meshInstances` array. */
9
+ index: number;
10
+ /**
11
+ * The runtime name of the mesh instance's current material, reported as-is: the engine
12
+ * names an unnamed glTF material `Untitled`, and assigns a shared material named
13
+ * `defaultGlbMaterial` to a primitive authored without one — neither is a unique authored
14
+ * identifier. `null` when a script has cleared the assignment.
15
+ */
16
+ name: string | null;
17
+ };
18
+ /**
19
+ * One node of the tree returned by {@link ModelElement.hierarchy}. A plain-data snapshot —
20
+ * `JSON.stringify` serializes it — whose `toString()` renders the node's subtree as a printable
21
+ * tree.
22
+ */
23
+ type HierarchyNode = {
24
+ /**
25
+ * The node's name as instantiated, which is the name `pc-node` binding resolves: the engine
26
+ * parser synthesizes `node_<index>` names for unnamed nodes and renames identically named
27
+ * siblings apart (`Wheel`, `Wheel1`, ...), so it can differ from the name authored in the
28
+ * source asset.
29
+ */
30
+ name: string;
31
+ /**
32
+ * The node's `/`-separated path below the model root — the path a `pc-node` bound to this
33
+ * node reports. The root's path is its own name.
34
+ */
35
+ path: string;
36
+ /**
37
+ * The node's position among identically named nodes in the model, counted in depth-first
38
+ * order over the whole tree: the match a `pc-node`'s `index` attribute selects when `name`
39
+ * alone is ambiguous.
40
+ */
41
+ index: number;
42
+ /** The types of the components attached to the node (e.g. 'render'), sorted. */
43
+ components: string[];
44
+ /**
45
+ * The material assignments of the node's render component, one entry per mesh instance in
46
+ * component order. Empty for a node without a render component.
47
+ */
48
+ materials: HierarchyMaterial[];
49
+ /** The node's children. */
50
+ children: HierarchyNode[];
51
+ /**
52
+ * Renders the subtree rooted at this node as a printable tree, one line per node: the name,
53
+ * `[index]` after a name that several nodes in the model share, the component types in
54
+ * parentheses, and the material names of a render component in braces.
55
+ */
56
+ toString(): string;
57
+ };
3
58
  /**
4
59
  * The ModelElement interface provides properties and methods for manipulating
5
60
  * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-model/ | `<pc-model>`} elements.
@@ -44,6 +99,21 @@ declare class ModelElement extends AsyncElement {
44
99
  * @returns The model's root entity, or `null`.
45
100
  */
46
101
  get entity(): Entity | null;
102
+ /**
103
+ * Returns a snapshot of the instantiated node tree, or `null` while there is none (the
104
+ * container asset has not loaded, or the element has left the document). One call grounds a
105
+ * session — a browser console, a test, an agent — in the vocabulary `pc-node` binding
106
+ * resolves against: the instantiated names ({@link HierarchyNode.name}), paths, match
107
+ * indices, attached component types and the material assignments of render components
108
+ * ({@link HierarchyNode.materials}). `String(...)` of the result, or of any node in it,
109
+ * is the printable form.
110
+ *
111
+ * The snapshot is plain data, computed afresh each call: it does not follow later changes
112
+ * to the hierarchy, and mutating it changes nothing.
113
+ *
114
+ * @returns The root of the instantiated node tree, or `null`.
115
+ */
116
+ hierarchy(): HierarchyNode | null;
47
117
  connectedCallback(): void;
48
118
  disconnectedCallback(): void;
49
119
  private _detachLoadHandlers;
@@ -70,3 +140,4 @@ declare class ModelElement extends AsyncElement {
70
140
  attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null): void;
71
141
  }
72
142
  export { ModelElement };
143
+ export type { HierarchyMaterial, HierarchyNode };
package/dist/model.d.ts CHANGED
@@ -1,5 +1,60 @@
1
1
  import type { Entity } from 'playcanvas';
2
2
  import { AsyncElement } from './async-element.js';
3
+ /**
4
+ * One material assignment of a {@link HierarchyNode} with a render component: a mesh instance's
5
+ * position within the component and the runtime name of its current material.
6
+ */
7
+ type HierarchyMaterial = {
8
+ /** The mesh instance's position in the render component's `meshInstances` array. */
9
+ index: number;
10
+ /**
11
+ * The runtime name of the mesh instance's current material, reported as-is: the engine
12
+ * names an unnamed glTF material `Untitled`, and assigns a shared material named
13
+ * `defaultGlbMaterial` to a primitive authored without one — neither is a unique authored
14
+ * identifier. `null` when a script has cleared the assignment.
15
+ */
16
+ name: string | null;
17
+ };
18
+ /**
19
+ * One node of the tree returned by {@link ModelElement.hierarchy}. A plain-data snapshot —
20
+ * `JSON.stringify` serializes it — whose `toString()` renders the node's subtree as a printable
21
+ * tree.
22
+ */
23
+ type HierarchyNode = {
24
+ /**
25
+ * The node's name as instantiated, which is the name `pc-node` binding resolves: the engine
26
+ * parser synthesizes `node_<index>` names for unnamed nodes and renames identically named
27
+ * siblings apart (`Wheel`, `Wheel1`, ...), so it can differ from the name authored in the
28
+ * source asset.
29
+ */
30
+ name: string;
31
+ /**
32
+ * The node's `/`-separated path below the model root — the path a `pc-node` bound to this
33
+ * node reports. The root's path is its own name.
34
+ */
35
+ path: string;
36
+ /**
37
+ * The node's position among identically named nodes in the model, counted in depth-first
38
+ * order over the whole tree: the match a `pc-node`'s `index` attribute selects when `name`
39
+ * alone is ambiguous.
40
+ */
41
+ index: number;
42
+ /** The types of the components attached to the node (e.g. 'render'), sorted. */
43
+ components: string[];
44
+ /**
45
+ * The material assignments of the node's render component, one entry per mesh instance in
46
+ * component order. Empty for a node without a render component.
47
+ */
48
+ materials: HierarchyMaterial[];
49
+ /** The node's children. */
50
+ children: HierarchyNode[];
51
+ /**
52
+ * Renders the subtree rooted at this node as a printable tree, one line per node: the name,
53
+ * `[index]` after a name that several nodes in the model share, the component types in
54
+ * parentheses, and the material names of a render component in braces.
55
+ */
56
+ toString(): string;
57
+ };
3
58
  /**
4
59
  * The ModelElement interface provides properties and methods for manipulating
5
60
  * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-model/ | `<pc-model>`} elements.
@@ -44,6 +99,21 @@ declare class ModelElement extends AsyncElement {
44
99
  * @returns The model's root entity, or `null`.
45
100
  */
46
101
  get entity(): Entity | null;
102
+ /**
103
+ * Returns a snapshot of the instantiated node tree, or `null` while there is none (the
104
+ * container asset has not loaded, or the element has left the document). One call grounds a
105
+ * session — a browser console, a test, an agent — in the vocabulary `pc-node` binding
106
+ * resolves against: the instantiated names ({@link HierarchyNode.name}), paths, match
107
+ * indices, attached component types and the material assignments of render components
108
+ * ({@link HierarchyNode.materials}). `String(...)` of the result, or of any node in it,
109
+ * is the printable form.
110
+ *
111
+ * The snapshot is plain data, computed afresh each call: it does not follow later changes
112
+ * to the hierarchy, and mutating it changes nothing.
113
+ *
114
+ * @returns The root of the instantiated node tree, or `null`.
115
+ */
116
+ hierarchy(): HierarchyNode | null;
47
117
  connectedCallback(): void;
48
118
  disconnectedCallback(): void;
49
119
  private _detachLoadHandlers;
@@ -70,3 +140,4 @@ declare class ModelElement extends AsyncElement {
70
140
  attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null): void;
71
141
  }
72
142
  export { ModelElement };
143
+ export type { HierarchyMaterial, HierarchyNode };
package/dist/node.d.cts CHANGED
@@ -7,6 +7,13 @@ import { EntityBaseElement } from './entity-base.cjs';
7
7
  * naming the cause.
8
8
  */
9
9
  type NodeBindingState = 'pending' | 'bound' | 'missing' | 'ambiguous' | 'duplicate';
10
+ /**
11
+ * A sparse mapping from selector to `pc-material` id, as carried by the `material-overrides`
12
+ * attribute and `materialOverrides` property. A `name:X` key selects every mesh instance of the
13
+ * bound node's render component whose baseline material is named `X`; an `index:N` key selects
14
+ * mesh instance `N` and wins over a name rule for the same instance.
15
+ */
16
+ type MaterialOverrides = Readonly<Record<string, string>>;
10
17
  /**
11
18
  * The NodeElement interface provides properties and methods for manipulating
12
19
  * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-node/ | `<pc-node>`}
@@ -41,6 +48,13 @@ type NodeBindingState = 'pending' | 'bound' | 'missing' | 'ambiguous' | 'duplica
41
48
  * "x y z" triple.
42
49
  * @attribute {string} scale - Overrides the node's local scale, as an "x y z" triple.
43
50
  * @attribute {string} tags - Overrides the node's tags, separated by spaces or commas.
51
+ * @attribute {string} material-overrides - Overrides material assignments on the bound node's
52
+ * render component, as a JSON object from selector to `pc-material` id — for example
53
+ * `{"name:CarPaint": "candy-red", "index:7": "smoked-glass"}`. A `name:X` key selects every mesh
54
+ * instance whose baseline material is named `X`; an `index:N` key selects mesh instance `N` and
55
+ * wins over a name rule for the same instance. Assignments no rule matches keep their baseline
56
+ * materials, and removing the attribute restores all of them. Use `pc-model.hierarchy()` to
57
+ * discover the names and indices a node offers.
44
58
  * @attribute {string} onpointerenter - Script to run when the pointer moves onto the node.
45
59
  * @attribute {string} onpointerleave - Script to run when the pointer moves off the node.
46
60
  * @attribute {string} onpointermove - Script to run when the pointer moves over the node.
@@ -76,11 +90,24 @@ declare class NodeElement extends EntityBaseElement {
76
90
  private _destroyHandle;
77
91
  /** The authored values displaced by this element's overrides, captured per property. */
78
92
  private _authored;
93
+ /**
94
+ * The model-authored render component of the bound node, recorded at bind — before child
95
+ * decorations build — so a render component added later by a child `pc-render` can never
96
+ * become the override target. `null` when the bound node has none.
97
+ */
98
+ private _authoredRender;
99
+ /**
100
+ * The baseline assignments displaced by the material overrides, captured for every mesh
101
+ * instance when the first non-empty mapping applies and released when the mapping goes
102
+ * absent (restoring them) or the binding dissolves.
103
+ */
104
+ private _baseline;
79
105
  private _enabled;
80
106
  private _position;
81
107
  private _rotation;
82
108
  private _scale;
83
109
  private _tags;
110
+ private _materialOverrides;
84
111
  /**
85
112
  * The binding state: `pending` until the host instantiates and `name` resolves, `bound`
86
113
  * once decorated, `missing`/`ambiguous`/`duplicate` when resolution failed (each also
@@ -149,6 +176,19 @@ declare class NodeElement extends EntityBaseElement {
149
176
  * themselves are kept - they re-apply on the next binding.
150
177
  */
151
178
  private _revertOverrides;
179
+ /**
180
+ * Applies the material mapping to the authored render component: parse the mapping's valid
181
+ * rules, capture the baseline on first application, then recompute every assignment from
182
+ * that baseline - name rules write over it, index rules write over them, so `index:` wins -
183
+ * and assign whatever changed. An absent mapping, or one with no valid rules, restores the
184
+ * baseline instead. Called while bound, from `_applyOverrides` and the property setter.
185
+ */
186
+ private _applyMaterialOverrides;
187
+ /**
188
+ * Restores every baseline assignment the material overrides displaced and releases the
189
+ * capture, so the next non-empty mapping captures afresh. Safe to call without a capture.
190
+ */
191
+ private _restoreBaseline;
152
192
  /**
153
193
  * Renders the path of `node` below `root`, for the `path` property and the resolution
154
194
  * warnings.
@@ -247,7 +287,22 @@ declare class NodeElement extends EntityBaseElement {
247
287
  * @returns The tags, or `null` while no override is set.
248
288
  */
249
289
  get tags(): string[] | null;
290
+ /**
291
+ * Sets the material overrides: a sparse mapping from selector to `pc-material` id, applied
292
+ * to the bound node's authored render component. A `name:X` key selects every mesh instance
293
+ * whose baseline material is named `X`; an `index:N` key selects mesh instance `N` and wins
294
+ * over a name rule for the same instance. Assignments no rule matches keep their baseline
295
+ * materials. `null` clears the mapping, restoring every baseline assignment.
296
+ * @param value - The mapping, or `null`.
297
+ */
298
+ set materialOverrides(value: MaterialOverrides | null);
299
+ /**
300
+ * Gets the material overrides.
301
+ * @returns The mapping, or `null` while no override is set.
302
+ */
303
+ get materialOverrides(): MaterialOverrides | null;
250
304
  static get observedAttributes(): string[];
251
305
  attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null): void;
252
306
  }
253
307
  export { NodeElement };
308
+ export type { MaterialOverrides };