@babylonjs/inspector 8.30.1-preview → 8.30.2-preview

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/lib/index.d.ts CHANGED
@@ -406,9 +406,7 @@ declare function ExtensibleAccordion<ContextT = unknown>(props: PropsWithChildre
406
406
  /**
407
407
  * Used to apply common styles to panes.
408
408
  */
409
- declare const Pane$1: react.ForwardRefExoticComponent<{
410
- children?: react.ReactNode | undefined;
411
- } & react.RefAttributes<HTMLDivElement>>;
409
+ declare const SidePaneContainer: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
412
410
 
413
411
  /**
414
412
  * Creates a hook for managing teaching moment state.
@@ -20352,7 +20350,9 @@ declare enum NodeParticleContextualSources {
20352
20350
  /** Initial Color */
20353
20351
  InitialColor = 19,
20354
20352
  /** Color Dead*/
20355
- ColorDead = 20
20353
+ ColorDead = 20,
20354
+ /** Initial Direction */
20355
+ InitialDirection = 21
20356
20356
  }
20357
20357
 
20358
20358
  /**
@@ -20366,7 +20366,9 @@ declare enum NodeParticleSystemSources {
20366
20366
  /** Delta time */
20367
20367
  Delta = 2,
20368
20368
  /** Emitter */
20369
- Emitter = 3
20369
+ Emitter = 3,
20370
+ /** Camera position */
20371
+ CameraPosition = 4
20370
20372
  }
20371
20373
 
20372
20374
  /**
@@ -20423,7 +20425,7 @@ declare class NodeParticleBuildState {
20423
20425
  * @param source Source of the contextual value
20424
20426
  * @returns the value associated with the source
20425
20427
  */
20426
- getContextualValue(source: NodeParticleContextualSources): number | Vector3 | Color4 | Vector2 | null;
20428
+ getContextualValue(source: NodeParticleContextualSources): number | Color4 | Nullable<Vector3> | Vector2;
20427
20429
  /**
20428
20430
  * Gets a boolean indicating if the emitter is a transform node (or a simple vector3)
20429
20431
  */
@@ -68826,5 +68828,5 @@ declare const Vector2PropertyLine: FunctionComponent<TensorPropertyLineProps<Vec
68826
68828
  declare const Vector3PropertyLine: FunctionComponent<TensorPropertyLineProps<Vector3>>;
68827
68829
  declare const Vector4PropertyLine: FunctionComponent<TensorPropertyLineProps<Vector4>>;
68828
68830
 
68829
- export { Accordion, AccordionSection, BooleanBadgePropertyLine, BoundProperty, BuiltInsExtensionFeed, Button, ButtonLine, CalculatePrecision, Checkbox, CheckboxPropertyLine, Collapse, Color3GradientComponent, Color3GradientList, Color3PropertyLine, Color4GradientComponent, Color4GradientList, Color4PropertyLine, ColorPickerPopup, ColorStepGradientComponent, ComboBox, ConstructorFactory, DebugServiceIdentity, DraggableLine, Dropdown, ExtensibleAccordion, FactorGradientComponent, FactorGradientList, FileUploadLine, GetPropertyDescriptor, HexPropertyLine, HideInspector, InfoLabel, InputHexField, InputHsvField, Inspector, InterceptFunction, InterceptProperty, IsInspectorVisible, IsPropertyReadonly, LineContainer, LinkPropertyLine, LinkToEntityPropertyLine, List, MakeDialogTeachingMoment, MakeLazyComponent, MakePopoverTeachingMoment, MakePropertyHook, MakeTeachingMoment, MessageBar, NumberDropdown, NumberDropdownPropertyLine, NumberInputPropertyLine, ObservableCollection, Pane, Pane$1 as PaneContainer, PlaceholderPropertyLine, PositionedPopover, PropertiesServiceIdentity, PropertyLine, QuaternionPropertyLine, RotationVectorPropertyLine, SceneContextIdentity, SceneExplorerServiceIdentity, SearchBar, SearchBox, SelectionServiceDefinition, SelectionServiceIdentity, SettingsContextIdentity, SettingsServiceIdentity, ShellServiceIdentity, ShowInspector, SpinButton, SpinButtonPropertyLine, StatsServiceIdentity, StringDropdown, StringDropdownPropertyLine, StringifiedPropertyLine, Switch, SwitchPropertyLine, SyncedSliderInput, SyncedSliderPropertyLine, TeachingMoment, TextAreaPropertyLine, TextInput, TextInputPropertyLine, TextPropertyLine, Textarea, ToggleButton, ToolsServiceIdentity, Vector2PropertyLine, Vector3PropertyLine, Vector4PropertyLine, useAngleConverters, useAsyncResource, useColor3Property, useColor4Property, useEventfulState, useInterceptObservable, useObservableCollection, useObservableState, useOrderedObservableCollection, usePollingObservable, useProperty, useQuaternionProperty, useResource, useVector3Property };
68831
+ export { Accordion, AccordionSection, BooleanBadgePropertyLine, BoundProperty, BuiltInsExtensionFeed, Button, ButtonLine, CalculatePrecision, Checkbox, CheckboxPropertyLine, Collapse, Color3GradientComponent, Color3GradientList, Color3PropertyLine, Color4GradientComponent, Color4GradientList, Color4PropertyLine, ColorPickerPopup, ColorStepGradientComponent, ComboBox, ConstructorFactory, DebugServiceIdentity, DraggableLine, Dropdown, ExtensibleAccordion, FactorGradientComponent, FactorGradientList, FileUploadLine, GetPropertyDescriptor, HexPropertyLine, HideInspector, InfoLabel, InputHexField, InputHsvField, Inspector, InterceptFunction, InterceptProperty, IsInspectorVisible, IsPropertyReadonly, LineContainer, LinkPropertyLine, LinkToEntityPropertyLine, List, MakeDialogTeachingMoment, MakeLazyComponent, MakePopoverTeachingMoment, MakePropertyHook, MakeTeachingMoment, MessageBar, NumberDropdown, NumberDropdownPropertyLine, NumberInputPropertyLine, ObservableCollection, Pane, PlaceholderPropertyLine, PositionedPopover, PropertiesServiceIdentity, PropertyLine, QuaternionPropertyLine, RotationVectorPropertyLine, SceneContextIdentity, SceneExplorerServiceIdentity, SearchBar, SearchBox, SelectionServiceDefinition, SelectionServiceIdentity, SettingsContextIdentity, SettingsServiceIdentity, ShellServiceIdentity, ShowInspector, SidePaneContainer, SpinButton, SpinButtonPropertyLine, StatsServiceIdentity, StringDropdown, StringDropdownPropertyLine, StringifiedPropertyLine, Switch, SwitchPropertyLine, SyncedSliderInput, SyncedSliderPropertyLine, TeachingMoment, TextAreaPropertyLine, TextInput, TextInputPropertyLine, TextPropertyLine, Textarea, ToggleButton, ToolsServiceIdentity, Vector2PropertyLine, Vector3PropertyLine, Vector4PropertyLine, useAngleConverters, useAsyncResource, useColor3Property, useColor4Property, useEventfulState, useInterceptObservable, useObservableCollection, useObservableState, useOrderedObservableCollection, usePollingObservable, useProperty, useQuaternionProperty, useResource, useVector3Property };
68830
68832
  export type { AcceptedDropdownValue, AccordionSectionProps, BasePrimitiveProps, BoundPropertyProps, BuiltInExtension, ButtonProps, CentralContent, ColorPickerProps, ColorPropertyLineProps, ComboBoxProps, DraggableLineProps, DropdownOption, DropdownProps, DynamicAccordionSection, DynamicAccordionSectionContent, EntityBase, EntityDisplayInfo, ExtensionMetadata, ExtensionModule, FunctionHooks, IDebugService, IExtensionFeed, IExtensionMetadataQuery, IPropertiesService, ISceneContext, ISceneExplorerService, ISelectionService, IService, ISettingsContext, ISettingsService, IShellService, IStatsService, IToolsService, ImmutablePrimitiveProps, InfoLabelParentProps, InfoLabelProps, InputHexProps, ListItem, PaneProps, PrimitiveProps, PropertyHooks, PropertyLineProps, SceneExplorerCommand, SceneExplorerCommandProvider, SceneExplorerSection, ServiceDefinition, ServiceFactory, SidePane, SpinButtonProps, SwitchProps, SyncedSliderProps, TensorPropertyLineProps, TextInputProps, TextareaProps, ToolbarItem };
package/lib/index.js CHANGED
@@ -3,7 +3,7 @@ import { useMemo, useEffect, useState, useRef, useCallback, forwardRef, createCo
3
3
  import { Color3, Color4 } from '@babylonjs/core/Maths/math.color.js';
4
4
  import { Vector3, Quaternion, Matrix, Vector2, Vector4, TmpVectors } from '@babylonjs/core/Maths/math.vector.js';
5
5
  import { Observable } from '@babylonjs/core/Misc/observable.js';
6
- import { makeStyles, ToggleButton as ToggleButton$1, Button as Button$1, tokens, Link, InfoLabel as InfoLabel$1, Body1Stronger, Checkbox as Checkbox$1, Body1, Accordion as Accordion$1, AccordionItem, AccordionHeader, Subtitle2Stronger, AccordionPanel, Divider, TeachingPopover, TeachingPopoverSurface, TeachingPopoverHeader, TeachingPopoverBody, Body1Strong, TabList, Tooltip, Title3, Tab, SearchBox as SearchBox$1, FlatTree, FlatTreeItem, TreeItemLayout, Menu, MenuTrigger, MenuPopover, MenuList, MenuItem, Switch as Switch$1, PresenceBadge, Spinner, Dialog, DialogTrigger, DialogSurface, DialogBody, DialogTitle, DialogContent, SplitButton, MenuItemRadio, createLightTheme, createDarkTheme, FluentProvider, DialogActions, List as List$1, ListItem, useId, SpinButton as SpinButton$1, Slider, Input, MessageBar as MessageBar$1, MessageBarBody, MessageBarTitle, Badge, Popover, PopoverTrigger, ColorSwatch, PopoverSurface, ColorPicker, ColorArea, ColorSlider, AlphaSlider, Dropdown as Dropdown$1, Option, Textarea as Textarea$1, useComboboxFilter, Combobox, Field } from '@fluentui/react-components';
6
+ import { makeStyles, ToggleButton as ToggleButton$1, Button as Button$1, tokens, Link, InfoLabel as InfoLabel$1, Body1Stronger, Checkbox as Checkbox$1, Body1, Accordion as Accordion$1, AccordionItem, AccordionHeader, Subtitle2Stronger, AccordionPanel, Divider, mergeClasses, TeachingPopover, TeachingPopoverSurface, TeachingPopoverHeader, TeachingPopoverBody, Body1Strong, TabList, Tooltip, Title3, Tab, SearchBox as SearchBox$1, FlatTree, FlatTreeItem, TreeItemLayout, Menu, MenuTrigger, MenuPopover, MenuList, MenuItem, Switch as Switch$1, PresenceBadge, Spinner, Dialog, DialogTrigger, DialogSurface, DialogBody, DialogTitle, DialogContent, SplitButton, MenuItemRadio, createLightTheme, createDarkTheme, FluentProvider, DialogActions, List as List$1, ListItem, useId, Input, SpinButton as SpinButton$1, Slider, MessageBar as MessageBar$1, MessageBarBody, MessageBarTitle, Badge, Popover, PopoverTrigger, ColorSwatch, PopoverSurface, ColorPicker, ColorArea, ColorSlider, AlphaSlider, Dropdown as Dropdown$1, Option, Textarea as Textarea$1, useComboboxFilter, Combobox, Field } from '@fluentui/react-components';
7
7
  export { Link } from '@fluentui/react-components';
8
8
  import { ChevronCircleRight20Regular, ChevronCircleDown20Regular, CopyRegular, PanelLeftExpandRegular, PanelLeftContractRegular, PanelRightExpandRegular, PanelRightContractRegular, DocumentTextRegular, FilterRegular, MoviesAndTvRegular, CubeTreeRegular, BugRegular, SettingsRegular, ArrowUploadRegular, DataBarHorizontalRegular, WrenchRegular, AppsAddInRegular, DismissRegular, WeatherSunnyRegular, WeatherMoonRegular, ErrorCircleRegular, ArrowMoveRegular, ArrowRotateClockwiseRegular, ArrowExpandRegular, SelectObjectRegular, CubeRegular, GlobeRegular, SaveRegular, ArrowUndoRegular, ClearFormattingRegular, DeleteRegular, EyeOffFilled, EyeFilled, ArrowMoveFilled, StopFilled, PlayFilled, StackRegular, FilmstripRegular, PauseFilled, WeatherSunnyLowFilled, LayerRegular, FrameRegular, PlayRegular, AppGenericRegular, PaintBrushRegular, BoxRegular, BranchRegular, CameraRegular, LightbulbRegular, EyeRegular, EyeOffRegular, VideoFilled, VideoRegular, FlashlightRegular, FlashlightOffRegular, Cone16Filled, Cone16Regular, DropRegular, BlurRegular, PipelineRegular, PersonWalkingRegular, DataLineRegular, PersonSquareRegular, LayerDiagonalPersonRegular, ImageEditRegular, ImageRegular, TargetRegular, DeleteFilled } from '@fluentui/react-icons';
9
9
  import { Collapse as Collapse$1 } from '@fluentui/react-motion-components-preview';
@@ -793,7 +793,7 @@ const LinkToEntityPropertyLine = (props) => {
793
793
  !linkedEntity.reservedDataStore?.hidden && jsx(LinkPropertyLine, { ...rest, value: linkedEntity.name, onLink: () => (selectionService.selectedEntity = linkedEntity) }));
794
794
  };
795
795
 
796
- const useStyles$e = makeStyles({
796
+ const useStyles$f = makeStyles({
797
797
  accordion: {
798
798
  overflowX: "hidden",
799
799
  overflowY: "auto",
@@ -813,11 +813,11 @@ const useStyles$e = makeStyles({
813
813
  },
814
814
  });
815
815
  const AccordionSection = (props) => {
816
- const classes = useStyles$e();
816
+ const classes = useStyles$f();
817
817
  return jsx("div", { className: classes.panelDiv, children: props.children });
818
818
  };
819
819
  const Accordion = (props) => {
820
- const classes = useStyles$e();
820
+ const classes = useStyles$f();
821
821
  const { children, ...rest } = props;
822
822
  const validChildren = useMemo(() => {
823
823
  return (Children.map(children, (child) => {
@@ -867,7 +867,7 @@ function AsReadonlyArray(array) {
867
867
  return array;
868
868
  }
869
869
  // eslint-disable-next-line @typescript-eslint/naming-convention
870
- const useStyles$d = makeStyles({
870
+ const useStyles$e = makeStyles({
871
871
  rootDiv: {
872
872
  flex: 1,
873
873
  overflow: "hidden",
@@ -876,7 +876,7 @@ const useStyles$d = makeStyles({
876
876
  },
877
877
  });
878
878
  function ExtensibleAccordion(props) {
879
- const classes = useStyles$d();
879
+ const classes = useStyles$e();
880
880
  const { children, sections, sectionContent, context } = props;
881
881
  const defaultSections = useMemo(() => {
882
882
  const defaultSections = [];
@@ -964,21 +964,25 @@ function ExtensibleAccordion(props) {
964
964
  })] })) }));
965
965
  }
966
966
 
967
- const useStyles$c = makeStyles({
967
+ const useStyles$d = makeStyles({
968
968
  paneRootDiv: {
969
- padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalM}`,
969
+ display: "flex",
970
+ flex: 1,
971
+ flexDirection: "column",
972
+ padding: `0 ${tokens.spacingHorizontalM}`,
970
973
  },
971
974
  });
972
975
  /**
973
976
  * Used to apply common styles to panes.
974
977
  */
975
- const Pane$1 = forwardRef((props, ref) => {
976
- const classes = useStyles$c();
977
- return (jsx("div", { className: classes.paneRootDiv, ref: ref, children: props.children }));
978
+ const SidePaneContainer = forwardRef((props, ref) => {
979
+ const { className, ...rest } = props;
980
+ const classes = useStyles$d();
981
+ return (jsx("div", { className: mergeClasses(classes.paneRootDiv, className), ref: ref, ...rest, children: props.children }));
978
982
  });
979
983
 
980
984
  // eslint-disable-next-line @typescript-eslint/naming-convention
981
- const useStyles$b = makeStyles({
985
+ const useStyles$c = makeStyles({
982
986
  extensionTeachingPopover: {
983
987
  maxWidth: "320px",
984
988
  },
@@ -989,7 +993,7 @@ const useStyles$b = makeStyles({
989
993
  * @returns The teaching moment popover.
990
994
  */
991
995
  const TeachingMoment = ({ shouldDisplay, positioningRef, onOpenChange, title, description }) => {
992
- const classes = useStyles$b();
996
+ const classes = useStyles$c();
993
997
  return (jsx(TeachingPopover, { appearance: "brand", open: shouldDisplay, positioning: { positioningRef }, onOpenChange: onOpenChange, children: jsxs(TeachingPopoverSurface, { className: classes.extensionTeachingPopover, children: [jsx(TeachingPopoverHeader, { children: title }), jsx(TeachingPopoverBody, { children: description })] }) }));
994
998
  };
995
999
 
@@ -1276,13 +1280,13 @@ function ConstructorFactory(constructor) {
1276
1280
  }
1277
1281
 
1278
1282
  // eslint-disable-next-line @typescript-eslint/naming-convention
1279
- const useStyles$a = makeStyles({
1283
+ const useStyles$b = makeStyles({
1280
1284
  placeholderDiv: {
1281
1285
  padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalM}`,
1282
1286
  },
1283
1287
  });
1284
1288
  const PropertiesPane = (props) => {
1285
- const classes = useStyles$a();
1289
+ const classes = useStyles$b();
1286
1290
  const entity = props.context;
1287
1291
  return entity != null ? (jsx(ExtensibleAccordion, { ...props })) : (jsx("div", { className: classes.placeholderDiv, children: jsx(Body1Strong, { italic: true, children: "No entity selected." }) }));
1288
1292
  };
@@ -1325,7 +1329,7 @@ const SelectionServiceDefinition = {
1325
1329
  const RootComponentServiceIdentity = Symbol("RootComponent");
1326
1330
  const ShellServiceIdentity = Symbol("ShellService");
1327
1331
  // eslint-disable-next-line @typescript-eslint/naming-convention
1328
- const useStyles$9 = makeStyles({
1332
+ const useStyles$a = makeStyles({
1329
1333
  mainView: {
1330
1334
  flex: 1,
1331
1335
  display: "flex",
@@ -1448,7 +1452,7 @@ const useStyles$9 = makeStyles({
1448
1452
  });
1449
1453
  // This is a wrapper for an item in a toolbar that simply adds a teaching moment, which is useful for dynamically added items, possibly from extensions.
1450
1454
  const ToolbarItem = ({ location, alignment, id, component: Component, displayName: displayName, suppressTeachingMoment }) => {
1451
- const classes = useStyles$9();
1455
+ const classes = useStyles$a();
1452
1456
  const useTeachingMoment = useMemo(() => MakePopoverTeachingMoment(`Bar/${location}/${alignment}/${displayName ?? id}`), [displayName, id]);
1453
1457
  const teachingMoment = useTeachingMoment(suppressTeachingMoment);
1454
1458
  return (jsxs(Fragment, { children: [jsx(TeachingMoment, { ...teachingMoment, shouldDisplay: teachingMoment.shouldDisplay && !suppressTeachingMoment, title: displayName ?? "Extension", description: `The "${displayName ?? id}" extension can be accessed here.` }), jsx("div", { className: classes.barItem, ref: teachingMoment.targetRef, children: jsx(Component, {}) })] }));
@@ -1456,7 +1460,7 @@ const ToolbarItem = ({ location, alignment, id, component: Component, displayNam
1456
1460
  // TODO: Handle overflow, possibly via https://react.fluentui.dev/?path=/docs/components-overflow--docs with priority.
1457
1461
  // This component just renders a toolbar with left aligned toolbar items on the left and right aligned toolbar items on the right.
1458
1462
  const Toolbar = ({ location, components }) => {
1459
- const classes = useStyles$9();
1463
+ const classes = useStyles$a();
1460
1464
  const leftComponents = useMemo(() => components.filter((entry) => entry.horizontalLocation === "left"), [components]);
1461
1465
  const rightComponents = useMemo(() => components.filter((entry) => entry.horizontalLocation === "right"), [components]);
1462
1466
  return (jsx(Fragment, { children: components.length > 0 && (jsxs("div", { className: `${classes.bar} ${location === "top" ? classes.barTop : classes.barBottom}`, children: [jsx("div", { className: classes.barLeft, children: leftComponents.map((entry) => (jsx(ToolbarItem, { location: location, alignment: entry.horizontalLocation, id: entry.key, component: entry.component, displayName: entry.displayName, suppressTeachingMoment: entry.suppressTeachingMoment }, entry.key))) }), jsx("div", { className: classes.barRight, children: rightComponents.map((entry) => (jsx(ToolbarItem, { location: location, alignment: entry.horizontalLocation, id: entry.key, component: entry.component, displayName: entry.displayName, suppressTeachingMoment: entry.suppressTeachingMoment }, entry.key))) })] })) }));
@@ -1465,7 +1469,7 @@ const Toolbar = ({ location, components }) => {
1465
1469
  const SidePaneTab = ({ alignment, id,
1466
1470
  // eslint-disable-next-line @typescript-eslint/naming-convention
1467
1471
  icon: Icon, title, suppressTeachingMoment, }) => {
1468
- const classes = useStyles$9();
1472
+ const classes = useStyles$a();
1469
1473
  const useTeachingMoment = useMemo(() => MakePopoverTeachingMoment(`Pane/${alignment}/${title ?? id}`), [title, id]);
1470
1474
  const teachingMoment = useTeachingMoment(suppressTeachingMoment);
1471
1475
  return (jsxs(Fragment, { children: [jsx(TeachingMoment, { ...teachingMoment, shouldDisplay: teachingMoment.shouldDisplay && !suppressTeachingMoment, title: title ?? "Extension", description: `The "${title ?? id}" extension can be accessed here.` }), jsx(Tab, { ref: teachingMoment.targetRef, className: classes.tab, value: id, icon: jsx(Tooltip, { content: title ?? id, relationship: "description", children: jsx(Icon, {}) }) }, id)] }));
@@ -1473,8 +1477,8 @@ icon: Icon, title, suppressTeachingMoment, }) => {
1473
1477
  // This hook provides a side pane container and the tab list.
1474
1478
  // In "compact" mode, the tab list is integrated into the pane itself.
1475
1479
  // In "full" mode, the returned tab list is later injected into the toolbar.
1476
- function usePane(alignment, defaultWidth, minWidth, topPaneComponents, bottomPaneComponents, toolbarMode, topBarComponents, bottomBarComponents) {
1477
- const classes = useStyles$9();
1480
+ function usePane(alignment, defaultWidth, minWidth, topPanes, bottomPanes, toolbarMode, topBarItems, bottomBarItems) {
1481
+ const classes = useStyles$a();
1478
1482
  const [topSelectedTab, setTopSelectedTab] = useState();
1479
1483
  const [bottomSelectedTab, setBottomSelectedTab] = useState();
1480
1484
  const [collapsed, setCollapsed] = useState(false);
@@ -1486,21 +1490,21 @@ function usePane(alignment, defaultWidth, minWidth, topPaneComponents, bottomPan
1486
1490
  const [width, setWidth] = useState(Number.parseInt(localStorage.getItem(widthStorageKey) ?? "") || Math.max(defaultWidth, minWidth));
1487
1491
  const [resizing, setResizing] = useState(false);
1488
1492
  useEffect(() => {
1489
- if ((topSelectedTab && !topPaneComponents.includes(topSelectedTab)) || (!topSelectedTab && topPaneComponents.length > 0)) {
1490
- setTopSelectedTab(topPaneComponents[0]);
1493
+ if ((topSelectedTab && !topPanes.includes(topSelectedTab)) || (!topSelectedTab && topPanes.length > 0)) {
1494
+ setTopSelectedTab(topPanes[0]);
1491
1495
  }
1492
- else if (topSelectedTab && topPaneComponents.length === 0) {
1496
+ else if (topSelectedTab && topPanes.length === 0) {
1493
1497
  setTopSelectedTab(undefined);
1494
1498
  }
1495
- }, [topSelectedTab, topPaneComponents]);
1499
+ }, [topSelectedTab, topPanes]);
1496
1500
  useEffect(() => {
1497
- if ((bottomSelectedTab && !bottomPaneComponents.includes(bottomSelectedTab)) || (!bottomSelectedTab && bottomPaneComponents.length > 0)) {
1498
- setBottomSelectedTab(bottomPaneComponents[0]);
1501
+ if ((bottomSelectedTab && !bottomPanes.includes(bottomSelectedTab)) || (!bottomSelectedTab && bottomPanes.length > 0)) {
1502
+ setBottomSelectedTab(bottomPanes[0]);
1499
1503
  }
1500
- else if (bottomSelectedTab && bottomPaneComponents.length === 0) {
1504
+ else if (bottomSelectedTab && bottomPanes.length === 0) {
1501
1505
  setBottomSelectedTab(undefined);
1502
1506
  }
1503
- }, [bottomSelectedTab, bottomPaneComponents]);
1507
+ }, [bottomSelectedTab, bottomPanes]);
1504
1508
  const expandCollapseIcon = useMemo(() => {
1505
1509
  if (alignment === "left") {
1506
1510
  return collapsed ? jsx(PanelLeftExpandRegular, {}) : jsx(PanelLeftContractRegular, {});
@@ -1546,8 +1550,8 @@ function usePane(alignment, defaultWidth, minWidth, topPaneComponents, bottomPan
1546
1550
  }, children: paneComponents.map((entry) => (jsx(SidePaneTab, { alignment: alignment, id: entry.key, title: entry.title, icon: entry.icon, suppressTeachingMoment: entry.suppressTeachingMoment }, entry.key))) }) })), toolbarMode === "full" && (jsxs(Fragment, { children: [jsx(Divider, { vertical: true, inset: true }), jsx(Tooltip, { content: collapsed ? "Show Side Pane" : "Hide Side Pane", relationship: "label", children: jsx(Button$1, { className: classes.paneCollapseButton, appearance: "subtle", icon: expandCollapseIcon, onClick: onExpandCollapseClick }) })] }))] })) }));
1547
1551
  }, [alignment, collapsed]);
1548
1552
  // This memos the TabList to make it easy for the JSX to be inserted at the top of the pane (in "compact" mode) or returned to the caller to be used in the toolbar (in "full" mode).
1549
- const topPaneTabList = useMemo(() => createPaneTabList(topPaneComponents, toolbarMode, topSelectedTab, setTopSelectedTab), [topPaneComponents, toolbarMode, topSelectedTab]);
1550
- const bottomPaneTabList = useMemo(() => createPaneTabList(bottomPaneComponents, "compact", bottomSelectedTab, setBottomSelectedTab), [bottomPaneComponents, bottomSelectedTab]);
1553
+ const topPaneTabList = useMemo(() => createPaneTabList(topPanes, toolbarMode, topSelectedTab, setTopSelectedTab), [topPanes, toolbarMode, topSelectedTab]);
1554
+ const bottomPaneTabList = useMemo(() => createPaneTabList(bottomPanes, "compact", bottomSelectedTab, setBottomSelectedTab), [bottomPanes, bottomSelectedTab]);
1551
1555
  // This manages the CSS variable that controls the height of the bottom pane.
1552
1556
  const paneHeightAdjustCSSVar = "--pane-height-adjust";
1553
1557
  const { elementRef: paneVerticalResizeElementRef, handleRef: paneVerticalResizeHandleRef, setValue: setPaneHeightAdjust, } = useResizeHandle({
@@ -1569,8 +1573,8 @@ function usePane(alignment, defaultWidth, minWidth, topPaneComponents, bottomPan
1569
1573
  });
1570
1574
  // This memoizes the pane itself, which may or may not include the tab list, depending on the toolbar mode.
1571
1575
  const pane = useMemo(() => {
1572
- return (jsx(Fragment, { children: (topPaneComponents.length > 0 || bottomPaneComponents.length > 0) && (jsxs("div", { className: `${classes.pane} ${alignment === "left" ? classes.paneLeft : classes.paneRight}`, children: [jsx(Collapse, { orientation: "horizontal", visible: !collapsed, children: jsxs("div", { className: classes.paneContainer, style: { width: `${width}px` }, children: [toolbarMode === "compact" && (topPaneComponents.length > 1 || topBarComponents.length > 0) && (jsx(Fragment, { children: jsxs("div", { className: classes.barDiv, children: [topPaneTabList, jsx(Toolbar, { location: "top", components: topBarComponents })] }) })), jsxs("div", { className: classes.paneContent, children: [topSelectedTab?.title ? (jsxs(Fragment, { children: [jsx(Title3, { className: classes.paneHeader, children: topSelectedTab.title }), jsx(Divider, { inset: true, className: classes.headerDivider, appearance: "brand" })] })) : null, topSelectedTab?.content && jsx(topSelectedTab.content, {})] }), topPaneComponents.length > 0 && bottomPaneComponents.length > 0 && (jsx(Divider, { ref: paneVerticalResizeHandleRef, className: classes.headerDivider, style: { margin: "0", minHeight: tokens.spacingVerticalM, cursor: "ns-resize" } })), bottomPaneComponents.length > 1 && (jsx(Fragment, { children: jsx("div", { className: classes.barDiv, children: bottomPaneTabList }) })), bottomPaneComponents.length > 0 && (jsxs("div", { ref: paneVerticalResizeElementRef, className: classes.paneContent, style: { height: `clamp(200px,calc(45% + var(${paneHeightAdjustCSSVar}, 0px)), 100% - 300px)`, flex: "0 0 auto" }, children: [bottomSelectedTab?.title ? (jsxs(Fragment, { children: [jsx(Title3, { className: classes.paneHeader, children: bottomSelectedTab.title }), jsx(Divider, { inset: true, className: classes.headerDivider, appearance: "brand" })] })) : null, bottomSelectedTab?.content && jsx(bottomSelectedTab.content, {})] })), toolbarMode === "compact" && bottomBarComponents.length > 0 && (jsx(Fragment, { children: jsx("div", { className: classes.barDiv, children: jsx(Toolbar, { location: "bottom", components: bottomBarComponents }) }) }))] }) }), jsx("div", { className: `${classes.resizer} ${alignment === "left" ? classes.resizerLeft : classes.resizerRight}`, style: { pointerEvents: `${collapsed ? "none" : "auto"}` }, onPointerDown: onResizerPointerDown })] })) }));
1573
- }, [topPaneComponents, topSelectedTab, bottomPaneComponents, bottomSelectedTab, collapsed, width, resizing]);
1576
+ return (jsx(Fragment, { children: (topPanes.length > 0 || bottomPanes.length > 0) && (jsxs("div", { className: `${classes.pane} ${alignment === "left" ? classes.paneLeft : classes.paneRight}`, children: [jsx(Collapse, { orientation: "horizontal", visible: !collapsed, children: jsxs("div", { className: classes.paneContainer, style: { width: `${width}px` }, children: [toolbarMode === "compact" && (topPanes.length > 1 || topBarItems.length > 0) && (jsx(Fragment, { children: jsxs("div", { className: classes.barDiv, children: [topPaneTabList, jsx(Toolbar, { location: "top", components: topBarItems })] }) })), jsxs("div", { className: classes.paneContent, children: [topSelectedTab?.title ? (jsxs(Fragment, { children: [jsx(Title3, { className: classes.paneHeader, children: topSelectedTab.title }), jsx(Divider, { inset: true, className: classes.headerDivider, appearance: "brand" })] })) : null, topSelectedTab?.content && jsx(topSelectedTab.content, {})] }), topPanes.length > 0 && bottomPanes.length > 0 && (jsx(Divider, { ref: paneVerticalResizeHandleRef, className: classes.headerDivider, style: { margin: "0", minHeight: tokens.spacingVerticalM, cursor: "ns-resize" } })), bottomPanes.length > 1 && (jsx(Fragment, { children: jsx("div", { className: classes.barDiv, children: bottomPaneTabList }) })), bottomPanes.length > 0 && (jsxs("div", { ref: paneVerticalResizeElementRef, className: classes.paneContent, style: { height: `clamp(200px,calc(45% + var(${paneHeightAdjustCSSVar}, 0px)), 100% - 300px)`, flex: "0 0 auto" }, children: [bottomSelectedTab?.title ? (jsxs(Fragment, { children: [jsx(Title3, { className: classes.paneHeader, children: bottomSelectedTab.title }), jsx(Divider, { inset: true, className: classes.headerDivider, appearance: "brand" })] })) : null, bottomSelectedTab?.content && jsx(bottomSelectedTab.content, {})] })), toolbarMode === "compact" && bottomBarItems.length > 0 && (jsx(Fragment, { children: jsx("div", { className: classes.barDiv, children: jsx(Toolbar, { location: "bottom", components: bottomBarItems }) }) }))] }) }), jsx("div", { className: `${classes.resizer} ${alignment === "left" ? classes.resizerLeft : classes.resizerRight}`, style: { pointerEvents: `${collapsed ? "none" : "auto"}` }, onPointerDown: onResizerPointerDown })] })) }));
1577
+ }, [topPanes, topSelectedTab, bottomPanes, bottomSelectedTab, topBarItems, bottomBarItems, collapsed, width, resizing]);
1574
1578
  return [topPaneTabList, pane];
1575
1579
  }
1576
1580
  function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWidth = 350, rightPaneDefaultWidth = 350, rightPaneMinWidth = 350, toolbarMode = "full", sidePaneMode = "both", } = {}) {
@@ -1578,46 +1582,46 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
1578
1582
  friendlyName: "MainView",
1579
1583
  produces: [ShellServiceIdentity, RootComponentServiceIdentity],
1580
1584
  factory: () => {
1581
- const topBarComponentCollection = new ObservableCollection();
1582
- const bottomBarComponentCollection = new ObservableCollection();
1583
- const topLeftPaneComponentCollection = new ObservableCollection();
1584
- const topRightPaneComponentCollection = new ObservableCollection();
1585
- const bottomLeftPaneComponentCollection = new ObservableCollection();
1586
- const bottomRightPaneComponentCollection = new ObservableCollection();
1587
- const contentComponentCollection = new ObservableCollection();
1585
+ const topBarItemCollection = new ObservableCollection();
1586
+ const bottomBarItemCollection = new ObservableCollection();
1587
+ const topLeftPaneCollection = new ObservableCollection();
1588
+ const topRightPaneCollection = new ObservableCollection();
1589
+ const bottomLeftPaneCollection = new ObservableCollection();
1590
+ const bottomRightPaneCollection = new ObservableCollection();
1591
+ const centralContentCollection = new ObservableCollection();
1588
1592
  const rootComponent = () => {
1589
- const classes = useStyles$9();
1590
- const topBarItems = useOrderedObservableCollection(topBarComponentCollection);
1591
- const bottomBarItems = useOrderedObservableCollection(bottomBarComponentCollection);
1592
- const topLeftPaneItems = useOrderedObservableCollection(topLeftPaneComponentCollection);
1593
- const topRightPaneItems = useOrderedObservableCollection(topRightPaneComponentCollection);
1594
- const bottomLeftPaneItems = useOrderedObservableCollection(bottomLeftPaneComponentCollection);
1595
- const bottomRightPaneItems = useOrderedObservableCollection(bottomRightPaneComponentCollection);
1596
- const hasLeftPaneItems = topLeftPaneItems.length > 0 || bottomLeftPaneItems.length > 0;
1597
- const hasRightPaneItems = topRightPaneItems.length > 0 || bottomRightPaneItems.length > 0;
1593
+ const classes = useStyles$a();
1594
+ const topBarItems = useOrderedObservableCollection(topBarItemCollection);
1595
+ const bottomBarItems = useOrderedObservableCollection(bottomBarItemCollection);
1596
+ const topLeftPanes = useOrderedObservableCollection(topLeftPaneCollection);
1597
+ const topRightPanes = useOrderedObservableCollection(topRightPaneCollection);
1598
+ const bottomLeftPanes = useOrderedObservableCollection(bottomLeftPaneCollection);
1599
+ const bottomRightPanes = useOrderedObservableCollection(bottomRightPaneCollection);
1600
+ const hasLeftPanes = topLeftPanes.length > 0 || bottomLeftPanes.length > 0;
1601
+ const hasRightPanes = topRightPanes.length > 0 || bottomRightPanes.length > 0;
1598
1602
  // If we are in compact toolbar mode, we may need to move toolbar items from the left to the right or vice versa,
1599
1603
  // depending on whether there are any side panes on that side.
1600
1604
  const coerceToolBarItemHorizontalLocation = (item) => {
1601
1605
  let location = item.horizontalLocation;
1602
1606
  // Coercion is only needed in compact toolbar mode since there might not be a left or right pane.
1603
1607
  if (toolbarMode === "compact") {
1604
- if (location === "left" && !hasLeftPaneItems) {
1608
+ if (location === "left" && !hasLeftPanes) {
1605
1609
  location = "right";
1606
1610
  }
1607
- if (location === "right" && !hasRightPaneItems) {
1611
+ if (location === "right" && !hasRightPanes) {
1608
1612
  location = "left";
1609
1613
  }
1610
1614
  }
1611
1615
  return location;
1612
1616
  };
1613
- const topBarLeftComponents = useMemo(() => topBarItems.filter((entry) => coerceToolBarItemHorizontalLocation(entry) === "left"), [topBarItems]);
1614
- const topBarRightComponents = useMemo(() => topBarItems.filter((entry) => coerceToolBarItemHorizontalLocation(entry) === "right"), [topBarItems]);
1615
- const bottomBarLeftComponents = useMemo(() => bottomBarItems.filter((entry) => coerceToolBarItemHorizontalLocation(entry) === "left"), [bottomBarItems]);
1616
- const bottomBarRightComponents = useMemo(() => bottomBarItems.filter((entry) => coerceToolBarItemHorizontalLocation(entry) === "right"), [bottomBarItems]);
1617
- const contentComponents = useOrderedObservableCollection(contentComponentCollection);
1618
- const [leftPaneTabList, leftPane] = usePane("left", leftPaneDefaultWidth, leftPaneMinWidth, topLeftPaneItems, bottomLeftPaneItems, toolbarMode, topBarLeftComponents, bottomBarLeftComponents);
1619
- const [rightPaneTabList, rightPane] = usePane("right", rightPaneDefaultWidth, rightPaneMinWidth, topRightPaneItems, bottomRightPaneItems, toolbarMode, topBarRightComponents, bottomBarRightComponents);
1620
- return (jsxs("div", { className: classes.mainView, children: [toolbarMode === "full" && (jsx(Fragment, { children: jsxs("div", { className: classes.barDiv, children: [leftPaneTabList, jsx(Toolbar, { location: "top", components: topBarItems }), rightPaneTabList] }) })), jsxs("div", { className: classes.verticallyCentralContent, children: [leftPane, jsx("div", { className: classes.centralContent, children: contentComponents.map((entry) => (jsx(entry.component, {}, entry.key))) }), rightPane] }), toolbarMode === "full" && (jsx(Fragment, { children: jsx("div", { className: classes.barDiv, children: jsx(Toolbar, { location: "bottom", components: bottomBarItems }) }) }))] }));
1617
+ const topBarLeftItems = useMemo(() => topBarItems.filter((entry) => coerceToolBarItemHorizontalLocation(entry) === "left"), [topBarItems]);
1618
+ const topBarRightItems = useMemo(() => topBarItems.filter((entry) => coerceToolBarItemHorizontalLocation(entry) === "right"), [topBarItems]);
1619
+ const bottomBarLeftItems = useMemo(() => bottomBarItems.filter((entry) => coerceToolBarItemHorizontalLocation(entry) === "left"), [bottomBarItems]);
1620
+ const bottomBarRightItems = useMemo(() => bottomBarItems.filter((entry) => coerceToolBarItemHorizontalLocation(entry) === "right"), [bottomBarItems]);
1621
+ const centralContents = useOrderedObservableCollection(centralContentCollection);
1622
+ const [leftPaneTabList, leftPane] = usePane("left", leftPaneDefaultWidth, leftPaneMinWidth, topLeftPanes, bottomLeftPanes, toolbarMode, topBarLeftItems, bottomBarLeftItems);
1623
+ const [rightPaneTabList, rightPane] = usePane("right", rightPaneDefaultWidth, rightPaneMinWidth, topRightPanes, bottomRightPanes, toolbarMode, topBarRightItems, bottomBarRightItems);
1624
+ return (jsxs("div", { className: classes.mainView, children: [toolbarMode === "full" && (jsx(Fragment, { children: jsxs("div", { className: classes.barDiv, children: [leftPaneTabList, jsx(Toolbar, { location: "top", components: topBarItems }), rightPaneTabList] }) })), jsxs("div", { className: classes.verticallyCentralContent, children: [leftPane, jsx("div", { className: classes.centralContent, children: centralContents.map((entry) => (jsx(entry.component, {}, entry.key))) }), rightPane] }), toolbarMode === "full" && (jsx(Fragment, { children: jsx("div", { className: classes.barDiv, children: jsx(Toolbar, { location: "bottom", components: bottomBarItems }) }) }))] }));
1621
1625
  };
1622
1626
  rootComponent.displayName = "Shell Service Root";
1623
1627
  return {
@@ -1626,10 +1630,10 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
1626
1630
  entry.component.displayName = `${entry.key} | ${entry.verticalLocation} ${entry.horizontalLocation} bar item`;
1627
1631
  }
1628
1632
  if (entry.verticalLocation === "top") {
1629
- return topBarComponentCollection.add(entry);
1633
+ return topBarItemCollection.add(entry);
1630
1634
  }
1631
1635
  else {
1632
- return bottomBarComponentCollection.add(entry);
1636
+ return bottomBarItemCollection.add(entry);
1633
1637
  }
1634
1638
  },
1635
1639
  addSidePane: (entry) => {
@@ -1655,22 +1659,22 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
1655
1659
  const { horizontalLocation, verticalLocation } = coerceSidePaneLocation(entry);
1656
1660
  if (horizontalLocation === "left") {
1657
1661
  if (verticalLocation === "top") {
1658
- return topLeftPaneComponentCollection.add(entry);
1662
+ return topLeftPaneCollection.add(entry);
1659
1663
  }
1660
1664
  else {
1661
- return bottomLeftPaneComponentCollection.add(entry);
1665
+ return bottomLeftPaneCollection.add(entry);
1662
1666
  }
1663
1667
  }
1664
1668
  else {
1665
1669
  if (verticalLocation === "top") {
1666
- return topRightPaneComponentCollection.add(entry);
1670
+ return topRightPaneCollection.add(entry);
1667
1671
  }
1668
1672
  else {
1669
- return bottomRightPaneComponentCollection.add(entry);
1673
+ return bottomRightPaneCollection.add(entry);
1670
1674
  }
1671
1675
  }
1672
1676
  },
1673
- addCentralContent: (entry) => contentComponentCollection.add(entry),
1677
+ addCentralContent: (entry) => centralContentCollection.add(entry),
1674
1678
  rootComponent,
1675
1679
  };
1676
1680
  },
@@ -1820,7 +1824,7 @@ function ExpandOrCollapseAll(treeItem, open, openItems) {
1820
1824
  TraverseGraph([treeItem], (treeItem) => treeItem.children, (treeItem) => addOrRemove(treeItem.type === "entity" ? treeItem.entity.uniqueId : treeItem.sectionName));
1821
1825
  }
1822
1826
  // eslint-disable-next-line @typescript-eslint/naming-convention
1823
- const useStyles$8 = makeStyles({
1827
+ const useStyles$9 = makeStyles({
1824
1828
  rootDiv: {
1825
1829
  flex: 1,
1826
1830
  overflow: "hidden",
@@ -1855,7 +1859,7 @@ const ToggleCommand = (props) => {
1855
1859
  };
1856
1860
  const SceneTreeItem = (props) => {
1857
1861
  const { isSelected, select } = props;
1858
- const classes = useStyles$8();
1862
+ const classes = useStyles$9();
1859
1863
  return (jsx(FlatTreeItem, { value: "scene", itemType: "leaf", parentValue: undefined, "aria-level": 1, "aria-setsize": 1, "aria-posinset": 1, onClick: select, children: jsx(TreeItemLayout, { iconBefore: jsx(MoviesAndTvRegular, {}), className: classes.sceneTreeItemLayout, style: isSelected ? { backgroundColor: tokens.colorNeutralBackground1Selected } : undefined, children: jsx(Body1Strong, { wrap: false, truncate: true, children: "Scene" }) }) }, "scene"));
1860
1864
  };
1861
1865
  const SectionTreeItem = (props) => {
@@ -1916,7 +1920,7 @@ const EntityTreeItem = (props) => {
1916
1920
  }, children: jsx(Body1, { wrap: false, truncate: true, children: name.substring(0, 100) }) }) }, entityItem.entity.uniqueId) }), jsx(MenuPopover, { hidden: !entityItem.children?.length, children: jsxs(MenuList, { children: [jsx(MenuItem, { onClick: expandAll, children: jsx(Body1, { children: "Expand All" }) }), jsx(MenuItem, { onClick: collapseAll, children: jsx(Body1, { children: "Collapse All" }) })] }) })] }));
1917
1921
  };
1918
1922
  const SceneExplorer = (props) => {
1919
- const classes = useStyles$8();
1923
+ const classes = useStyles$9();
1920
1924
  const { sections, commandProviders, scene, selectedEntity } = props;
1921
1925
  const [openItems, setOpenItems] = useState(new Set());
1922
1926
  const [sceneVersion, setSceneVersion] = useState(0);
@@ -2655,11 +2659,18 @@ const TextPropertyLine = (props) => {
2655
2659
  return (jsx(PropertyLine, { ...props, children: jsx(Body1, { title: title, children: value }) }));
2656
2660
  };
2657
2661
 
2662
+ const useStyles$8 = makeStyles({
2663
+ pinnedStatsPane: {
2664
+ flex: "0 1 auto",
2665
+ paddingBottom: tokens.spacingHorizontalM,
2666
+ },
2667
+ });
2658
2668
  const StatsPane = (props) => {
2669
+ const classes = useStyles$8();
2659
2670
  const scene = props.context;
2660
2671
  const engine = scene.getEngine();
2661
2672
  const fps = useObservableState(() => Math.round(engine.getFps()), engine.onBeginFrameObservable);
2662
- return (jsxs(Fragment, { children: [jsxs(Pane$1, { children: [jsx(TextPropertyLine, { label: "Version", description: "The Babylon.js engine version.", value: AbstractEngine.Version }, "EngineVersion"), jsx(StringifiedPropertyLine, { label: "FPS:", description: "The current framerate", value: fps }, "FPS")] }), jsx(ExtensibleAccordion, { ...props })] }));
2673
+ return (jsxs(Fragment, { children: [jsxs(SidePaneContainer, { className: classes.pinnedStatsPane, children: [jsx(TextPropertyLine, { label: "Version", description: "The Babylon.js engine version.", value: AbstractEngine.Version }, "EngineVersion"), jsx(StringifiedPropertyLine, { label: "FPS:", description: "The current framerate", value: fps }, "FPS")] }), jsx(ExtensibleAccordion, { ...props })] }));
2663
2674
  };
2664
2675
 
2665
2676
  /**
@@ -3832,6 +3843,41 @@ const InfoLabel = (props) => {
3832
3843
  return (jsx(InfoLabel$1, { htmlFor: props.htmlFor, info: props.info, children: jsx(Body1, { children: props.label }) }));
3833
3844
  };
3834
3845
 
3846
+ const TextInput = (props) => {
3847
+ const classes = useInputStyles$1();
3848
+ const [value, setValue] = useState(props.value);
3849
+ const lastCommittedValue = useRef(props.value);
3850
+ useEffect(() => {
3851
+ if (props.value !== lastCommittedValue.current) {
3852
+ setValue(props.value); // Update local state when props.value changes
3853
+ lastCommittedValue.current = props.value;
3854
+ }
3855
+ }, [props.value]);
3856
+ const validateValue = (val) => {
3857
+ const failsValidator = props.validator && !props.validator(val);
3858
+ return !failsValidator;
3859
+ };
3860
+ const tryCommitValue = (currVal) => {
3861
+ // Only commit if valid and different from last committed value
3862
+ if (validateValue(currVal) && currVal !== lastCommittedValue.current) {
3863
+ lastCommittedValue.current = currVal;
3864
+ props.onChange(currVal);
3865
+ }
3866
+ };
3867
+ const handleChange = (event, data) => {
3868
+ event.stopPropagation();
3869
+ setValue(data.value);
3870
+ tryCommitValue(data.value);
3871
+ };
3872
+ const handleKeyUp = (event) => {
3873
+ event.stopPropagation();
3874
+ setValue(event.currentTarget.value);
3875
+ tryCommitValue(event.currentTarget.value);
3876
+ };
3877
+ const id = useId("input-button");
3878
+ return (jsxs("div", { children: [props.infoLabel && jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), jsx(Input, { ...props, id: id, size: "medium", value: value, onChange: handleChange, onKeyUp: handleKeyUp, onKeyDown: HandleKeyDown, onBlur: HandleOnBlur, className: `${!validateValue(value) ? classes.invalid : classes.valid}` })] }));
3879
+ };
3880
+
3835
3881
  const SpinButton = (props) => {
3836
3882
  const classes = useInputStyles$1();
3837
3883
  const { min, max } = props;
@@ -3921,6 +3967,22 @@ function PrecisionRound(value, precision) {
3921
3967
  return Math.round(value * exp) / exp;
3922
3968
  }
3923
3969
 
3970
+ /**
3971
+ * Wraps a text input in a property line
3972
+ * @param props - PropertyLineProps and InputProps
3973
+ * @returns property-line wrapped input component
3974
+ */
3975
+ const TextInputPropertyLine = (props) => (jsx(PropertyLine, { ...props, children: jsx(TextInput, { ...props }) }));
3976
+ /**
3977
+ * Wraps a number input in a property line
3978
+ * To force integer values, use forceInt param (this is distinct from the 'step' param, which will still allow submitting an integer value. forceInt will not)
3979
+ * @param props - PropertyLineProps and InputProps
3980
+ * @returns property-line wrapped input component
3981
+ */
3982
+ const NumberInputPropertyLine = (props) => {
3983
+ return (jsx(PropertyLine, { ...props, children: jsx(SpinButton, { ...props }) }));
3984
+ };
3985
+
3924
3986
  const useSyncedSliderStyles = makeStyles({
3925
3987
  container: { display: "flex" },
3926
3988
  syncedSlider: {
@@ -3993,57 +4055,6 @@ const SyncedSliderPropertyLine = forwardRef((props, ref) => {
3993
4055
  return (jsx(PropertyLine, { ref: ref, ...props, children: jsx(SyncedSliderInput, { ...sliderProps }) }));
3994
4056
  });
3995
4057
 
3996
- const TextInput = (props) => {
3997
- const classes = useInputStyles$1();
3998
- const [value, setValue] = useState(props.value);
3999
- const lastCommittedValue = useRef(props.value);
4000
- useEffect(() => {
4001
- if (props.value !== lastCommittedValue.current) {
4002
- setValue(props.value); // Update local state when props.value changes
4003
- lastCommittedValue.current = props.value;
4004
- }
4005
- }, [props.value]);
4006
- const validateValue = (val) => {
4007
- const failsValidator = props.validator && !props.validator(val);
4008
- return !failsValidator;
4009
- };
4010
- const tryCommitValue = (currVal) => {
4011
- // Only commit if valid and different from last committed value
4012
- if (validateValue(currVal) && currVal !== lastCommittedValue.current) {
4013
- lastCommittedValue.current = currVal;
4014
- props.onChange(currVal);
4015
- }
4016
- };
4017
- const handleChange = (event, data) => {
4018
- event.stopPropagation();
4019
- setValue(data.value);
4020
- tryCommitValue(data.value);
4021
- };
4022
- const handleKeyUp = (event) => {
4023
- event.stopPropagation();
4024
- setValue(event.currentTarget.value);
4025
- tryCommitValue(event.currentTarget.value);
4026
- };
4027
- const id = useId("input-button");
4028
- return (jsxs("div", { children: [props.infoLabel && jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), jsx(Input, { ...props, id: id, size: "medium", value: value, onChange: handleChange, onKeyUp: handleKeyUp, onKeyDown: HandleKeyDown, onBlur: HandleOnBlur, className: `${!validateValue(value) ? classes.invalid : classes.valid}` })] }));
4029
- };
4030
-
4031
- /**
4032
- * Wraps a text input in a property line
4033
- * @param props - PropertyLineProps and InputProps
4034
- * @returns property-line wrapped input component
4035
- */
4036
- const TextInputPropertyLine = (props) => (jsx(PropertyLine, { ...props, children: jsx(TextInput, { ...props }) }));
4037
- /**
4038
- * Wraps a number input in a property line
4039
- * To force integer values, use forceInt param (this is distinct from the 'step' param, which will still allow submitting an integer value. forceInt will not)
4040
- * @param props - PropertyLineProps and InputProps
4041
- * @returns property-line wrapped input component
4042
- */
4043
- const NumberInputPropertyLine = (props) => {
4044
- return (jsx(PropertyLine, { ...props, children: jsx(SpinButton, { ...props }) }));
4045
- };
4046
-
4047
4058
  const AnimationGroupControlProperties = (props) => {
4048
4059
  const { animationGroup } = props;
4049
4060
  const targetedAnimations = animationGroup.targetedAnimations;
@@ -6707,18 +6718,18 @@ const SpriteGeneralProperties = (props) => {
6707
6718
  return (jsxs(Fragment, { children: [jsx(LinkToEntityPropertyLine, { label: "Parent", description: `Sprite Manager that owns this sprite.`, entity: sprite.manager, selectionService: selectionService }, "Parent"), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Is Visible", description: "Whether the sprite is visible or not.", target: sprite, propertyKey: "isVisible" }, "IsVisible")] }));
6708
6719
  };
6709
6720
 
6710
- const SpriteTransformProperties = (props) => {
6711
- const { sprite, settings } = props;
6712
- const [toDisplayAngle, fromDisplayAngle, useDegrees] = useAngleConverters(settings);
6713
- return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: Vector3PropertyLine, label: "Position", target: sprite, propertyKey: "position" }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Angle", description: `Rotation angle of the sprite in ${useDegrees ? "degrees" : "radians"}`, min: 0, max: toDisplayAngle(Math.PI * 2), step: toDisplayAngle(0.01), target: sprite, propertyKey: "angle", convertTo: toDisplayAngle, convertFrom: fromDisplayAngle }, "Angle"), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Width", description: "Width of the sprite (in world space units)", target: sprite, propertyKey: "width" }, "Width"), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Height", description: "Height of the sprite (in world space units)", target: sprite, propertyKey: "height" }, "Height")] }));
6714
- };
6715
-
6716
6721
  const SpriteOtherProperties = (props) => {
6717
6722
  const { sprite } = props;
6718
6723
  const color = useColor4Property(sprite, "color");
6719
6724
  return (jsx(Fragment, { children: jsx(Color4PropertyLine, { label: "Color", description: "Color to tint the sprite.", value: color, onChange: (col) => (sprite.color = col) }, "Color") }));
6720
6725
  };
6721
6726
 
6727
+ const SpriteTransformProperties = (props) => {
6728
+ const { sprite, settings } = props;
6729
+ const [toDisplayAngle, fromDisplayAngle, useDegrees] = useAngleConverters(settings);
6730
+ return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: Vector3PropertyLine, label: "Position", target: sprite, propertyKey: "position" }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Angle", description: `Rotation angle of the sprite in ${useDegrees ? "degrees" : "radians"}`, min: 0, max: toDisplayAngle(Math.PI * 2), step: toDisplayAngle(0.01), target: sprite, propertyKey: "angle", convertTo: toDisplayAngle, convertFrom: fromDisplayAngle }, "Angle"), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Width", description: "Width of the sprite (in world space units)", target: sprite, propertyKey: "width" }, "Width"), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Height", description: "Height of the sprite (in world space units)", target: sprite, propertyKey: "height" }, "Height")] }));
6731
+ };
6732
+
6722
6733
  const SpritePropertiesServiceDefinition = {
6723
6734
  friendlyName: "Sprite Properties",
6724
6735
  consumes: [PropertiesServiceIdentity, SelectionServiceIdentity, SettingsContextIdentity],
@@ -7003,7 +7014,7 @@ const ThinTextureGeneralProperties = (props) => {
7003
7014
 
7004
7015
  // Don't use instanceof in this case as we don't want to bring in the gui package just to check if the entity is an AdvancedDynamicTexture.
7005
7016
  function IsAdvancedDynamicTexture$1(entity) {
7006
- return entity?.getClassName() === "AdvancedDynamicTexture";
7017
+ return entity?.getClassName?.() === "AdvancedDynamicTexture";
7007
7018
  }
7008
7019
  const TexturePropertiesServiceDefinition = {
7009
7020
  friendlyName: "Texture Properties",
@@ -7392,7 +7403,7 @@ const FrameGraphExplorerServiceDefinition = {
7392
7403
 
7393
7404
  // Don't use instanceof in this case as we don't want to bring in the gui package just to check if the entity is an AdvancedDynamicTexture.
7394
7405
  function IsAdvancedDynamicTexture(entity) {
7395
- return entity?.getClassName() === "AdvancedDynamicTexture";
7406
+ return entity?.getClassName?.() === "AdvancedDynamicTexture";
7396
7407
  }
7397
7408
  const GuiExplorerServiceDefinition = {
7398
7409
  friendlyName: "GUI Explorer",
@@ -8506,5 +8517,5 @@ const TextAreaPropertyLine = (props) => {
8506
8517
  return (jsx(PropertyLine, { ...props, children: jsx(Textarea, { ...props }) }));
8507
8518
  };
8508
8519
 
8509
- export { Accordion, AccordionSection, BooleanBadgePropertyLine, BoundProperty, BuiltInsExtensionFeed, Button, ButtonLine, CalculatePrecision, Checkbox, CheckboxPropertyLine, Collapse, Color3GradientComponent, Color3GradientList, Color3PropertyLine, Color4GradientComponent, Color4GradientList, Color4PropertyLine, ColorPickerPopup, ColorStepGradientComponent, ComboBox, ConstructorFactory, DebugServiceIdentity, DraggableLine, Dropdown, ExtensibleAccordion, FactorGradientComponent, FactorGradientList, FileUploadLine, GetPropertyDescriptor, HexPropertyLine, HideInspector, InfoLabel, InputHexField, InputHsvField, Inspector, InterceptFunction, InterceptProperty, IsInspectorVisible, IsPropertyReadonly, LineContainer, LinkPropertyLine, LinkToEntityPropertyLine, List, MakeDialogTeachingMoment, MakeLazyComponent, MakePopoverTeachingMoment, MakePropertyHook, MakeTeachingMoment, MessageBar, NumberDropdown, NumberDropdownPropertyLine, NumberInputPropertyLine, ObservableCollection, Pane, Pane$1 as PaneContainer, PlaceholderPropertyLine, PositionedPopover, PropertiesServiceIdentity, PropertyLine, QuaternionPropertyLine, RotationVectorPropertyLine, SceneContextIdentity, SceneExplorerServiceIdentity, SearchBar, SearchBox, SelectionServiceDefinition, SelectionServiceIdentity, SettingsContextIdentity, SettingsServiceIdentity, ShellServiceIdentity, ShowInspector, SpinButton, SpinButtonPropertyLine, StatsServiceIdentity, StringDropdown, StringDropdownPropertyLine, StringifiedPropertyLine, Switch, SwitchPropertyLine, SyncedSliderInput, SyncedSliderPropertyLine, TeachingMoment, TextAreaPropertyLine, TextInput, TextInputPropertyLine, TextPropertyLine, Textarea, ToggleButton, ToolsServiceIdentity, Vector2PropertyLine, Vector3PropertyLine, Vector4PropertyLine, useAngleConverters, useAsyncResource, useColor3Property, useColor4Property, useEventfulState, useInterceptObservable, useObservableCollection, useObservableState, useOrderedObservableCollection, usePollingObservable, useProperty, useQuaternionProperty, useResource, useVector3Property };
8520
+ export { Accordion, AccordionSection, BooleanBadgePropertyLine, BoundProperty, BuiltInsExtensionFeed, Button, ButtonLine, CalculatePrecision, Checkbox, CheckboxPropertyLine, Collapse, Color3GradientComponent, Color3GradientList, Color3PropertyLine, Color4GradientComponent, Color4GradientList, Color4PropertyLine, ColorPickerPopup, ColorStepGradientComponent, ComboBox, ConstructorFactory, DebugServiceIdentity, DraggableLine, Dropdown, ExtensibleAccordion, FactorGradientComponent, FactorGradientList, FileUploadLine, GetPropertyDescriptor, HexPropertyLine, HideInspector, InfoLabel, InputHexField, InputHsvField, Inspector, InterceptFunction, InterceptProperty, IsInspectorVisible, IsPropertyReadonly, LineContainer, LinkPropertyLine, LinkToEntityPropertyLine, List, MakeDialogTeachingMoment, MakeLazyComponent, MakePopoverTeachingMoment, MakePropertyHook, MakeTeachingMoment, MessageBar, NumberDropdown, NumberDropdownPropertyLine, NumberInputPropertyLine, ObservableCollection, Pane, PlaceholderPropertyLine, PositionedPopover, PropertiesServiceIdentity, PropertyLine, QuaternionPropertyLine, RotationVectorPropertyLine, SceneContextIdentity, SceneExplorerServiceIdentity, SearchBar, SearchBox, SelectionServiceDefinition, SelectionServiceIdentity, SettingsContextIdentity, SettingsServiceIdentity, ShellServiceIdentity, ShowInspector, SidePaneContainer, SpinButton, SpinButtonPropertyLine, StatsServiceIdentity, StringDropdown, StringDropdownPropertyLine, StringifiedPropertyLine, Switch, SwitchPropertyLine, SyncedSliderInput, SyncedSliderPropertyLine, TeachingMoment, TextAreaPropertyLine, TextInput, TextInputPropertyLine, TextPropertyLine, Textarea, ToggleButton, ToolsServiceIdentity, Vector2PropertyLine, Vector3PropertyLine, Vector4PropertyLine, useAngleConverters, useAsyncResource, useColor3Property, useColor4Property, useEventfulState, useInterceptObservable, useObservableCollection, useObservableState, useOrderedObservableCollection, usePollingObservable, useProperty, useQuaternionProperty, useResource, useVector3Property };
8510
8521
  //# sourceMappingURL=index.js.map