@playcanvas/web-components 0.5.0 → 0.7.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 (36) hide show
  1. package/dist/asset.d.ts +8 -0
  2. package/dist/components/button-component.d.ts +184 -0
  3. package/dist/components/camera-component.d.ts +1 -1
  4. package/dist/components/element-component.d.ts +162 -16
  5. package/dist/components/gsplat-component.d.ts +79 -0
  6. package/dist/components/layoutchild-component.d.ts +110 -0
  7. package/dist/components/layoutgroup-component.d.ts +134 -0
  8. package/dist/components/light-component.d.ts +1 -1
  9. package/dist/components/scrollbar-component.d.ts +68 -0
  10. package/dist/components/scrollview-component.d.ts +173 -0
  11. package/dist/entity.d.ts +4 -0
  12. package/dist/index.d.ts +7 -2
  13. package/dist/pwc.cjs +1957 -59
  14. package/dist/pwc.cjs.map +1 -1
  15. package/dist/pwc.js +1957 -59
  16. package/dist/pwc.js.map +1 -1
  17. package/dist/pwc.min.js +1 -1
  18. package/dist/pwc.min.js.map +1 -1
  19. package/dist/pwc.mjs +1953 -60
  20. package/dist/pwc.mjs.map +1 -1
  21. package/dist/utils.d.ts +20 -1
  22. package/package.json +9 -9
  23. package/src/app.ts +5 -0
  24. package/src/asset.ts +75 -2
  25. package/src/components/button-component.ts +450 -0
  26. package/src/components/element-component.ts +415 -5
  27. package/src/components/gsplat-component.ts +161 -0
  28. package/src/components/layoutchild-component.ts +232 -0
  29. package/src/components/layoutgroup-component.ts +297 -0
  30. package/src/components/scrollbar-component.ts +166 -0
  31. package/src/components/scrollview-component.ts +427 -0
  32. package/src/entity.ts +15 -1
  33. package/src/index.ts +12 -2
  34. package/src/utils.ts +49 -1
  35. package/dist/components/splat-component.d.ts +0 -48
  36. package/src/components/splat-component.ts +0 -102
package/dist/pwc.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { basisInitialize, WasmModule, createGraphicsDevice, AppOptions, Keyboard, Mouse, AnimComponentSystem, AnimationComponentSystem, AudioListenerComponentSystem, ButtonComponentSystem, CameraComponentSystem, CollisionComponentSystem, ElementComponentSystem, GSplatComponentSystem, JointComponentSystem, LayoutChildComponentSystem, LayoutGroupComponentSystem, LightComponentSystem, ModelComponentSystem, ParticleSystemComponentSystem, RenderComponentSystem, RigidBodyComponentSystem, ScreenComponentSystem, ScriptComponentSystem, ScrollbarComponentSystem, ScrollViewComponentSystem, SoundComponentSystem, SpriteComponentSystem, ZoneComponentSystem, AnimClipHandler, AnimationHandler, AnimStateGraphHandler, AudioHandler, BinaryHandler, CssHandler, ContainerHandler, CubemapHandler, FolderHandler, FontHandler, GSplatHandler, HierarchyHandler, HtmlHandler, JsonHandler, MaterialHandler, ModelHandler, RenderHandler, ScriptHandler, SceneHandler, ShaderHandler, SpriteHandler, TemplateHandler, TextHandler, TextureAtlasHandler, TextureHandler, SoundManager, Lightmapper, BatchManager, XrManager, AppBase, FILLMODE_FILL_WINDOW, RESOLUTION_AUTO, Picker, MeshInstance, Vec3, Vec4, Color, Quat, Vec2, Entity, Asset, GAMMA_SRGB, GAMMA_NONE, XRTYPE_VR, PROJECTION_ORTHOGRAPHIC, PROJECTION_PERSPECTIVE, TONEMAP_NONE, TONEMAP_LINEAR, TONEMAP_FILMIC, TONEMAP_HEJL, TONEMAP_ACES, TONEMAP_ACES2, TONEMAP_NEUTRAL, SHADOW_PCF3_32F, SHADOW_PCF1_16F, SHADOW_PCF1_32F, SHADOW_PCF3_16F, SHADOW_PCF5_16F, SHADOW_PCF5_32F, SHADOW_VSM_16F, SHADOW_VSM_32F, SHADOW_PCSS_32F, StandardMaterial, SCALEMODE_BLEND, SCALEMODE_NONE, EnvLighting, LAYERID_SKYBOX } from 'playcanvas';
1
+ import { basisInitialize, WasmModule, createGraphicsDevice, AppOptions, Keyboard, Mouse, ElementInput, AnimComponentSystem, AnimationComponentSystem, AudioListenerComponentSystem, ButtonComponentSystem, CameraComponentSystem, CollisionComponentSystem, ElementComponentSystem, GSplatComponentSystem, JointComponentSystem, LayoutChildComponentSystem, LayoutGroupComponentSystem, LightComponentSystem, ModelComponentSystem, ParticleSystemComponentSystem, RenderComponentSystem, RigidBodyComponentSystem, ScreenComponentSystem, ScriptComponentSystem, ScrollbarComponentSystem, ScrollViewComponentSystem, SoundComponentSystem, SpriteComponentSystem, ZoneComponentSystem, AnimClipHandler, AnimationHandler, AnimStateGraphHandler, AudioHandler, BinaryHandler, CssHandler, ContainerHandler, CubemapHandler, FolderHandler, FontHandler, GSplatHandler, HierarchyHandler, HtmlHandler, JsonHandler, MaterialHandler, ModelHandler, RenderHandler, ScriptHandler, SceneHandler, ShaderHandler, SpriteHandler, TemplateHandler, TextHandler, TextureAtlasHandler, TextureHandler, SoundManager, Lightmapper, BatchManager, XrManager, AppBase, FILLMODE_FILL_WINDOW, RESOLUTION_AUTO, Picker, MeshInstance, Vec3, Color, Vec4, Quat, Vec2, Entity, Asset, SPRITE_RENDERMODE_SIMPLE, SPRITE_RENDERMODE_SLICED, SPRITE_RENDERMODE_TILED, BUTTON_TRANSITION_MODE_TINT, BUTTON_TRANSITION_MODE_SPRITE_CHANGE, GAMMA_SRGB, GAMMA_NONE, XRTYPE_VR, PROJECTION_ORTHOGRAPHIC, PROJECTION_PERSPECTIVE, TONEMAP_NONE, TONEMAP_LINEAR, TONEMAP_FILMIC, TONEMAP_HEJL, TONEMAP_ACES, TONEMAP_ACES2, TONEMAP_NEUTRAL, ORIENTATION_HORIZONTAL, FITTING_NONE, FITTING_STRETCH, FITTING_SHRINK, FITTING_BOTH, ORIENTATION_VERTICAL, SHADOW_PCF3_32F, SHADOW_PCF1_16F, SHADOW_PCF1_32F, SHADOW_PCF3_16F, SHADOW_PCF5_16F, SHADOW_PCF5_32F, SHADOW_VSM_16F, SHADOW_VSM_32F, SHADOW_PCSS_32F, StandardMaterial, SCALEMODE_BLEND, SCALEMODE_NONE, SCROLL_MODE_BOUNCE, SCROLLBAR_VISIBILITY_SHOW_WHEN_REQUIRED, SCROLLBAR_VISIBILITY_SHOW_ALWAYS, SCROLL_MODE_CLAMP, SCROLL_MODE_INFINITE, EnvLighting, LAYERID_SKYBOX } from 'playcanvas';
2
2
 
3
3
  /**
4
4
  * Base class for all PlayCanvas Web Components that initialize asynchronously.
@@ -144,6 +144,10 @@ class AppElement extends AsyncElement {
144
144
  createOptions.graphicsDevice = device;
145
145
  createOptions.keyboard = new Keyboard(window);
146
146
  createOptions.mouse = new Mouse(this._canvas);
147
+ createOptions.elementInput = new ElementInput(this._canvas, {
148
+ useMouse: true,
149
+ useTouch: true
150
+ });
147
151
  createOptions.componentSystems = [
148
152
  AnimComponentSystem,
149
153
  AnimationComponentSystem,
@@ -743,6 +747,50 @@ const parseVec4 = (value) => {
743
747
  const components = value.split(' ').map(Number);
744
748
  return new Vec4(components);
745
749
  };
750
+ /**
751
+ * Resolves an enum value supplied as either a named string (looked up in `map`) or a numeric
752
+ * string. Falls back to `defaultValue` when the value is neither a known name nor a finite number.
753
+ *
754
+ * @param value - The attribute value to parse.
755
+ * @param map - A map of named values to their numeric enum equivalents.
756
+ * @param defaultValue - The value to return when parsing fails.
757
+ * @returns The resolved numeric enum value.
758
+ */
759
+ const parseEnum = (value, map, defaultValue) => {
760
+ const named = map.get(value);
761
+ if (named !== undefined) {
762
+ return named;
763
+ }
764
+ const numeric = Number(value);
765
+ return Number.isFinite(numeric) ? numeric : defaultValue;
766
+ };
767
+ /**
768
+ * Resolves a reference string to the {@link Entity} backing a `<pc-entity>` element. The reference
769
+ * can be a CSS selector (e.g. `#my-id`, `pc-entity[name="Foo"]`), a bare element id, or a bare
770
+ * entity name. Returns `null` if no matching element (or backing entity) is found.
771
+ *
772
+ * @param ref - The reference string to resolve.
773
+ * @returns The resolved entity, or `null`.
774
+ */
775
+ const getEntity = (ref) => {
776
+ var _a, _b;
777
+ if (!ref) {
778
+ return null;
779
+ }
780
+ let element = null;
781
+ // Try the reference as a CSS selector. An invalid selector (e.g. a bare name containing
782
+ // spaces) throws, in which case we fall back to id/name lookups below.
783
+ try {
784
+ element = document.querySelector(ref);
785
+ }
786
+ catch (_c) {
787
+ element = null;
788
+ }
789
+ if (!element) {
790
+ element = (_a = document.getElementById(ref)) !== null && _a !== void 0 ? _a : document.querySelector(`pc-entity[name="${ref}"]`);
791
+ }
792
+ return (_b = element === null || element === void 0 ? void 0 : element.entity) !== null && _b !== void 0 ? _b : null;
793
+ };
746
794
 
747
795
  /**
748
796
  * The EntityElement interface provides properties and methods for manipulating
@@ -781,12 +829,22 @@ class EntityElement extends AsyncElement {
781
829
  * The pointer event listeners for the entity.
782
830
  */
783
831
  this._listeners = {};
832
+ /**
833
+ * Whether the hierarchy has been built for this entity.
834
+ */
835
+ this._built = false;
784
836
  /**
785
837
  * The PlayCanvas entity instance.
786
838
  */
787
839
  this.entity = null;
788
840
  }
789
841
  createEntity(app) {
842
+ // Guard against double creation. When a subtree is inserted at runtime (e.g. cloning a
843
+ // `<template>`), an ancestor's connectedCallback eagerly creates descendant entities; the
844
+ // descendants' own connectedCallbacks would otherwise create them a second time.
845
+ if (this.entity) {
846
+ return;
847
+ }
790
848
  // Create a new entity
791
849
  this.entity = new Entity(this.getAttribute('name') || this._name, app);
792
850
  const enabled = this.getAttribute('enabled');
@@ -835,8 +893,9 @@ class EntityElement extends AsyncElement {
835
893
  });
836
894
  }
837
895
  buildHierarchy(app) {
838
- if (!this.entity)
896
+ if (!this.entity || this._built)
839
897
  return;
898
+ this._built = true;
840
899
  const closestEntity = this.closestEntity;
841
900
  if (closestEntity === null || closestEntity === void 0 ? void 0 : closestEntity.entity) {
842
901
  closestEntity.entity.addChild(this.entity);
@@ -876,6 +935,7 @@ class EntityElement extends AsyncElement {
876
935
  // Destroy the entity
877
936
  this.entity.destroy();
878
937
  this.entity = null;
938
+ this._built = false;
879
939
  }
880
940
  }
881
941
  /**
@@ -1241,6 +1301,11 @@ var MeshoptDecoder = (function() {
1241
1301
  };
1242
1302
  })();
1243
1303
 
1304
+ const renderModes = new Map([
1305
+ ['simple', SPRITE_RENDERMODE_SIMPLE],
1306
+ ['sliced', SPRITE_RENDERMODE_SLICED],
1307
+ ['tiled', SPRITE_RENDERMODE_TILED]
1308
+ ]);
1244
1309
  const extToType = new Map([
1245
1310
  ['bin', 'binary'],
1246
1311
  ['css', 'css'],
@@ -1314,6 +1379,9 @@ class AssetElement extends HTMLElement {
1314
1379
  console.warn(`Unsupported asset type: ${src}`);
1315
1380
  return;
1316
1381
  }
1382
+ // Optional inline asset data, used by data-driven assets such as texture atlases (frame
1383
+ // definitions) and sprites (atlas reference, frame keys, etc.).
1384
+ const data = this._buildData(type);
1317
1385
  if (type === 'container') {
1318
1386
  this.asset = new Asset(id, type, { url: src }, undefined, {
1319
1387
  // @ts-ignore TODO no definition in pc
@@ -1322,12 +1390,69 @@ class AssetElement extends HTMLElement {
1322
1390
  }
1323
1391
  });
1324
1392
  }
1393
+ else if (type === 'sprite') {
1394
+ // Sprite assets have no file of their own; their data references a texture atlas asset.
1395
+ // @ts-ignore
1396
+ this.asset = new Asset(id, type, null, data);
1397
+ }
1325
1398
  else {
1326
1399
  // @ts-ignore
1327
- this.asset = new Asset(id, type, { url: src });
1400
+ this.asset = new Asset(id, type, src ? { url: src } : null, data);
1328
1401
  }
1329
1402
  this.asset.preload = !this._lazy;
1330
1403
  }
1404
+ /**
1405
+ * Builds the `data` object for the asset from an optional inline `data` attribute (JSON) and,
1406
+ * for sprites, from the convenience attributes (`atlas`, `frame-keys`, `pixels-per-unit`,
1407
+ * `render-mode`). Returns `undefined` when there is no data to apply.
1408
+ * @param type - The resolved asset type.
1409
+ * @returns The asset data, or `undefined`.
1410
+ */
1411
+ _buildData(type) {
1412
+ var _a, _b, _c, _d;
1413
+ let data;
1414
+ const dataAttr = this.getAttribute('data');
1415
+ if (dataAttr) {
1416
+ try {
1417
+ data = JSON.parse(dataAttr);
1418
+ }
1419
+ catch (e) {
1420
+ console.warn(`Invalid 'data' JSON on pc-asset: ${dataAttr}`);
1421
+ }
1422
+ }
1423
+ if (type === 'sprite') {
1424
+ data = data !== null && data !== void 0 ? data : {};
1425
+ // Resolve the referenced texture atlas to its (numeric) asset id. The atlas must be
1426
+ // declared before the sprite so its asset already exists in the registry.
1427
+ const atlas = (_a = this.getAttribute('atlas')) !== null && _a !== void 0 ? _a : data.textureAtlasAsset;
1428
+ if (typeof atlas === 'string') {
1429
+ const atlasAsset = AssetElement.get(atlas);
1430
+ if (atlasAsset) {
1431
+ data.textureAtlasAsset = atlasAsset.id;
1432
+ }
1433
+ else {
1434
+ console.warn(`pc-asset sprite '${this.getAttribute('id')}' could not find atlas '${atlas}'`);
1435
+ }
1436
+ }
1437
+ const frameKeys = this.getAttribute('frame-keys');
1438
+ if (frameKeys !== null) {
1439
+ data.frameKeys = frameKeys.split(/[\s,]+/).filter(Boolean);
1440
+ }
1441
+ const pixelsPerUnit = this.getAttribute('pixels-per-unit');
1442
+ if (pixelsPerUnit !== null) {
1443
+ data.pixelsPerUnit = Number(pixelsPerUnit);
1444
+ }
1445
+ const renderMode = this.getAttribute('render-mode');
1446
+ if (renderMode !== null) {
1447
+ data.renderMode = parseEnum(renderMode, renderModes, SPRITE_RENDERMODE_SIMPLE);
1448
+ }
1449
+ // Apply engine defaults for any values not supplied.
1450
+ data.renderMode = (_b = data.renderMode) !== null && _b !== void 0 ? _b : SPRITE_RENDERMODE_SIMPLE;
1451
+ data.pixelsPerUnit = (_c = data.pixelsPerUnit) !== null && _c !== void 0 ? _c : 1;
1452
+ data.frameKeys = (_d = data.frameKeys) !== null && _d !== void 0 ? _d : [];
1453
+ }
1454
+ return data;
1455
+ }
1331
1456
  destroyAsset() {
1332
1457
  if (this.asset) {
1333
1458
  this.asset.unload();
@@ -1467,6 +1592,396 @@ class ListenerComponentElement extends ComponentElement {
1467
1592
  }
1468
1593
  customElements.define('pc-listener', ListenerComponentElement);
1469
1594
 
1595
+ const transitionModes = new Map([
1596
+ ['tint', BUTTON_TRANSITION_MODE_TINT],
1597
+ ['sprite', BUTTON_TRANSITION_MODE_SPRITE_CHANGE]
1598
+ ]);
1599
+ /**
1600
+ * The ButtonComponentElement interface provides properties and methods for manipulating
1601
+ * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-button/ | `<pc-button>`} elements.
1602
+ * The ButtonComponentElement interface also inherits the properties and methods of the
1603
+ * {@link HTMLElement} interface.
1604
+ *
1605
+ * @category Components
1606
+ */
1607
+ class ButtonComponentElement extends ComponentElement {
1608
+ /** @ignore */
1609
+ constructor() {
1610
+ super('button');
1611
+ this._active = true;
1612
+ this._image = '';
1613
+ this._hitPadding = new Vec4(0, 0, 0, 0);
1614
+ this._transitionMode = BUTTON_TRANSITION_MODE_TINT;
1615
+ this._hoverTint = new Color(1, 1, 1, 1);
1616
+ this._pressedTint = new Color(1, 1, 1, 1);
1617
+ this._inactiveTint = new Color(1, 1, 1, 1);
1618
+ this._fadeDuration = 0;
1619
+ this._hoverSpriteAsset = '';
1620
+ this._hoverSpriteFrame = 0;
1621
+ this._pressedSpriteAsset = '';
1622
+ this._pressedSpriteFrame = 0;
1623
+ this._inactiveSpriteAsset = '';
1624
+ this._inactiveSpriteFrame = 0;
1625
+ }
1626
+ getInitialComponentData() {
1627
+ var _a;
1628
+ const data = {
1629
+ active: this._active,
1630
+ hitPadding: this._hitPadding,
1631
+ transitionMode: this._transitionMode,
1632
+ hoverTint: this._hoverTint,
1633
+ pressedTint: this._pressedTint,
1634
+ inactiveTint: this._inactiveTint,
1635
+ fadeDuration: this._fadeDuration,
1636
+ hoverSpriteFrame: this._hoverSpriteFrame,
1637
+ pressedSpriteFrame: this._pressedSpriteFrame,
1638
+ inactiveSpriteFrame: this._inactiveSpriteFrame
1639
+ };
1640
+ // The image entity defaults to the button's own entity (which carries the image element)
1641
+ // when no explicit reference is provided.
1642
+ const imageEntity = this._image ? getEntity(this._image) : (_a = this.closestEntity) === null || _a === void 0 ? void 0 : _a.entity;
1643
+ if (imageEntity) {
1644
+ data.imageEntity = imageEntity;
1645
+ }
1646
+ const hoverSpriteAsset = AssetElement.get(this._hoverSpriteAsset);
1647
+ if (hoverSpriteAsset) {
1648
+ data.hoverSpriteAsset = hoverSpriteAsset.id;
1649
+ }
1650
+ const pressedSpriteAsset = AssetElement.get(this._pressedSpriteAsset);
1651
+ if (pressedSpriteAsset) {
1652
+ data.pressedSpriteAsset = pressedSpriteAsset.id;
1653
+ }
1654
+ const inactiveSpriteAsset = AssetElement.get(this._inactiveSpriteAsset);
1655
+ if (inactiveSpriteAsset) {
1656
+ data.inactiveSpriteAsset = inactiveSpriteAsset.id;
1657
+ }
1658
+ return data;
1659
+ }
1660
+ /**
1661
+ * Gets the underlying PlayCanvas button component.
1662
+ * @returns The button component.
1663
+ */
1664
+ get component() {
1665
+ return super.component;
1666
+ }
1667
+ /**
1668
+ * Sets whether the button is active and responds to input.
1669
+ * @param value - Whether the button is active.
1670
+ */
1671
+ set active(value) {
1672
+ this._active = value;
1673
+ if (this.component) {
1674
+ this.component.active = value;
1675
+ }
1676
+ }
1677
+ /**
1678
+ * Gets whether the button is active.
1679
+ * @returns Whether the button is active.
1680
+ */
1681
+ get active() {
1682
+ return this._active;
1683
+ }
1684
+ /**
1685
+ * Sets the reference (CSS selector, element id or entity name) to the `<pc-entity>` whose image
1686
+ * element is used for visual transitions. Defaults to the button's own entity.
1687
+ * @param value - The image entity reference.
1688
+ */
1689
+ set image(value) {
1690
+ this._image = value;
1691
+ const entity = getEntity(value);
1692
+ if (this.component && entity) {
1693
+ this.component.imageEntity = entity;
1694
+ }
1695
+ }
1696
+ /**
1697
+ * Gets the reference to the `<pc-entity>` whose image element is used for visual transitions.
1698
+ * @returns The image entity reference.
1699
+ */
1700
+ get image() {
1701
+ return this._image;
1702
+ }
1703
+ /**
1704
+ * Sets the padding used to expand the button's hit area, as a Vec4 (left, bottom, right, top).
1705
+ * @param value - The hit padding.
1706
+ */
1707
+ set hitPadding(value) {
1708
+ this._hitPadding = value;
1709
+ if (this.component) {
1710
+ this.component.hitPadding = value;
1711
+ }
1712
+ }
1713
+ /**
1714
+ * Gets the padding used to expand the button's hit area.
1715
+ * @returns The hit padding.
1716
+ */
1717
+ get hitPadding() {
1718
+ return this._hitPadding;
1719
+ }
1720
+ /**
1721
+ * Sets how the button reacts to being hovered/pressed. Can be `tint` (0) or `sprite` (1).
1722
+ * @param value - The transition mode.
1723
+ */
1724
+ set transitionMode(value) {
1725
+ this._transitionMode = value;
1726
+ if (this.component) {
1727
+ this.component.transitionMode = value;
1728
+ }
1729
+ }
1730
+ /**
1731
+ * Gets how the button reacts to being hovered/pressed.
1732
+ * @returns The transition mode.
1733
+ */
1734
+ get transitionMode() {
1735
+ return this._transitionMode;
1736
+ }
1737
+ /**
1738
+ * Sets the tint color applied to the image entity when the button is hovered (tint transition
1739
+ * mode).
1740
+ * @param value - The hover tint.
1741
+ */
1742
+ set hoverTint(value) {
1743
+ this._hoverTint = value;
1744
+ if (this.component) {
1745
+ this.component.hoverTint = value;
1746
+ }
1747
+ }
1748
+ /**
1749
+ * Gets the hover tint color.
1750
+ * @returns The hover tint.
1751
+ */
1752
+ get hoverTint() {
1753
+ return this._hoverTint;
1754
+ }
1755
+ /**
1756
+ * Sets the tint color applied to the image entity when the button is pressed (tint transition
1757
+ * mode).
1758
+ * @param value - The pressed tint.
1759
+ */
1760
+ set pressedTint(value) {
1761
+ this._pressedTint = value;
1762
+ if (this.component) {
1763
+ this.component.pressedTint = value;
1764
+ }
1765
+ }
1766
+ /**
1767
+ * Gets the pressed tint color.
1768
+ * @returns The pressed tint.
1769
+ */
1770
+ get pressedTint() {
1771
+ return this._pressedTint;
1772
+ }
1773
+ /**
1774
+ * Sets the tint color applied to the image entity when the button is inactive (tint transition
1775
+ * mode).
1776
+ * @param value - The inactive tint.
1777
+ */
1778
+ set inactiveTint(value) {
1779
+ this._inactiveTint = value;
1780
+ if (this.component) {
1781
+ this.component.inactiveTint = value;
1782
+ }
1783
+ }
1784
+ /**
1785
+ * Gets the inactive tint color.
1786
+ * @returns The inactive tint.
1787
+ */
1788
+ get inactiveTint() {
1789
+ return this._inactiveTint;
1790
+ }
1791
+ /**
1792
+ * Sets the duration (in milliseconds) over which tint transitions are applied.
1793
+ * @param value - The fade duration.
1794
+ */
1795
+ set fadeDuration(value) {
1796
+ this._fadeDuration = value;
1797
+ if (this.component) {
1798
+ this.component.fadeDuration = value;
1799
+ }
1800
+ }
1801
+ /**
1802
+ * Gets the duration over which tint transitions are applied.
1803
+ * @returns The fade duration.
1804
+ */
1805
+ get fadeDuration() {
1806
+ return this._fadeDuration;
1807
+ }
1808
+ /**
1809
+ * Sets the id of the `pc-asset` sprite shown when the button is hovered (sprite transition
1810
+ * mode).
1811
+ * @param value - The hover sprite asset id.
1812
+ */
1813
+ set hoverSpriteAsset(value) {
1814
+ this._hoverSpriteAsset = value;
1815
+ const asset = AssetElement.get(value);
1816
+ if (this.component && asset) {
1817
+ this.component.hoverSpriteAsset = asset.id;
1818
+ }
1819
+ }
1820
+ /**
1821
+ * Gets the id of the `pc-asset` sprite shown when the button is hovered.
1822
+ * @returns The hover sprite asset id.
1823
+ */
1824
+ get hoverSpriteAsset() {
1825
+ return this._hoverSpriteAsset;
1826
+ }
1827
+ /**
1828
+ * Sets the frame of the hover sprite to show.
1829
+ * @param value - The hover sprite frame.
1830
+ */
1831
+ set hoverSpriteFrame(value) {
1832
+ this._hoverSpriteFrame = value;
1833
+ if (this.component) {
1834
+ this.component.hoverSpriteFrame = value;
1835
+ }
1836
+ }
1837
+ /**
1838
+ * Gets the frame of the hover sprite to show.
1839
+ * @returns The hover sprite frame.
1840
+ */
1841
+ get hoverSpriteFrame() {
1842
+ return this._hoverSpriteFrame;
1843
+ }
1844
+ /**
1845
+ * Sets the id of the `pc-asset` sprite shown when the button is pressed (sprite transition
1846
+ * mode).
1847
+ * @param value - The pressed sprite asset id.
1848
+ */
1849
+ set pressedSpriteAsset(value) {
1850
+ this._pressedSpriteAsset = value;
1851
+ const asset = AssetElement.get(value);
1852
+ if (this.component && asset) {
1853
+ this.component.pressedSpriteAsset = asset.id;
1854
+ }
1855
+ }
1856
+ /**
1857
+ * Gets the id of the `pc-asset` sprite shown when the button is pressed.
1858
+ * @returns The pressed sprite asset id.
1859
+ */
1860
+ get pressedSpriteAsset() {
1861
+ return this._pressedSpriteAsset;
1862
+ }
1863
+ /**
1864
+ * Sets the frame of the pressed sprite to show.
1865
+ * @param value - The pressed sprite frame.
1866
+ */
1867
+ set pressedSpriteFrame(value) {
1868
+ this._pressedSpriteFrame = value;
1869
+ if (this.component) {
1870
+ this.component.pressedSpriteFrame = value;
1871
+ }
1872
+ }
1873
+ /**
1874
+ * Gets the frame of the pressed sprite to show.
1875
+ * @returns The pressed sprite frame.
1876
+ */
1877
+ get pressedSpriteFrame() {
1878
+ return this._pressedSpriteFrame;
1879
+ }
1880
+ /**
1881
+ * Sets the id of the `pc-asset` sprite shown when the button is inactive (sprite transition
1882
+ * mode).
1883
+ * @param value - The inactive sprite asset id.
1884
+ */
1885
+ set inactiveSpriteAsset(value) {
1886
+ this._inactiveSpriteAsset = value;
1887
+ const asset = AssetElement.get(value);
1888
+ if (this.component && asset) {
1889
+ this.component.inactiveSpriteAsset = asset.id;
1890
+ }
1891
+ }
1892
+ /**
1893
+ * Gets the id of the `pc-asset` sprite shown when the button is inactive.
1894
+ * @returns The inactive sprite asset id.
1895
+ */
1896
+ get inactiveSpriteAsset() {
1897
+ return this._inactiveSpriteAsset;
1898
+ }
1899
+ /**
1900
+ * Sets the frame of the inactive sprite to show.
1901
+ * @param value - The inactive sprite frame.
1902
+ */
1903
+ set inactiveSpriteFrame(value) {
1904
+ this._inactiveSpriteFrame = value;
1905
+ if (this.component) {
1906
+ this.component.inactiveSpriteFrame = value;
1907
+ }
1908
+ }
1909
+ /**
1910
+ * Gets the frame of the inactive sprite to show.
1911
+ * @returns The inactive sprite frame.
1912
+ */
1913
+ get inactiveSpriteFrame() {
1914
+ return this._inactiveSpriteFrame;
1915
+ }
1916
+ static get observedAttributes() {
1917
+ return [
1918
+ ...super.observedAttributes,
1919
+ 'active',
1920
+ 'image',
1921
+ 'hit-padding',
1922
+ 'transition-mode',
1923
+ 'hover-tint',
1924
+ 'pressed-tint',
1925
+ 'inactive-tint',
1926
+ 'fade-duration',
1927
+ 'hover-sprite-asset',
1928
+ 'hover-sprite-frame',
1929
+ 'pressed-sprite-asset',
1930
+ 'pressed-sprite-frame',
1931
+ 'inactive-sprite-asset',
1932
+ 'inactive-sprite-frame'
1933
+ ];
1934
+ }
1935
+ attributeChangedCallback(name, _oldValue, newValue) {
1936
+ super.attributeChangedCallback(name, _oldValue, newValue);
1937
+ switch (name) {
1938
+ case 'active':
1939
+ this.active = newValue !== 'false';
1940
+ break;
1941
+ case 'image':
1942
+ this.image = newValue;
1943
+ break;
1944
+ case 'hit-padding':
1945
+ this.hitPadding = parseVec4(newValue);
1946
+ break;
1947
+ case 'transition-mode':
1948
+ this.transitionMode = parseEnum(newValue, transitionModes, BUTTON_TRANSITION_MODE_TINT);
1949
+ break;
1950
+ case 'hover-tint':
1951
+ this.hoverTint = parseColor(newValue);
1952
+ break;
1953
+ case 'pressed-tint':
1954
+ this.pressedTint = parseColor(newValue);
1955
+ break;
1956
+ case 'inactive-tint':
1957
+ this.inactiveTint = parseColor(newValue);
1958
+ break;
1959
+ case 'fade-duration':
1960
+ this.fadeDuration = Number(newValue);
1961
+ break;
1962
+ case 'hover-sprite-asset':
1963
+ this.hoverSpriteAsset = newValue;
1964
+ break;
1965
+ case 'hover-sprite-frame':
1966
+ this.hoverSpriteFrame = Number(newValue);
1967
+ break;
1968
+ case 'pressed-sprite-asset':
1969
+ this.pressedSpriteAsset = newValue;
1970
+ break;
1971
+ case 'pressed-sprite-frame':
1972
+ this.pressedSpriteFrame = Number(newValue);
1973
+ break;
1974
+ case 'inactive-sprite-asset':
1975
+ this.inactiveSpriteAsset = newValue;
1976
+ break;
1977
+ case 'inactive-sprite-frame':
1978
+ this.inactiveSpriteFrame = Number(newValue);
1979
+ break;
1980
+ }
1981
+ }
1982
+ }
1983
+ customElements.define('pc-button', ButtonComponentElement);
1984
+
1470
1985
  const tonemaps = new Map([
1471
1986
  ['none', TONEMAP_NONE],
1472
1987
  ['linear', TONEMAP_LINEAR],
@@ -2119,34 +2634,94 @@ class ElementComponentElement extends ComponentElement {
2119
2634
  this._anchor = new Vec4(0.5, 0.5, 0.5, 0.5);
2120
2635
  this._asset = '';
2121
2636
  this._autoWidth = true;
2637
+ this._autoHeight = true;
2638
+ this._autoFitWidth = false;
2639
+ this._autoFitHeight = false;
2122
2640
  this._color = new Color(1, 1, 1, 1);
2123
2641
  this._enableMarkup = false;
2124
2642
  this._fontSize = 32;
2643
+ this._maxFontSize = 32;
2644
+ this._minFontSize = 8;
2645
+ this._height = 0;
2125
2646
  this._lineHeight = 32;
2647
+ this._margin = null;
2648
+ this._mask = false;
2649
+ this._opacity = 1;
2126
2650
  this._pivot = new Vec2(0.5, 0.5);
2651
+ this._pixelsPerUnit = null;
2652
+ this._spriteAsset = '';
2653
+ this._spriteFrame = 0;
2127
2654
  this._text = '';
2655
+ this._textureAsset = '';
2128
2656
  this._type = 'group';
2657
+ this._useInput = false;
2129
2658
  this._width = 0;
2130
2659
  this._wrapLines = false;
2131
2660
  }
2132
2661
  initComponent() {
2133
- this.component._text._material.useFog = true;
2662
+ var _a, _b;
2663
+ const component = this.component;
2664
+ if (!component) {
2665
+ return;
2666
+ }
2667
+ // Text elements render through their own material; enable fog on it so 3D text respects
2668
+ // scene fog. Image/group elements have no text material, so guard the access.
2669
+ if ((_a = component._text) === null || _a === void 0 ? void 0 : _a._material) {
2670
+ component._text._material.useFog = true;
2671
+ }
2672
+ // The engine establishes element masking in ElementComponent._onInsert, which fires when an
2673
+ // entity is inserted into the hierarchy. Web-components inserts the entity first and adds
2674
+ // the element component afterwards, so that pass is missed. Re-dirty the mask state here so
2675
+ // masks (e.g. a scroll view viewport) correctly clip this element and any added at runtime.
2676
+ (_b = component._dirtifyMask) === null || _b === void 0 ? void 0 : _b.call(component);
2134
2677
  }
2135
2678
  getInitialComponentData() {
2136
- return {
2679
+ const data = {
2137
2680
  anchor: this._anchor,
2138
2681
  autoWidth: this._autoWidth,
2682
+ autoHeight: this._autoHeight,
2683
+ autoFitWidth: this._autoFitWidth,
2684
+ autoFitHeight: this._autoFitHeight,
2139
2685
  color: this._color,
2140
2686
  enableMarkup: this._enableMarkup,
2141
- fontAsset: AssetElement.get(this._asset).id,
2142
2687
  fontSize: this._fontSize,
2688
+ maxFontSize: this._maxFontSize,
2689
+ minFontSize: this._minFontSize,
2690
+ height: this._height,
2143
2691
  lineHeight: this._lineHeight,
2692
+ mask: this._mask,
2693
+ opacity: this._opacity,
2144
2694
  pivot: this._pivot,
2695
+ spriteFrame: this._spriteFrame,
2145
2696
  type: this._type,
2146
2697
  text: this._text,
2698
+ useInput: this._useInput,
2147
2699
  width: this._width,
2148
2700
  wrapLines: this._wrapLines
2149
2701
  };
2702
+ // Asset references are resolved from `<pc-asset>` element ids to engine asset ids. They are
2703
+ // only included when they resolve, so image/group elements (with no font) don't error.
2704
+ const fontAsset = AssetElement.get(this._asset);
2705
+ if (fontAsset) {
2706
+ data.fontAsset = fontAsset.id;
2707
+ }
2708
+ const spriteAsset = AssetElement.get(this._spriteAsset);
2709
+ if (spriteAsset) {
2710
+ data.spriteAsset = spriteAsset.id;
2711
+ }
2712
+ const textureAsset = AssetElement.get(this._textureAsset);
2713
+ if (textureAsset) {
2714
+ data.textureAsset = textureAsset.id;
2715
+ }
2716
+ // Margin is only applied when explicitly set. For stretched (split) anchors it governs the
2717
+ // element size; for point anchors width/height take over (handled by the engine).
2718
+ if (this._margin) {
2719
+ data.margin = this._margin;
2720
+ }
2721
+ if (this._pixelsPerUnit !== null) {
2722
+ data.pixelsPerUnit = this._pixelsPerUnit;
2723
+ }
2724
+ return data;
2150
2725
  }
2151
2726
  /**
2152
2727
  * Gets the underlying PlayCanvas element component.
@@ -2173,7 +2748,7 @@ class ElementComponentElement extends ComponentElement {
2173
2748
  return this._anchor;
2174
2749
  }
2175
2750
  /**
2176
- * Sets the id of the `pc-asset` to use for the font.
2751
+ * Sets the id of the `pc-asset` to use for the font (text elements).
2177
2752
  * @param value - The asset ID.
2178
2753
  */
2179
2754
  set asset(value) {
@@ -2191,7 +2766,8 @@ class ElementComponentElement extends ComponentElement {
2191
2766
  return this._asset;
2192
2767
  }
2193
2768
  /**
2194
- * Sets whether the element component should automatically adjust its width.
2769
+ * Sets whether the element component should automatically adjust its width to the text content
2770
+ * (text elements only).
2195
2771
  * @param value - Whether to automatically adjust the width.
2196
2772
  */
2197
2773
  set autoWidth(value) {
@@ -2207,6 +2783,24 @@ class ElementComponentElement extends ComponentElement {
2207
2783
  get autoWidth() {
2208
2784
  return this._autoWidth;
2209
2785
  }
2786
+ /**
2787
+ * Sets whether the element component should automatically adjust its height to the text content
2788
+ * (text elements only).
2789
+ * @param value - Whether to automatically adjust the height.
2790
+ */
2791
+ set autoHeight(value) {
2792
+ this._autoHeight = value;
2793
+ if (this.component) {
2794
+ this.component.autoHeight = value;
2795
+ }
2796
+ }
2797
+ /**
2798
+ * Gets whether the element component should automatically adjust its height.
2799
+ * @returns Whether to automatically adjust the height.
2800
+ */
2801
+ get autoHeight() {
2802
+ return this._autoHeight;
2803
+ }
2210
2804
  /**
2211
2805
  * Sets the color of the element component.
2212
2806
  * @param value - The color.
@@ -2258,6 +2852,23 @@ class ElementComponentElement extends ComponentElement {
2258
2852
  get fontSize() {
2259
2853
  return this._fontSize;
2260
2854
  }
2855
+ /**
2856
+ * Sets the height of the element component.
2857
+ * @param value - The height.
2858
+ */
2859
+ set height(value) {
2860
+ this._height = value;
2861
+ if (this.component) {
2862
+ this.component.height = value;
2863
+ }
2864
+ }
2865
+ /**
2866
+ * Gets the height of the element component.
2867
+ * @returns The height.
2868
+ */
2869
+ get height() {
2870
+ return this._height;
2871
+ }
2261
2872
  /**
2262
2873
  * Sets the line height of the element component.
2263
2874
  * @param value - The line height.
@@ -2276,56 +2887,195 @@ class ElementComponentElement extends ComponentElement {
2276
2887
  return this._lineHeight;
2277
2888
  }
2278
2889
  /**
2279
- * Sets the pivot of the element component.
2280
- * @param value - The pivot.
2890
+ * Sets the margin of the element component (used to inset the element from stretched anchors).
2891
+ * @param value - The margin as a Vec4 (left, bottom, right, top).
2281
2892
  */
2282
- set pivot(value) {
2283
- this._pivot = value;
2284
- if (this.component) {
2285
- this.component.pivot = value;
2893
+ set margin(value) {
2894
+ this._margin = value;
2895
+ if (this.component && value) {
2896
+ this.component.margin = value;
2286
2897
  }
2287
2898
  }
2288
2899
  /**
2289
- * Gets the pivot of the element component.
2290
- * @returns The pivot.
2900
+ * Gets the margin of the element component.
2901
+ * @returns The margin.
2291
2902
  */
2292
- get pivot() {
2293
- return this._pivot;
2903
+ get margin() {
2904
+ return this._margin;
2294
2905
  }
2295
2906
  /**
2296
- * Sets the text of the element component.
2297
- * @param value - The text.
2907
+ * Sets whether the element component is a mask, clipping its descendants to its bounds (image
2908
+ * elements only).
2909
+ * @param value - Whether the element is a mask.
2298
2910
  */
2299
- set text(value) {
2300
- this._text = value;
2911
+ set mask(value) {
2912
+ this._mask = value;
2301
2913
  if (this.component) {
2302
- this.component.text = value;
2914
+ this.component.mask = value;
2303
2915
  }
2304
2916
  }
2305
2917
  /**
2306
- * Gets the text of the element component.
2307
- * @returns The text.
2918
+ * Gets whether the element component is a mask.
2919
+ * @returns Whether the element is a mask.
2308
2920
  */
2309
- get text() {
2310
- return this._text;
2921
+ get mask() {
2922
+ return this._mask;
2311
2923
  }
2312
2924
  /**
2313
- * Sets the type of the element component.
2314
- * @param value - The type.
2925
+ * Sets the opacity of the element component.
2926
+ * @param value - The opacity (0 to 1).
2315
2927
  */
2316
- set type(value) {
2317
- this._type = value;
2928
+ set opacity(value) {
2929
+ this._opacity = value;
2318
2930
  if (this.component) {
2319
- this.component.type = value;
2931
+ this.component.opacity = value;
2320
2932
  }
2321
2933
  }
2322
2934
  /**
2323
- * Gets the type of the element component.
2935
+ * Gets the opacity of the element component.
2936
+ * @returns The opacity.
2937
+ */
2938
+ get opacity() {
2939
+ return this._opacity;
2940
+ }
2941
+ /**
2942
+ * Sets the pivot of the element component.
2943
+ * @param value - The pivot.
2944
+ */
2945
+ set pivot(value) {
2946
+ this._pivot = value;
2947
+ if (this.component) {
2948
+ this.component.pivot = value;
2949
+ }
2950
+ }
2951
+ /**
2952
+ * Gets the pivot of the element component.
2953
+ * @returns The pivot.
2954
+ */
2955
+ get pivot() {
2956
+ return this._pivot;
2957
+ }
2958
+ /**
2959
+ * Sets the number of pixels per unit to use when rendering a sprite (image elements only).
2960
+ * @param value - The pixels per unit.
2961
+ */
2962
+ set pixelsPerUnit(value) {
2963
+ this._pixelsPerUnit = value;
2964
+ if (this.component && value !== null) {
2965
+ this.component.pixelsPerUnit = value;
2966
+ }
2967
+ }
2968
+ /**
2969
+ * Gets the number of pixels per unit used when rendering a sprite.
2970
+ * @returns The pixels per unit.
2971
+ */
2972
+ get pixelsPerUnit() {
2973
+ return this._pixelsPerUnit;
2974
+ }
2975
+ /**
2976
+ * Sets the id of the `pc-asset` to use for the sprite (image elements only).
2977
+ * @param value - The sprite asset ID.
2978
+ */
2979
+ set spriteAsset(value) {
2980
+ this._spriteAsset = value;
2981
+ const asset = AssetElement.get(value);
2982
+ if (this.component && asset) {
2983
+ this.component.spriteAsset = asset.id;
2984
+ }
2985
+ }
2986
+ /**
2987
+ * Gets the id of the `pc-asset` to use for the sprite.
2988
+ * @returns The sprite asset ID.
2989
+ */
2990
+ get spriteAsset() {
2991
+ return this._spriteAsset;
2992
+ }
2993
+ /**
2994
+ * Sets the frame of the sprite to render (image elements only).
2995
+ * @param value - The sprite frame index.
2996
+ */
2997
+ set spriteFrame(value) {
2998
+ this._spriteFrame = value;
2999
+ if (this.component) {
3000
+ this.component.spriteFrame = value;
3001
+ }
3002
+ }
3003
+ /**
3004
+ * Gets the frame of the sprite to render.
3005
+ * @returns The sprite frame index.
3006
+ */
3007
+ get spriteFrame() {
3008
+ return this._spriteFrame;
3009
+ }
3010
+ /**
3011
+ * Sets the text of the element component.
3012
+ * @param value - The text.
3013
+ */
3014
+ set text(value) {
3015
+ this._text = value;
3016
+ if (this.component) {
3017
+ this.component.text = value;
3018
+ }
3019
+ }
3020
+ /**
3021
+ * Gets the text of the element component.
3022
+ * @returns The text.
3023
+ */
3024
+ get text() {
3025
+ return this._text;
3026
+ }
3027
+ /**
3028
+ * Sets the id of the `pc-asset` to use for the texture (image elements only).
3029
+ * @param value - The texture asset ID.
3030
+ */
3031
+ set textureAsset(value) {
3032
+ this._textureAsset = value;
3033
+ const asset = AssetElement.get(value);
3034
+ if (this.component && asset) {
3035
+ this.component.textureAsset = asset.id;
3036
+ }
3037
+ }
3038
+ /**
3039
+ * Gets the id of the `pc-asset` to use for the texture.
3040
+ * @returns The texture asset ID.
3041
+ */
3042
+ get textureAsset() {
3043
+ return this._textureAsset;
3044
+ }
3045
+ /**
3046
+ * Sets the type of the element component.
3047
+ * @param value - The type.
3048
+ */
3049
+ set type(value) {
3050
+ this._type = value;
3051
+ if (this.component) {
3052
+ this.component.type = value;
3053
+ }
3054
+ }
3055
+ /**
3056
+ * Gets the type of the element component.
2324
3057
  * @returns The type.
2325
3058
  */
2326
3059
  get type() {
2327
3060
  return this._type;
2328
3061
  }
3062
+ /**
3063
+ * Sets whether the element component accepts input events (required for buttons and scrolling).
3064
+ * @param value - Whether the element accepts input.
3065
+ */
3066
+ set useInput(value) {
3067
+ this._useInput = value;
3068
+ if (this.component) {
3069
+ this.component.useInput = value;
3070
+ }
3071
+ }
3072
+ /**
3073
+ * Gets whether the element component accepts input events.
3074
+ * @returns Whether the element accepts input.
3075
+ */
3076
+ get useInput() {
3077
+ return this._useInput;
3078
+ }
2329
3079
  /**
2330
3080
  * Sets the width of the element component.
2331
3081
  * @param value - The width.
@@ -2360,19 +3110,103 @@ class ElementComponentElement extends ComponentElement {
2360
3110
  get wrapLines() {
2361
3111
  return this._wrapLines;
2362
3112
  }
3113
+ /**
3114
+ * Sets whether a text element should automatically reduce its font size (down to `min-font-size`)
3115
+ * so the text fits within the element's width. Requires `auto-width` to be `false`.
3116
+ * @param value - Whether to auto-fit the width.
3117
+ */
3118
+ set autoFitWidth(value) {
3119
+ this._autoFitWidth = value;
3120
+ if (this.component) {
3121
+ this.component.autoFitWidth = value;
3122
+ }
3123
+ }
3124
+ /**
3125
+ * Gets whether a text element automatically reduces its font size to fit its width.
3126
+ * @returns Whether the width is auto-fit.
3127
+ */
3128
+ get autoFitWidth() {
3129
+ return this._autoFitWidth;
3130
+ }
3131
+ /**
3132
+ * Sets whether a text element should automatically reduce its font size (down to `min-font-size`)
3133
+ * so the text fits within the element's height. Requires `auto-height` to be `false`.
3134
+ * @param value - Whether to auto-fit the height.
3135
+ */
3136
+ set autoFitHeight(value) {
3137
+ this._autoFitHeight = value;
3138
+ if (this.component) {
3139
+ this.component.autoFitHeight = value;
3140
+ }
3141
+ }
3142
+ /**
3143
+ * Gets whether a text element automatically reduces its font size to fit its height.
3144
+ * @returns Whether the height is auto-fit.
3145
+ */
3146
+ get autoFitHeight() {
3147
+ return this._autoFitHeight;
3148
+ }
3149
+ /**
3150
+ * Sets the smallest font size a text element may use when auto-fitting.
3151
+ * @param value - The minimum font size.
3152
+ */
3153
+ set minFontSize(value) {
3154
+ this._minFontSize = value;
3155
+ if (this.component) {
3156
+ this.component.minFontSize = value;
3157
+ }
3158
+ }
3159
+ /**
3160
+ * Gets the smallest font size a text element may use when auto-fitting.
3161
+ * @returns The minimum font size.
3162
+ */
3163
+ get minFontSize() {
3164
+ return this._minFontSize;
3165
+ }
3166
+ /**
3167
+ * Sets the largest font size a text element may use when auto-fitting.
3168
+ * @param value - The maximum font size.
3169
+ */
3170
+ set maxFontSize(value) {
3171
+ this._maxFontSize = value;
3172
+ if (this.component) {
3173
+ this.component.maxFontSize = value;
3174
+ }
3175
+ }
3176
+ /**
3177
+ * Gets the largest font size a text element may use when auto-fitting.
3178
+ * @returns The maximum font size.
3179
+ */
3180
+ get maxFontSize() {
3181
+ return this._maxFontSize;
3182
+ }
2363
3183
  static get observedAttributes() {
2364
3184
  return [
2365
3185
  ...super.observedAttributes,
2366
3186
  'anchor',
2367
3187
  'asset',
2368
3188
  'auto-width',
3189
+ 'auto-height',
3190
+ 'auto-fit-width',
3191
+ 'auto-fit-height',
2369
3192
  'color',
2370
3193
  'enable-markup',
2371
3194
  'font-size',
3195
+ 'max-font-size',
3196
+ 'min-font-size',
3197
+ 'height',
2372
3198
  'line-height',
3199
+ 'margin',
3200
+ 'mask',
3201
+ 'opacity',
2373
3202
  'pivot',
3203
+ 'pixels-per-unit',
3204
+ 'sprite-asset',
3205
+ 'sprite-frame',
2374
3206
  'text',
3207
+ 'texture-asset',
2375
3208
  'type',
3209
+ 'use-input',
2376
3210
  'width',
2377
3211
  'wrap-lines'
2378
3212
  ];
@@ -2389,37 +3223,535 @@ class ElementComponentElement extends ComponentElement {
2389
3223
  case 'auto-width':
2390
3224
  this.autoWidth = newValue !== 'false';
2391
3225
  break;
3226
+ case 'auto-height':
3227
+ this.autoHeight = newValue !== 'false';
3228
+ break;
3229
+ case 'auto-fit-width':
3230
+ this.autoFitWidth = newValue !== 'false';
3231
+ break;
3232
+ case 'auto-fit-height':
3233
+ this.autoFitHeight = newValue !== 'false';
3234
+ break;
2392
3235
  case 'color':
2393
3236
  this.color = parseColor(newValue);
2394
3237
  break;
2395
- case 'enable-markup':
2396
- this.enableMarkup = this.hasAttribute(name);
3238
+ case 'enable-markup':
3239
+ this.enableMarkup = this.hasAttribute(name);
3240
+ break;
3241
+ case 'font-size':
3242
+ this.fontSize = Number(newValue);
3243
+ break;
3244
+ case 'max-font-size':
3245
+ this.maxFontSize = Number(newValue);
3246
+ break;
3247
+ case 'min-font-size':
3248
+ this.minFontSize = Number(newValue);
3249
+ break;
3250
+ case 'height':
3251
+ this.height = Number(newValue);
3252
+ break;
3253
+ case 'line-height':
3254
+ this.lineHeight = Number(newValue);
3255
+ break;
3256
+ case 'margin':
3257
+ this.margin = parseVec4(newValue);
3258
+ break;
3259
+ case 'mask':
3260
+ this.mask = this.hasAttribute(name);
3261
+ break;
3262
+ case 'opacity':
3263
+ this.opacity = Number(newValue);
3264
+ break;
3265
+ case 'pivot':
3266
+ this.pivot = parseVec2(newValue);
3267
+ break;
3268
+ case 'pixels-per-unit':
3269
+ this.pixelsPerUnit = Number(newValue);
3270
+ break;
3271
+ case 'sprite-asset':
3272
+ this.spriteAsset = newValue;
3273
+ break;
3274
+ case 'sprite-frame':
3275
+ this.spriteFrame = Number(newValue);
3276
+ break;
3277
+ case 'text':
3278
+ this.text = newValue;
3279
+ break;
3280
+ case 'texture-asset':
3281
+ this.textureAsset = newValue;
3282
+ break;
3283
+ case 'type':
3284
+ this.type = newValue;
3285
+ break;
3286
+ case 'use-input':
3287
+ this.useInput = this.hasAttribute(name);
3288
+ break;
3289
+ case 'width':
3290
+ this.width = Number(newValue);
3291
+ break;
3292
+ case 'wrap-lines':
3293
+ this.wrapLines = this.hasAttribute(name);
3294
+ break;
3295
+ }
3296
+ }
3297
+ }
3298
+ customElements.define('pc-element', ElementComponentElement);
3299
+
3300
+ /**
3301
+ * The LayoutChildComponentElement interface provides properties and methods for manipulating
3302
+ * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-layoutchild/ | `<pc-layoutchild>`} elements.
3303
+ * The LayoutChildComponentElement interface also inherits the properties and methods of the
3304
+ * {@link HTMLElement} interface.
3305
+ *
3306
+ * @category Components
3307
+ */
3308
+ class LayoutChildComponentElement extends ComponentElement {
3309
+ /** @ignore */
3310
+ constructor() {
3311
+ super('layoutchild');
3312
+ this._minWidth = 0;
3313
+ this._minHeight = 0;
3314
+ this._maxWidth = null;
3315
+ this._maxHeight = null;
3316
+ this._fitWidthProportion = 0;
3317
+ this._fitHeightProportion = 0;
3318
+ this._excludeFromLayout = false;
3319
+ }
3320
+ getInitialComponentData() {
3321
+ return {
3322
+ minWidth: this._minWidth,
3323
+ minHeight: this._minHeight,
3324
+ maxWidth: this._maxWidth,
3325
+ maxHeight: this._maxHeight,
3326
+ fitWidthProportion: this._fitWidthProportion,
3327
+ fitHeightProportion: this._fitHeightProportion,
3328
+ excludeFromLayout: this._excludeFromLayout
3329
+ };
3330
+ }
3331
+ /**
3332
+ * Gets the underlying PlayCanvas layout child component.
3333
+ * @returns The layout child component.
3334
+ */
3335
+ get component() {
3336
+ return super.component;
3337
+ }
3338
+ /**
3339
+ * Sets the minimum width the element should be laid out with.
3340
+ * @param value - The minimum width.
3341
+ */
3342
+ set minWidth(value) {
3343
+ this._minWidth = value;
3344
+ if (this.component) {
3345
+ this.component.minWidth = value;
3346
+ }
3347
+ }
3348
+ /**
3349
+ * Gets the minimum width the element should be laid out with.
3350
+ * @returns The minimum width.
3351
+ */
3352
+ get minWidth() {
3353
+ return this._minWidth;
3354
+ }
3355
+ /**
3356
+ * Sets the minimum height the element should be laid out with.
3357
+ * @param value - The minimum height.
3358
+ */
3359
+ set minHeight(value) {
3360
+ this._minHeight = value;
3361
+ if (this.component) {
3362
+ this.component.minHeight = value;
3363
+ }
3364
+ }
3365
+ /**
3366
+ * Gets the minimum height the element should be laid out with.
3367
+ * @returns The minimum height.
3368
+ */
3369
+ get minHeight() {
3370
+ return this._minHeight;
3371
+ }
3372
+ /**
3373
+ * Sets the maximum width the element should be laid out with (or `null` for no limit).
3374
+ * @param value - The maximum width.
3375
+ */
3376
+ set maxWidth(value) {
3377
+ this._maxWidth = value;
3378
+ if (this.component) {
3379
+ this.component.maxWidth = value;
3380
+ }
3381
+ }
3382
+ /**
3383
+ * Gets the maximum width the element should be laid out with.
3384
+ * @returns The maximum width.
3385
+ */
3386
+ get maxWidth() {
3387
+ return this._maxWidth;
3388
+ }
3389
+ /**
3390
+ * Sets the maximum height the element should be laid out with (or `null` for no limit).
3391
+ * @param value - The maximum height.
3392
+ */
3393
+ set maxHeight(value) {
3394
+ this._maxHeight = value;
3395
+ if (this.component) {
3396
+ this.component.maxHeight = value;
3397
+ }
3398
+ }
3399
+ /**
3400
+ * Gets the maximum height the element should be laid out with.
3401
+ * @returns The maximum height.
3402
+ */
3403
+ get maxHeight() {
3404
+ return this._maxHeight;
3405
+ }
3406
+ /**
3407
+ * Sets the proportion of the container's spare width this element should take (when the layout
3408
+ * group's `width-fitting` is set to stretch or shrink).
3409
+ * @param value - The fit width proportion.
3410
+ */
3411
+ set fitWidthProportion(value) {
3412
+ this._fitWidthProportion = value;
3413
+ if (this.component) {
3414
+ this.component.fitWidthProportion = value;
3415
+ }
3416
+ }
3417
+ /**
3418
+ * Gets the proportion of the container's spare width this element should take.
3419
+ * @returns The fit width proportion.
3420
+ */
3421
+ get fitWidthProportion() {
3422
+ return this._fitWidthProportion;
3423
+ }
3424
+ /**
3425
+ * Sets the proportion of the container's spare height this element should take (when the layout
3426
+ * group's `height-fitting` is set to stretch or shrink).
3427
+ * @param value - The fit height proportion.
3428
+ */
3429
+ set fitHeightProportion(value) {
3430
+ this._fitHeightProportion = value;
3431
+ if (this.component) {
3432
+ this.component.fitHeightProportion = value;
3433
+ }
3434
+ }
3435
+ /**
3436
+ * Gets the proportion of the container's spare height this element should take.
3437
+ * @returns The fit height proportion.
3438
+ */
3439
+ get fitHeightProportion() {
3440
+ return this._fitHeightProportion;
3441
+ }
3442
+ /**
3443
+ * Sets whether the element should be excluded from the layout (and thus not take up space).
3444
+ * @param value - Whether to exclude the element from layout.
3445
+ */
3446
+ set excludeFromLayout(value) {
3447
+ this._excludeFromLayout = value;
3448
+ if (this.component) {
3449
+ this.component.excludeFromLayout = value;
3450
+ }
3451
+ }
3452
+ /**
3453
+ * Gets whether the element is excluded from the layout.
3454
+ * @returns Whether the element is excluded from layout.
3455
+ */
3456
+ get excludeFromLayout() {
3457
+ return this._excludeFromLayout;
3458
+ }
3459
+ static get observedAttributes() {
3460
+ return [
3461
+ ...super.observedAttributes,
3462
+ 'min-width',
3463
+ 'min-height',
3464
+ 'max-width',
3465
+ 'max-height',
3466
+ 'fit-width-proportion',
3467
+ 'fit-height-proportion',
3468
+ 'exclude-from-layout'
3469
+ ];
3470
+ }
3471
+ attributeChangedCallback(name, _oldValue, newValue) {
3472
+ super.attributeChangedCallback(name, _oldValue, newValue);
3473
+ switch (name) {
3474
+ case 'min-width':
3475
+ this.minWidth = Number(newValue);
3476
+ break;
3477
+ case 'min-height':
3478
+ this.minHeight = Number(newValue);
3479
+ break;
3480
+ case 'max-width':
3481
+ this.maxWidth = newValue === '' ? null : Number(newValue);
3482
+ break;
3483
+ case 'max-height':
3484
+ this.maxHeight = newValue === '' ? null : Number(newValue);
3485
+ break;
3486
+ case 'fit-width-proportion':
3487
+ this.fitWidthProportion = Number(newValue);
3488
+ break;
3489
+ case 'fit-height-proportion':
3490
+ this.fitHeightProportion = Number(newValue);
3491
+ break;
3492
+ case 'exclude-from-layout':
3493
+ this.excludeFromLayout = newValue !== 'false';
3494
+ break;
3495
+ }
3496
+ }
3497
+ }
3498
+ customElements.define('pc-layoutchild', LayoutChildComponentElement);
3499
+
3500
+ const orientations$1 = new Map([
3501
+ ['horizontal', ORIENTATION_HORIZONTAL],
3502
+ ['vertical', ORIENTATION_VERTICAL]
3503
+ ]);
3504
+ const fittings = new Map([
3505
+ ['none', FITTING_NONE],
3506
+ ['stretch', FITTING_STRETCH],
3507
+ ['shrink', FITTING_SHRINK],
3508
+ ['both', FITTING_BOTH]
3509
+ ]);
3510
+ /**
3511
+ * The LayoutGroupComponentElement interface provides properties and methods for manipulating
3512
+ * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-layoutgroup/ | `<pc-layoutgroup>`} elements.
3513
+ * The LayoutGroupComponentElement interface also inherits the properties and methods of the
3514
+ * {@link HTMLElement} interface.
3515
+ *
3516
+ * @category Components
3517
+ */
3518
+ class LayoutGroupComponentElement extends ComponentElement {
3519
+ /** @ignore */
3520
+ constructor() {
3521
+ super('layoutgroup');
3522
+ this._orientation = ORIENTATION_HORIZONTAL;
3523
+ this._reverseX = false;
3524
+ this._reverseY = false;
3525
+ this._alignment = new Vec2(0, 1);
3526
+ this._padding = new Vec4(0, 0, 0, 0);
3527
+ this._spacing = new Vec2(0, 0);
3528
+ this._widthFitting = FITTING_NONE;
3529
+ this._heightFitting = FITTING_NONE;
3530
+ this._wrap = false;
3531
+ }
3532
+ getInitialComponentData() {
3533
+ return {
3534
+ orientation: this._orientation,
3535
+ reverseX: this._reverseX,
3536
+ reverseY: this._reverseY,
3537
+ alignment: this._alignment,
3538
+ padding: this._padding,
3539
+ spacing: this._spacing,
3540
+ widthFitting: this._widthFitting,
3541
+ heightFitting: this._heightFitting,
3542
+ wrap: this._wrap
3543
+ };
3544
+ }
3545
+ /**
3546
+ * Gets the underlying PlayCanvas layout group component.
3547
+ * @returns The layout group component.
3548
+ */
3549
+ get component() {
3550
+ return super.component;
3551
+ }
3552
+ /**
3553
+ * Sets the orientation of the layout group. Can be `horizontal` (0) or `vertical` (1).
3554
+ * @param value - The orientation.
3555
+ */
3556
+ set orientation(value) {
3557
+ this._orientation = value;
3558
+ if (this.component) {
3559
+ this.component.orientation = value;
3560
+ }
3561
+ }
3562
+ /**
3563
+ * Gets the orientation of the layout group.
3564
+ * @returns The orientation.
3565
+ */
3566
+ get orientation() {
3567
+ return this._orientation;
3568
+ }
3569
+ /**
3570
+ * Sets whether the order of children is reversed along the horizontal axis.
3571
+ * @param value - Whether to reverse the horizontal order.
3572
+ */
3573
+ set reverseX(value) {
3574
+ this._reverseX = value;
3575
+ if (this.component) {
3576
+ this.component.reverseX = value;
3577
+ }
3578
+ }
3579
+ /**
3580
+ * Gets whether the order of children is reversed along the horizontal axis.
3581
+ * @returns Whether the horizontal order is reversed.
3582
+ */
3583
+ get reverseX() {
3584
+ return this._reverseX;
3585
+ }
3586
+ /**
3587
+ * Sets whether the order of children is reversed along the vertical axis.
3588
+ * @param value - Whether to reverse the vertical order.
3589
+ */
3590
+ set reverseY(value) {
3591
+ this._reverseY = value;
3592
+ if (this.component) {
3593
+ this.component.reverseY = value;
3594
+ }
3595
+ }
3596
+ /**
3597
+ * Gets whether the order of children is reversed along the vertical axis.
3598
+ * @returns Whether the vertical order is reversed.
3599
+ */
3600
+ get reverseY() {
3601
+ return this._reverseY;
3602
+ }
3603
+ /**
3604
+ * Sets the horizontal and vertical alignment of the child elements (each component 0 to 1).
3605
+ * @param value - The alignment.
3606
+ */
3607
+ set alignment(value) {
3608
+ this._alignment = value;
3609
+ if (this.component) {
3610
+ this.component.alignment = value;
3611
+ }
3612
+ }
3613
+ /**
3614
+ * Gets the alignment of the child elements.
3615
+ * @returns The alignment.
3616
+ */
3617
+ get alignment() {
3618
+ return this._alignment;
3619
+ }
3620
+ /**
3621
+ * Sets the padding around the layout group, as a Vec4 (left, bottom, right, top).
3622
+ * @param value - The padding.
3623
+ */
3624
+ set padding(value) {
3625
+ this._padding = value;
3626
+ if (this.component) {
3627
+ this.component.padding = value;
3628
+ }
3629
+ }
3630
+ /**
3631
+ * Gets the padding around the layout group.
3632
+ * @returns The padding.
3633
+ */
3634
+ get padding() {
3635
+ return this._padding;
3636
+ }
3637
+ /**
3638
+ * Sets the spacing between child elements, as a Vec2 (x, y).
3639
+ * @param value - The spacing.
3640
+ */
3641
+ set spacing(value) {
3642
+ this._spacing = value;
3643
+ if (this.component) {
3644
+ this.component.spacing = value;
3645
+ }
3646
+ }
3647
+ /**
3648
+ * Gets the spacing between child elements.
3649
+ * @returns The spacing.
3650
+ */
3651
+ get spacing() {
3652
+ return this._spacing;
3653
+ }
3654
+ /**
3655
+ * Sets the fitting mode along the horizontal axis. Can be `none` (0), `stretch` (1), `shrink`
3656
+ * (2) or `both` (3).
3657
+ * @param value - The width fitting mode.
3658
+ */
3659
+ set widthFitting(value) {
3660
+ this._widthFitting = value;
3661
+ if (this.component) {
3662
+ this.component.widthFitting = value;
3663
+ }
3664
+ }
3665
+ /**
3666
+ * Gets the fitting mode along the horizontal axis.
3667
+ * @returns The width fitting mode.
3668
+ */
3669
+ get widthFitting() {
3670
+ return this._widthFitting;
3671
+ }
3672
+ /**
3673
+ * Sets the fitting mode along the vertical axis. Can be `none` (0), `stretch` (1), `shrink` (2)
3674
+ * or `both` (3).
3675
+ * @param value - The height fitting mode.
3676
+ */
3677
+ set heightFitting(value) {
3678
+ this._heightFitting = value;
3679
+ if (this.component) {
3680
+ this.component.heightFitting = value;
3681
+ }
3682
+ }
3683
+ /**
3684
+ * Gets the fitting mode along the vertical axis.
3685
+ * @returns The height fitting mode.
3686
+ */
3687
+ get heightFitting() {
3688
+ return this._heightFitting;
3689
+ }
3690
+ /**
3691
+ * Sets whether children wrap onto a new line/column when they overflow the group.
3692
+ * @param value - Whether to wrap children.
3693
+ */
3694
+ set wrap(value) {
3695
+ this._wrap = value;
3696
+ if (this.component) {
3697
+ this.component.wrap = value;
3698
+ }
3699
+ }
3700
+ /**
3701
+ * Gets whether children wrap onto a new line/column when they overflow the group.
3702
+ * @returns Whether children wrap.
3703
+ */
3704
+ get wrap() {
3705
+ return this._wrap;
3706
+ }
3707
+ static get observedAttributes() {
3708
+ return [
3709
+ ...super.observedAttributes,
3710
+ 'orientation',
3711
+ 'reverse-x',
3712
+ 'reverse-y',
3713
+ 'alignment',
3714
+ 'padding',
3715
+ 'spacing',
3716
+ 'width-fitting',
3717
+ 'height-fitting',
3718
+ 'wrap'
3719
+ ];
3720
+ }
3721
+ attributeChangedCallback(name, _oldValue, newValue) {
3722
+ super.attributeChangedCallback(name, _oldValue, newValue);
3723
+ switch (name) {
3724
+ case 'orientation':
3725
+ this.orientation = parseEnum(newValue, orientations$1, ORIENTATION_HORIZONTAL);
3726
+ break;
3727
+ case 'reverse-x':
3728
+ this.reverseX = newValue !== 'false';
2397
3729
  break;
2398
- case 'font-size':
2399
- this.fontSize = Number(newValue);
3730
+ case 'reverse-y':
3731
+ this.reverseY = newValue !== 'false';
2400
3732
  break;
2401
- case 'line-height':
2402
- this.lineHeight = Number(newValue);
3733
+ case 'alignment':
3734
+ this.alignment = parseVec2(newValue);
2403
3735
  break;
2404
- case 'pivot':
2405
- this.pivot = parseVec2(newValue);
3736
+ case 'padding':
3737
+ this.padding = parseVec4(newValue);
2406
3738
  break;
2407
- case 'text':
2408
- this.text = newValue;
3739
+ case 'spacing':
3740
+ this.spacing = parseVec2(newValue);
2409
3741
  break;
2410
- case 'type':
2411
- this.type = newValue;
3742
+ case 'width-fitting':
3743
+ this.widthFitting = parseEnum(newValue, fittings, FITTING_NONE);
2412
3744
  break;
2413
- case 'width':
2414
- this.width = Number(newValue);
3745
+ case 'height-fitting':
3746
+ this.heightFitting = parseEnum(newValue, fittings, FITTING_NONE);
2415
3747
  break;
2416
- case 'wrap-lines':
2417
- this.wrapLines = this.hasAttribute(name);
3748
+ case 'wrap':
3749
+ this.wrap = newValue !== 'false';
2418
3750
  break;
2419
3751
  }
2420
3752
  }
2421
3753
  }
2422
- customElements.define('pc-element', ElementComponentElement);
3754
+ customElements.define('pc-layoutgroup', LayoutGroupComponentElement);
2423
3755
 
2424
3756
  const shadowTypes = new Map([
2425
3757
  ['pcf1-16f', SHADOW_PCF1_16F],
@@ -3608,6 +4940,514 @@ class ScreenComponentElement extends ComponentElement {
3608
4940
  }
3609
4941
  customElements.define('pc-screen', ScreenComponentElement);
3610
4942
 
4943
+ const orientations = new Map([
4944
+ ['horizontal', ORIENTATION_HORIZONTAL],
4945
+ ['vertical', ORIENTATION_VERTICAL]
4946
+ ]);
4947
+ /**
4948
+ * The ScrollbarComponentElement interface provides properties and methods for manipulating
4949
+ * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-scrollbar/ | `<pc-scrollbar>`} elements.
4950
+ * The ScrollbarComponentElement interface also inherits the properties and methods of the
4951
+ * {@link HTMLElement} interface.
4952
+ *
4953
+ * @category Components
4954
+ */
4955
+ class ScrollbarComponentElement extends ComponentElement {
4956
+ /** @ignore */
4957
+ constructor() {
4958
+ super('scrollbar');
4959
+ this._orientation = ORIENTATION_HORIZONTAL;
4960
+ this._value = 0;
4961
+ this._handleSize = 0.5;
4962
+ this._handle = '';
4963
+ }
4964
+ getInitialComponentData() {
4965
+ const data = {
4966
+ orientation: this._orientation,
4967
+ value: this._value,
4968
+ handleSize: this._handleSize
4969
+ };
4970
+ const handle = getEntity(this._handle);
4971
+ if (handle) {
4972
+ data.handleEntity = handle;
4973
+ }
4974
+ return data;
4975
+ }
4976
+ /**
4977
+ * Gets the underlying PlayCanvas scrollbar component.
4978
+ * @returns The scrollbar component.
4979
+ */
4980
+ get component() {
4981
+ return super.component;
4982
+ }
4983
+ /**
4984
+ * Sets the orientation of the scrollbar. Can be `horizontal` (0) or `vertical` (1).
4985
+ * @param value - The orientation.
4986
+ */
4987
+ set orientation(value) {
4988
+ this._orientation = value;
4989
+ if (this.component) {
4990
+ this.component.orientation = value;
4991
+ }
4992
+ }
4993
+ /**
4994
+ * Gets the orientation of the scrollbar.
4995
+ * @returns The orientation.
4996
+ */
4997
+ get orientation() {
4998
+ return this._orientation;
4999
+ }
5000
+ /**
5001
+ * Sets the current position value of the scrollbar, in the range 0 to 1.
5002
+ * @param value - The scrollbar value.
5003
+ */
5004
+ set value(value) {
5005
+ this._value = value;
5006
+ if (this.component) {
5007
+ this.component.value = value;
5008
+ }
5009
+ }
5010
+ /**
5011
+ * Gets the current position value of the scrollbar.
5012
+ * @returns The scrollbar value.
5013
+ */
5014
+ get value() {
5015
+ return this._value;
5016
+ }
5017
+ /**
5018
+ * Sets the size of the handle relative to the size of the track, in the range 0 to 1.
5019
+ * @param value - The handle size.
5020
+ */
5021
+ set handleSize(value) {
5022
+ this._handleSize = value;
5023
+ if (this.component) {
5024
+ this.component.handleSize = value;
5025
+ }
5026
+ }
5027
+ /**
5028
+ * Gets the size of the handle relative to the size of the track.
5029
+ * @returns The handle size.
5030
+ */
5031
+ get handleSize() {
5032
+ return this._handleSize;
5033
+ }
5034
+ /**
5035
+ * Sets the reference (CSS selector, element id or entity name) to the `<pc-entity>` used as the
5036
+ * scrollbar handle.
5037
+ * @param value - The handle entity reference.
5038
+ */
5039
+ set handle(value) {
5040
+ this._handle = value;
5041
+ const entity = getEntity(value);
5042
+ if (this.component && entity) {
5043
+ this.component.handleEntity = entity;
5044
+ }
5045
+ }
5046
+ /**
5047
+ * Gets the reference to the `<pc-entity>` used as the scrollbar handle.
5048
+ * @returns The handle entity reference.
5049
+ */
5050
+ get handle() {
5051
+ return this._handle;
5052
+ }
5053
+ static get observedAttributes() {
5054
+ return [
5055
+ ...super.observedAttributes,
5056
+ 'orientation',
5057
+ 'value',
5058
+ 'handle-size',
5059
+ 'handle'
5060
+ ];
5061
+ }
5062
+ attributeChangedCallback(name, _oldValue, newValue) {
5063
+ super.attributeChangedCallback(name, _oldValue, newValue);
5064
+ switch (name) {
5065
+ case 'orientation':
5066
+ this.orientation = parseEnum(newValue, orientations, ORIENTATION_HORIZONTAL);
5067
+ break;
5068
+ case 'value':
5069
+ this.value = Number(newValue);
5070
+ break;
5071
+ case 'handle-size':
5072
+ this.handleSize = Number(newValue);
5073
+ break;
5074
+ case 'handle':
5075
+ this.handle = newValue;
5076
+ break;
5077
+ }
5078
+ }
5079
+ }
5080
+ customElements.define('pc-scrollbar', ScrollbarComponentElement);
5081
+
5082
+ const scrollModes = new Map([
5083
+ ['clamp', SCROLL_MODE_CLAMP],
5084
+ ['bounce', SCROLL_MODE_BOUNCE],
5085
+ ['infinite', SCROLL_MODE_INFINITE]
5086
+ ]);
5087
+ const visibilities = new Map([
5088
+ ['always', SCROLLBAR_VISIBILITY_SHOW_ALWAYS],
5089
+ ['when-required', SCROLLBAR_VISIBILITY_SHOW_WHEN_REQUIRED]
5090
+ ]);
5091
+ /**
5092
+ * The ScrollViewComponentElement interface provides properties and methods for manipulating
5093
+ * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-scrollview/ | `<pc-scrollview>`} elements.
5094
+ * The ScrollViewComponentElement interface also inherits the properties and methods of the
5095
+ * {@link HTMLElement} interface.
5096
+ *
5097
+ * @category Components
5098
+ */
5099
+ class ScrollViewComponentElement extends ComponentElement {
5100
+ /** @ignore */
5101
+ constructor() {
5102
+ super('scrollview');
5103
+ this._horizontal = true;
5104
+ this._vertical = true;
5105
+ this._scrollMode = SCROLL_MODE_BOUNCE;
5106
+ this._bounceAmount = 0.1;
5107
+ this._friction = 0.05;
5108
+ this._useMouseWheel = true;
5109
+ this._mouseWheelSensitivity = new Vec2(1, 1);
5110
+ this._horizontalScrollbarVisibility = SCROLLBAR_VISIBILITY_SHOW_WHEN_REQUIRED;
5111
+ this._verticalScrollbarVisibility = SCROLLBAR_VISIBILITY_SHOW_WHEN_REQUIRED;
5112
+ this._viewport = '';
5113
+ this._content = '';
5114
+ this._horizontalScrollbar = '';
5115
+ this._verticalScrollbar = '';
5116
+ }
5117
+ getInitialComponentData() {
5118
+ const data = {
5119
+ horizontal: this._horizontal,
5120
+ vertical: this._vertical,
5121
+ scrollMode: this._scrollMode,
5122
+ bounceAmount: this._bounceAmount,
5123
+ friction: this._friction,
5124
+ useMouseWheel: this._useMouseWheel,
5125
+ mouseWheelSensitivity: this._mouseWheelSensitivity,
5126
+ horizontalScrollbarVisibility: this._horizontalScrollbarVisibility,
5127
+ verticalScrollbarVisibility: this._verticalScrollbarVisibility
5128
+ };
5129
+ const viewport = getEntity(this._viewport);
5130
+ if (viewport) {
5131
+ data.viewportEntity = viewport;
5132
+ }
5133
+ const content = getEntity(this._content);
5134
+ if (content) {
5135
+ data.contentEntity = content;
5136
+ }
5137
+ const horizontalScrollbar = getEntity(this._horizontalScrollbar);
5138
+ if (horizontalScrollbar) {
5139
+ data.horizontalScrollbarEntity = horizontalScrollbar;
5140
+ }
5141
+ const verticalScrollbar = getEntity(this._verticalScrollbar);
5142
+ if (verticalScrollbar) {
5143
+ data.verticalScrollbarEntity = verticalScrollbar;
5144
+ }
5145
+ return data;
5146
+ }
5147
+ /**
5148
+ * Gets the underlying PlayCanvas scroll view component.
5149
+ * @returns The scroll view component.
5150
+ */
5151
+ get component() {
5152
+ return super.component;
5153
+ }
5154
+ /**
5155
+ * Sets whether horizontal scrolling is enabled.
5156
+ * @param value - Whether horizontal scrolling is enabled.
5157
+ */
5158
+ set horizontal(value) {
5159
+ this._horizontal = value;
5160
+ if (this.component) {
5161
+ this.component.horizontal = value;
5162
+ }
5163
+ }
5164
+ /**
5165
+ * Gets whether horizontal scrolling is enabled.
5166
+ * @returns Whether horizontal scrolling is enabled.
5167
+ */
5168
+ get horizontal() {
5169
+ return this._horizontal;
5170
+ }
5171
+ /**
5172
+ * Sets whether vertical scrolling is enabled.
5173
+ * @param value - Whether vertical scrolling is enabled.
5174
+ */
5175
+ set vertical(value) {
5176
+ this._vertical = value;
5177
+ if (this.component) {
5178
+ this.component.vertical = value;
5179
+ }
5180
+ }
5181
+ /**
5182
+ * Gets whether vertical scrolling is enabled.
5183
+ * @returns Whether vertical scrolling is enabled.
5184
+ */
5185
+ get vertical() {
5186
+ return this._vertical;
5187
+ }
5188
+ /**
5189
+ * Sets how the scroll view should behave when the content is scrolled beyond its bounds. Can be
5190
+ * `clamp` (0), `bounce` (1) or `infinite` (2).
5191
+ * @param value - The scroll mode.
5192
+ */
5193
+ set scrollMode(value) {
5194
+ this._scrollMode = value;
5195
+ if (this.component) {
5196
+ this.component.scrollMode = value;
5197
+ }
5198
+ }
5199
+ /**
5200
+ * Gets how the scroll view behaves when the content is scrolled beyond its bounds.
5201
+ * @returns The scroll mode.
5202
+ */
5203
+ get scrollMode() {
5204
+ return this._scrollMode;
5205
+ }
5206
+ /**
5207
+ * Sets how far the content is allowed to bounce beyond its bounds when `scroll-mode` is
5208
+ * `bounce`, in the range 0 to 1.
5209
+ * @param value - The bounce amount.
5210
+ */
5211
+ set bounceAmount(value) {
5212
+ this._bounceAmount = value;
5213
+ if (this.component) {
5214
+ this.component.bounceAmount = value;
5215
+ }
5216
+ }
5217
+ /**
5218
+ * Gets the bounce amount.
5219
+ * @returns The bounce amount.
5220
+ */
5221
+ get bounceAmount() {
5222
+ return this._bounceAmount;
5223
+ }
5224
+ /**
5225
+ * Sets how freely the content moves once thrown, in the range 0 (no friction) to 1.
5226
+ * @param value - The friction.
5227
+ */
5228
+ set friction(value) {
5229
+ this._friction = value;
5230
+ if (this.component) {
5231
+ this.component.friction = value;
5232
+ }
5233
+ }
5234
+ /**
5235
+ * Gets the friction.
5236
+ * @returns The friction.
5237
+ */
5238
+ get friction() {
5239
+ return this._friction;
5240
+ }
5241
+ /**
5242
+ * Sets whether the scroll view responds to mouse wheel events.
5243
+ * @param value - Whether to use the mouse wheel.
5244
+ */
5245
+ set useMouseWheel(value) {
5246
+ this._useMouseWheel = value;
5247
+ if (this.component) {
5248
+ this.component.useMouseWheel = value;
5249
+ }
5250
+ }
5251
+ /**
5252
+ * Gets whether the scroll view responds to mouse wheel events.
5253
+ * @returns Whether the mouse wheel is used.
5254
+ */
5255
+ get useMouseWheel() {
5256
+ return this._useMouseWheel;
5257
+ }
5258
+ /**
5259
+ * Sets the mouse wheel sensitivity as a Vec2 (horizontal, vertical). A value of 0 on an axis
5260
+ * disables mouse wheel scrolling for that axis.
5261
+ * @param value - The mouse wheel sensitivity.
5262
+ */
5263
+ set mouseWheelSensitivity(value) {
5264
+ this._mouseWheelSensitivity = value;
5265
+ if (this.component) {
5266
+ this.component.mouseWheelSensitivity = value;
5267
+ }
5268
+ }
5269
+ /**
5270
+ * Gets the mouse wheel sensitivity.
5271
+ * @returns The mouse wheel sensitivity.
5272
+ */
5273
+ get mouseWheelSensitivity() {
5274
+ return this._mouseWheelSensitivity;
5275
+ }
5276
+ /**
5277
+ * Sets the visibility of the horizontal scrollbar. Can be `always` (0) or `when-required` (1).
5278
+ * @param value - The horizontal scrollbar visibility.
5279
+ */
5280
+ set horizontalScrollbarVisibility(value) {
5281
+ this._horizontalScrollbarVisibility = value;
5282
+ if (this.component) {
5283
+ this.component.horizontalScrollbarVisibility = value;
5284
+ }
5285
+ }
5286
+ /**
5287
+ * Gets the visibility of the horizontal scrollbar.
5288
+ * @returns The horizontal scrollbar visibility.
5289
+ */
5290
+ get horizontalScrollbarVisibility() {
5291
+ return this._horizontalScrollbarVisibility;
5292
+ }
5293
+ /**
5294
+ * Sets the visibility of the vertical scrollbar. Can be `always` (0) or `when-required` (1).
5295
+ * @param value - The vertical scrollbar visibility.
5296
+ */
5297
+ set verticalScrollbarVisibility(value) {
5298
+ this._verticalScrollbarVisibility = value;
5299
+ if (this.component) {
5300
+ this.component.verticalScrollbarVisibility = value;
5301
+ }
5302
+ }
5303
+ /**
5304
+ * Gets the visibility of the vertical scrollbar.
5305
+ * @returns The vertical scrollbar visibility.
5306
+ */
5307
+ get verticalScrollbarVisibility() {
5308
+ return this._verticalScrollbarVisibility;
5309
+ }
5310
+ /**
5311
+ * Sets the reference (CSS selector, element id or entity name) to the `<pc-entity>` used as the
5312
+ * viewport, which clips the content to the scroll view's bounds.
5313
+ * @param value - The viewport entity reference.
5314
+ */
5315
+ set viewport(value) {
5316
+ this._viewport = value;
5317
+ const entity = getEntity(value);
5318
+ if (this.component && entity) {
5319
+ this.component.viewportEntity = entity;
5320
+ }
5321
+ }
5322
+ /**
5323
+ * Gets the reference to the `<pc-entity>` used as the viewport.
5324
+ * @returns The viewport entity reference.
5325
+ */
5326
+ get viewport() {
5327
+ return this._viewport;
5328
+ }
5329
+ /**
5330
+ * Sets the reference (CSS selector, element id or entity name) to the `<pc-entity>` used as the
5331
+ * content, which is moved as the scroll view is scrolled.
5332
+ * @param value - The content entity reference.
5333
+ */
5334
+ set content(value) {
5335
+ this._content = value;
5336
+ const entity = getEntity(value);
5337
+ if (this.component && entity) {
5338
+ this.component.contentEntity = entity;
5339
+ }
5340
+ }
5341
+ /**
5342
+ * Gets the reference to the `<pc-entity>` used as the content.
5343
+ * @returns The content entity reference.
5344
+ */
5345
+ get content() {
5346
+ return this._content;
5347
+ }
5348
+ /**
5349
+ * Sets the reference (CSS selector, element id or entity name) to the `<pc-entity>` containing
5350
+ * the horizontal `<pc-scrollbar>`.
5351
+ * @param value - The horizontal scrollbar entity reference.
5352
+ */
5353
+ set horizontalScrollbar(value) {
5354
+ this._horizontalScrollbar = value;
5355
+ const entity = getEntity(value);
5356
+ if (this.component && entity) {
5357
+ this.component.horizontalScrollbarEntity = entity;
5358
+ }
5359
+ }
5360
+ /**
5361
+ * Gets the reference to the `<pc-entity>` containing the horizontal scrollbar.
5362
+ * @returns The horizontal scrollbar entity reference.
5363
+ */
5364
+ get horizontalScrollbar() {
5365
+ return this._horizontalScrollbar;
5366
+ }
5367
+ /**
5368
+ * Sets the reference (CSS selector, element id or entity name) to the `<pc-entity>` containing
5369
+ * the vertical `<pc-scrollbar>`.
5370
+ * @param value - The vertical scrollbar entity reference.
5371
+ */
5372
+ set verticalScrollbar(value) {
5373
+ this._verticalScrollbar = value;
5374
+ const entity = getEntity(value);
5375
+ if (this.component && entity) {
5376
+ this.component.verticalScrollbarEntity = entity;
5377
+ }
5378
+ }
5379
+ /**
5380
+ * Gets the reference to the `<pc-entity>` containing the vertical scrollbar.
5381
+ * @returns The vertical scrollbar entity reference.
5382
+ */
5383
+ get verticalScrollbar() {
5384
+ return this._verticalScrollbar;
5385
+ }
5386
+ static get observedAttributes() {
5387
+ return [
5388
+ ...super.observedAttributes,
5389
+ 'horizontal',
5390
+ 'vertical',
5391
+ 'scroll-mode',
5392
+ 'bounce-amount',
5393
+ 'friction',
5394
+ 'use-mouse-wheel',
5395
+ 'mouse-wheel-sensitivity',
5396
+ 'horizontal-scrollbar-visibility',
5397
+ 'vertical-scrollbar-visibility',
5398
+ 'viewport',
5399
+ 'content',
5400
+ 'horizontal-scrollbar',
5401
+ 'vertical-scrollbar'
5402
+ ];
5403
+ }
5404
+ attributeChangedCallback(name, _oldValue, newValue) {
5405
+ super.attributeChangedCallback(name, _oldValue, newValue);
5406
+ switch (name) {
5407
+ case 'horizontal':
5408
+ this.horizontal = newValue !== 'false';
5409
+ break;
5410
+ case 'vertical':
5411
+ this.vertical = newValue !== 'false';
5412
+ break;
5413
+ case 'scroll-mode':
5414
+ this.scrollMode = parseEnum(newValue, scrollModes, SCROLL_MODE_BOUNCE);
5415
+ break;
5416
+ case 'bounce-amount':
5417
+ this.bounceAmount = Number(newValue);
5418
+ break;
5419
+ case 'friction':
5420
+ this.friction = Number(newValue);
5421
+ break;
5422
+ case 'use-mouse-wheel':
5423
+ this.useMouseWheel = newValue !== 'false';
5424
+ break;
5425
+ case 'mouse-wheel-sensitivity':
5426
+ this.mouseWheelSensitivity = parseVec2(newValue);
5427
+ break;
5428
+ case 'horizontal-scrollbar-visibility':
5429
+ this.horizontalScrollbarVisibility = parseEnum(newValue, visibilities, SCROLLBAR_VISIBILITY_SHOW_WHEN_REQUIRED);
5430
+ break;
5431
+ case 'vertical-scrollbar-visibility':
5432
+ this.verticalScrollbarVisibility = parseEnum(newValue, visibilities, SCROLLBAR_VISIBILITY_SHOW_WHEN_REQUIRED);
5433
+ break;
5434
+ case 'viewport':
5435
+ this.viewport = newValue;
5436
+ break;
5437
+ case 'content':
5438
+ this.content = newValue;
5439
+ break;
5440
+ case 'horizontal-scrollbar':
5441
+ this.horizontalScrollbar = newValue;
5442
+ break;
5443
+ case 'vertical-scrollbar':
5444
+ this.verticalScrollbar = newValue;
5445
+ break;
5446
+ }
5447
+ }
5448
+ }
5449
+ customElements.define('pc-scrollview', ScrollViewComponentElement);
5450
+
3611
5451
  /**
3612
5452
  * The ScriptComponentElement interface provides properties and methods for manipulating
3613
5453
  * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-scripts/ | `<pc-scripts>`} elements.
@@ -4363,29 +6203,33 @@ class SoundSlotElement extends AsyncElement {
4363
6203
  customElements.define('pc-sound', SoundSlotElement);
4364
6204
 
4365
6205
  /**
4366
- * The SplatComponentElement interface provides properties and methods for manipulating
4367
- * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-splat/ | `<pc-splat>`} elements.
4368
- * The SplatComponentElement interface also inherits the properties and methods of the
6206
+ * The GSplatComponentElement interface provides properties and methods for manipulating
6207
+ * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-gsplat/ | `<pc-gsplat>`} elements.
6208
+ * The GSplatComponentElement interface also inherits the properties and methods of the
4369
6209
  * {@link HTMLElement} interface.
4370
6210
  *
4371
6211
  * @category Components
4372
6212
  */
4373
- class SplatComponentElement extends ComponentElement {
6213
+ class GSplatComponentElement extends ComponentElement {
4374
6214
  /** @ignore */
4375
6215
  constructor() {
4376
6216
  super('gsplat');
4377
6217
  this._asset = '';
4378
6218
  this._castShadows = false;
6219
+ this._lodBaseDistance = 5;
6220
+ this._lodMultiplier = 3;
4379
6221
  }
4380
6222
  getInitialComponentData() {
4381
6223
  return {
4382
6224
  asset: AssetElement.get(this._asset),
4383
- castShadows: this._castShadows
6225
+ castShadows: this._castShadows,
6226
+ lodBaseDistance: this._lodBaseDistance,
6227
+ lodMultiplier: this._lodMultiplier
4384
6228
  };
4385
6229
  }
4386
6230
  /**
4387
- * Gets the underlying PlayCanvas splat component.
4388
- * @returns The splat component.
6231
+ * Gets the underlying PlayCanvas gsplat component.
6232
+ * @returns The gsplat component.
4389
6233
  */
4390
6234
  get component() {
4391
6235
  return super.component;
@@ -4425,11 +6269,54 @@ class SplatComponentElement extends ComponentElement {
4425
6269
  get castShadows() {
4426
6270
  return this._castShadows;
4427
6271
  }
6272
+ /**
6273
+ * Sets the base distance for the first LOD transition (LOD 0 to LOD 1). Splats closer than
6274
+ * this distance use the highest quality LOD. Each subsequent LOD level transitions at a
6275
+ * progressively larger distance, controlled by {@link lodMultiplier}. Clamped to a minimum of
6276
+ * 0.1. Defaults to 5. Only affects assets that contain LOD levels (e.g. `.lod-meta.json`).
6277
+ * @param value - The LOD base distance.
6278
+ */
6279
+ set lodBaseDistance(value) {
6280
+ this._lodBaseDistance = value;
6281
+ if (this.component) {
6282
+ this.component.lodBaseDistance = value;
6283
+ }
6284
+ }
6285
+ /**
6286
+ * Gets the base distance for the first LOD transition.
6287
+ * @returns The LOD base distance.
6288
+ */
6289
+ get lodBaseDistance() {
6290
+ return this._lodBaseDistance;
6291
+ }
6292
+ /**
6293
+ * Sets the multiplier between successive LOD distance thresholds. Each LOD level transitions
6294
+ * at this factor times the previous level's distance, creating a geometric progression. Lower
6295
+ * values keep higher quality at distance; higher values switch to coarser LODs sooner. Clamped
6296
+ * to a minimum of 1.2. Defaults to 3. Only affects assets that contain LOD levels (e.g.
6297
+ * `.lod-meta.json`).
6298
+ * @param value - The LOD multiplier.
6299
+ */
6300
+ set lodMultiplier(value) {
6301
+ this._lodMultiplier = value;
6302
+ if (this.component) {
6303
+ this.component.lodMultiplier = value;
6304
+ }
6305
+ }
6306
+ /**
6307
+ * Gets the multiplier between successive LOD distance thresholds.
6308
+ * @returns The LOD multiplier.
6309
+ */
6310
+ get lodMultiplier() {
6311
+ return this._lodMultiplier;
6312
+ }
4428
6313
  static get observedAttributes() {
4429
6314
  return [
4430
6315
  ...super.observedAttributes,
4431
6316
  'asset',
4432
- 'cast-shadows'
6317
+ 'cast-shadows',
6318
+ 'lod-base-distance',
6319
+ 'lod-multiplier'
4433
6320
  ];
4434
6321
  }
4435
6322
  attributeChangedCallback(name, _oldValue, newValue) {
@@ -4441,10 +6328,16 @@ class SplatComponentElement extends ComponentElement {
4441
6328
  case 'cast-shadows':
4442
6329
  this.castShadows = this.hasAttribute('cast-shadows');
4443
6330
  break;
6331
+ case 'lod-base-distance':
6332
+ this.lodBaseDistance = Number(newValue);
6333
+ break;
6334
+ case 'lod-multiplier':
6335
+ this.lodMultiplier = Number(newValue);
6336
+ break;
4444
6337
  }
4445
6338
  }
4446
6339
  }
4447
- customElements.define('pc-splat', SplatComponentElement);
6340
+ customElements.define('pc-gsplat', GSplatComponentElement);
4448
6341
 
4449
6342
  /**
4450
6343
  * The ModelElement interface provides properties and methods for manipulating
@@ -4982,5 +6875,5 @@ class SkyElement extends AsyncElement {
4982
6875
  }
4983
6876
  customElements.define('pc-sky', SkyElement);
4984
6877
 
4985
- export { AppElement, AssetElement, AsyncElement, CameraComponentElement, CollisionComponentElement, ComponentElement, ElementComponentElement, EntityElement, LightComponentElement, ListenerComponentElement, MaterialElement, ModelElement, ModuleElement, ParticleSystemComponentElement, RenderComponentElement, RigidBodyComponentElement, SceneElement, ScreenComponentElement, ScriptComponentElement, ScriptElement, SkyElement, SoundComponentElement, SoundSlotElement, SplatComponentElement };
6878
+ export { AppElement, AssetElement, AsyncElement, ButtonComponentElement, CameraComponentElement, CollisionComponentElement, ComponentElement, ElementComponentElement, EntityElement, GSplatComponentElement, LayoutChildComponentElement, LayoutGroupComponentElement, LightComponentElement, ListenerComponentElement, MaterialElement, ModelElement, ModuleElement, ParticleSystemComponentElement, RenderComponentElement, RigidBodyComponentElement, SceneElement, ScreenComponentElement, ScriptComponentElement, ScriptElement, ScrollViewComponentElement, ScrollbarComponentElement, SkyElement, SoundComponentElement, SoundSlotElement };
4986
6879
  //# sourceMappingURL=pwc.mjs.map