Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
618c2ac
Squashed: Add all changes from freshSharedComponents
Jun 3, 2025
a7f155f
fix eslint issues
Jun 3, 2025
623b303
PR comments
Jun 4, 2025
348b49b
merge
Jun 4, 2025
4d90b99
remove required dropdown defaultvalue and default to first if not sup…
Jun 4, 2025
b54b986
rename styles to classes when using makeStyles; remove the SplitPrope…
Jun 4, 2025
7b640de
rename obj/key to target/propertyKey; move type imports out of {}; a…
Jun 5, 2025
fcefc8f
delete the temp inspectorv2 folder, will update the true iv2 componen…
Jun 5, 2025
e61f9b7
package lock after npm install from codespace
georginahalpern Jun 5, 2025
db03499
revert eslint change
Jun 5, 2025
22a1413
Dummy commit
Jun 5, 2025
1b2dd1a
remove packagelock change from PR
Jun 5, 2025
ab37234
merge
Jun 5, 2025
d86b344
reset
Jun 5, 2025
1a8f367
missing command
RaananW Jun 6, 2025
2e95cef
separate build process
RaananW Jun 6, 2025
d9335f7
try something
RaananW Jun 6, 2025
7795dfb
revert
RaananW Jun 6, 2025
141bf56
add back a single instance of fluent primitive, HOC, toolContext, and…
Jun 6, 2025
9e3b373
package lock
Jun 6, 2025
25e1c89
eslint
Jun 6, 2025
fb3f559
remove usage of the new components -- just create the components them…
Jun 6, 2025
e6e585d
fluentui to any
RaananW Jun 9, 2025
86aa5c1
move the generateDeclaration changes from test branch into this branch
Jun 9, 2025
b7f3887
introduce fluentprovider and contextprovider
Jun 9, 2025
f402c13
explicit imports, shouldnt impact build but want to rule out
Jun 9, 2025
ece188d
remove nested contextprovider
Jun 9, 2025
709f52f
small fix
RaananW Jun 9, 2025
5daac3f
fix regex
RaananW Jun 9, 2025
c555a1e
small push so raanan can test his change
Jun 9, 2025
45c21a8
remove changes to textinputlinecomponent
Jun 9, 2025
ff9fc0a
textinputlinecomponent import changes without yet using conditional f…
Jun 9, 2025
0f898d3
condiitonally load fluent, all relative imports
Jun 9, 2025
f34b501
remove import from root, cleanup react.changeHandlers
Jun 9, 2025
6de41da
update textarea import to include keyboard/change event
Jun 9, 2025
54b75c4
remove icons
Jun 9, 2025
5a94de8
reduce parallelization in umd and es6 build steps to see if it reduce…
Jun 9, 2025
53d405c
point public inspector/gui editor package.json entrypoint to minified…
Jun 11, 2025
cf35e8c
Merge branch 'master' of https://github.com/georginahalpern/Babylon.j…
Jun 11, 2025
d24c8d8
ensure proper binding in the fluent/original componenttype props. rev…
Jun 11, 2025
d5a697a
revert the parallelization change, back to 6
Jun 11, 2025
b50114d
just the package.jsona nd webpack config changes
Jun 11, 2025
50e8c2e
parallel 4
Jun 11, 2025
b03e1f5
revert back to using minified entrypoint, try 4 parallel processes
Jun 11, 2025
9c040e6
Merge branch 'sharedComponents1' of https://github.com/georginahalper…
Jun 11, 2025
04e8327
try both , treeshaking and minfiied entrypoint
Jun 11, 2025
da936aa
Merge branch 'master' of https://github.com/georginahalpern/Babylon.j…
Jun 11, 2025
a208d2a
point to max for umd builds too
Jun 11, 2025
2f7a3f2
add back raanan's optimization
Jun 11, 2025
834d53d
revert webpack usedexports change
Jun 12, 2025
7948373
Build libs (no fluent dependency) and tools (fluent dependency) separ…
ryantrem Jun 12, 2025
1ebfd1d
Dummy commit
ryantrem Jun 12, 2025
8037605
Merge master
ryantrem Jun 12, 2025
67f851d
merge
Jun 16, 2025
742c957
conditionallyusefluent component
Jun 16, 2025
d64c0c7
merge
Jun 16, 2025
c4c8723
Merge branch 'master' of https://github.com/georginahalpern/Babylon.j…
Jun 16, 2025
6ea17ab
merge build changes from master
Jun 16, 2025
c6f8a00
rm webpack config change leftover from testing treeshaking
Jun 16, 2025
117f18f
check for existence of QSP instead of truthiness
Jun 16, 2025
5d6a54a
remove HOC for conditionally loading fluent
Jun 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,16 @@ const rules = {
match: true,
},
},
{
// Exception for hooks which start with 'use'
selector: "variable",
format: ["strictCamelCase"],
modifiers: ["global"],
filter: {
regex: "^use",
match: true,
},
},
{
selector: "variable",
format: ["PascalCase"],
Expand Down
4 changes: 4 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions packages/dev/buildTools/src/generateDeclaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ function GetModuleDeclaration(
// not a dev dependency
// TODO - make a list of external dependencies per package
// for now - we support react
if (match[1] !== "react") {
if (match[1] !== "react" /* && !match[1].startsWith("@fluentui")*/) {
// check what the line imports
line = "";
}
Expand Down Expand Up @@ -163,9 +163,9 @@ function GetModuleDeclaration(
// TODO - make a list of dependencies that are accepted by each package
if (!devPackageName) {
if (externalName) {
if (externalName === "@fortawesome" || externalName === "react-contextmenu") {
if (externalName === "@fortawesome" || externalName === "react-contextmenu" || externalName === "@fluentui") {
// replace with any
const matchRegex = new RegExp(`([ <])(${alias}[^;\n ]*)([^\\w])`, "g");
const matchRegex = new RegExp(`([ <])(${alias}[^,;\n> ]*)([^\\w])`, "g");
processedLines = processedLines.replace(matchRegex, `$1any$3`);
return;
}
Expand Down Expand Up @@ -399,9 +399,9 @@ function GetPackageDeclaration(
// TODO - make a list of dependencies that are accepted by each package
if (!localDevPackageMap) {
if (externalName) {
if (externalName === "@fortawesome" || externalName === "react-contextmenu") {
if (externalName === "@fortawesome" || externalName === "react-contextmenu" || externalName === "@fluentui") {
// replace with any
const matchRegex = new RegExp(`([ <])(${alias}[^;\n ]*)([^\\w])`, "g");
const matchRegex = new RegExp(`([ <])(${alias}[^,;\n> ]*)([^\\w])`, "g");
processedSource = processedSource.replace(matchRegex, `$1any$3`);
return;
} else if (externalName === "react") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ import { SkyMaterialPropertyGridComponent } from "./propertyGrids/materials/skyM
import { Tags } from "core/Misc/tags";
import { LineContainerComponent } from "shared-ui-components/lines/lineContainerComponent";
import type { RectAreaLight } from "core/Lights/rectAreaLight";
import { FluentToolWrapper } from "shared-ui-components/fluent/hoc/fluentToolWrapper";

export class PropertyGridTabComponent extends PaneComponent {
private _timerIntervalId: number;
Expand Down Expand Up @@ -774,15 +775,17 @@ export class PropertyGridTabComponent extends PaneComponent {
const entity = this.props.selectedEntity || {};
const entityHasMetadataProp = Object.prototype.hasOwnProperty.call(entity, "metadata");
return (
<div className="pane">
{this.renderContent()}
{Tags.HasTags(entity) && (
<LineContainerComponent title="TAGS" selection={this.props.globalState}>
<div className="tagContainer">{this.renderTags()}</div>
</LineContainerComponent>
)}
{entityHasMetadataProp && <MetadataGridComponent globalState={this.props.globalState} entity={entity} />}
</div>
<FluentToolWrapper>
<div className="pane">
{this.renderContent()}
{Tags.HasTags(entity) && (
<LineContainerComponent title="TAGS" selection={this.props.globalState}>
<div className="tagContainer">{this.renderTags()}</div>
</LineContainerComponent>
)}
{entityHasMetadataProp && <MetadataGridComponent globalState={this.props.globalState} entity={entity} />}
</div>
</FluentToolWrapper>
);
}
}
4 changes: 4 additions & 0 deletions packages/dev/sharedUiComponents/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"@fortawesome/fontawesome-svg-core": "^6.1.0",
"@fortawesome/free-solid-svg-icons": "^6.1.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@fluentui/react-components": "^9.62.0",
"@fluentui/react-icons": "^2.0.271",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"react": "^18.2.0",
Expand All @@ -38,6 +40,8 @@
"@fortawesome/fontawesome-svg-core": "^6.1.0",
"@fortawesome/free-solid-svg-icons": "^6.0.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@fluentui/react-components": "^9.62.0",
"@fluentui/react-icons": "^2.0.271",
"sass": "^1.62.1"
},
"sideEffects": false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { FunctionComponent } from "react";

import type { PropertyLineProps } from "./propertyLine";
import { PropertyLine } from "./propertyLine";
import { SyncedSliderLine } from "./syncedSliderLine";

import type { Color3 } from "core/Maths/math.color";
import { Color4 } from "core/Maths/math.color";

type ColorSliderProps = {
color: Color3 | Color4;
};

const ColorSliders: FunctionComponent<ColorSliderProps> = (props) => {
return (
<>
<SyncedSliderLine label="R" propertyKey="r" target={props.color} min={0} max={255} />
<SyncedSliderLine label="G" propertyKey="g" target={props.color} min={0} max={255} />
<SyncedSliderLine label="B" propertyKey="b" target={props.color} min={0} max={255} />
{props.color instanceof Color4 && <SyncedSliderLine label="A" propertyKey="a" target={props.color} min={0} max={1} />}
</>
);
};

/**
* Reusable component which renders a color property line containing a label, colorPicker popout, and expandable RGBA values
* The expandable RGBA values are synced sliders that allow the user to modify the color's RGBA values directly
* @param props - PropertyLine props, replacing children with a color object so that we can properly display the color
* @returns Component wrapping a colorPicker component (coming soon) with a property line
*/
export const ColorPropertyLine: FunctionComponent<ColorSliderProps & PropertyLineProps> = (props) => {
return (
<PropertyLine {...props} expandedContent={<ColorSliders {...props} />}>
{
props.color.toString()
// Will replace with colorPicker in future PR
}
</PropertyLine>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { PropsWithChildren, FunctionComponent } from "react";
import { createContext } from "react";
import type { Theme } from "@fluentui/react-components";
import { FluentProvider, webDarkTheme } from "@fluentui/react-components";

export type ToolHostProps = {
/**
* Allows host to pass in a theme
*/
customTheme?: Theme;
};

export const ToolContext = createContext({ useFluent: false as boolean } as const);

/**
* For tools which are ready to move over the fluent, wrap the root of the tool (or the panel which you want fluentized) with this component
* Today we will only enable fluent if the URL has the `newUX` query parameter is truthy
* @param props
* @returns
*/
export const FluentToolWrapper: FunctionComponent<PropsWithChildren<ToolHostProps>> = (props) => {
const url = new URL(window.location.href);
const enableFluent = url.searchParams.has("newUX") || url.hash.includes("newUX");

return enableFluent ? (
<FluentProvider theme={props.customTheme || webDarkTheme}>
<ToolContext.Provider value={{ useFluent: true }}>{props.children}</ToolContext.Provider>
</FluentProvider>
) : (
props.children
);
};
108 changes: 108 additions & 0 deletions packages/dev/sharedUiComponents/src/fluent/hoc/propertyLine.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { Body1Strong, Button, InfoLabel, makeStyles, tokens } from "@fluentui/react-components";
import { Add24Filled, Copy24Regular, Subtract24Filled } from "@fluentui/react-icons";
import type { FunctionComponent, PropsWithChildren } from "react";
import { useState } from "react";
import { copyCommandToClipboard } from "../../copyCommandToClipboard";

const usePropertyLineStyles = makeStyles({
container: {
width: "100%",
display: "flex",
flexDirection: "column", // Stack line + expanded content
borderBottom: `${tokens.strokeWidthThin} solid ${tokens.colorNeutralStroke1}`,
},
line: {
display: "flex",
alignItems: "center",
justifyContent: "flex-start",
padding: `${tokens.spacingVerticalXS} 0px`,
width: "100%",
},
label: {
width: "33%",
textAlign: "left",
},
rightContent: {
width: "67%",
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
},
button: {
marginLeft: tokens.spacingHorizontalXXS,
width: "100px",
},
fillRestOfRightContentWidth: {
flex: 1,
display: "flex",
justifyContent: "flex-end",
alignItems: "center",
},
expandedContent: {
backgroundColor: tokens.colorNeutralBackground1,
},
});

export type PropertyLineProps = {
/**
* The name of the property to display in the property line.
*/
label: string;
/**
* Optional description for the property, shown on hover of the info icon
*/
description?: string;
/**
* Optional function returning a string to copy to clipboard.
*/
onCopy?: () => string;
/**
* If supplied, an 'expand' icon will be shown which, when clicked, renders this component within the property line.
*/
expandedContent?: JSX.Element;
};

/**
* A reusable component that renders a property line with a label and child content, and an optional description, copy button, and expandable section.
*
* @param props - The properties for the PropertyLine component.
* @returns A React element representing the property line.
*
*/
export const PropertyLine: FunctionComponent<PropsWithChildren<PropertyLineProps>> = (props) => {
const classes = usePropertyLineStyles();
const [expanded, setExpanded] = useState(false);

const { label, description, onCopy, expandedContent, children } = props;

return (
<div className={classes.container}>
<div className={classes.line}>
<InfoLabel className={classes.label} info={description}>
<Body1Strong>{label}</Body1Strong>
</InfoLabel>
<div className={classes.rightContent}>
<div className={classes.fillRestOfRightContentWidth}>{children}</div>

{expandedContent && (
<Button
appearance="subtle"
icon={expanded ? <Subtract24Filled /> : <Add24Filled />}
className={classes.button}
onClick={(e) => {
e.stopPropagation();
setExpanded((expanded) => !expanded);
}}
/>
)}

{onCopy && (
<Button className={classes.button} id="copyProperty" icon={<Copy24Regular />} onClick={() => copyCommandToClipboard(onCopy())} title="Copy to clipboard" />
)}
</div>
</div>

{expanded && expandedContent && <div className={classes.expandedContent}>{expandedContent}</div>}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { PropertyLine } from "./propertyLine";
import type { PropertyLineProps } from "./propertyLine";
import { SyncedSliderInput } from "../primitives/syncedSlider";
import type { SyncedSliderProps } from "../primitives/syncedSlider";

export type SyncedSliderLineProps<O, K> = PropertyLineProps &
Omit<SyncedSliderProps, "value" | "onChange"> & {
/**
* String key
*/
propertyKey: K;
/**
* target where O[K] is a number
*/
target: O;
/**
* Callback when either the slider or input value changes
*/
onChange?: (value: number) => void;
};

/**
* Renders a SyncedSlider within a PropertyLine for a given key/value pair, where the value is number (ex: can be used for a color's RGBA values, a vector's XYZ values, etc)
* When value changes, updates the object with the new value and calls the onChange callback.
*
* Example usage looks like
* \<SyncedSliderLine propertyKey="x" target=\{vector\} /\>
* \<SyncedSliderLine propertyKey="r" target=\{color\} /\>
* @param props
* @returns
*/
export const SyncedSliderLine = <O extends Record<K, number>, K extends PropertyKey>(props: SyncedSliderLineProps<O, K>): React.ReactElement => {
return (
<PropertyLine {...props}>
<SyncedSliderInput
{...props}
value={props.target[props.propertyKey]}
onChange={(val) => {
props.target[props.propertyKey] = val as O[K];
props.onChange?.(val);
}}
/>
</PropertyLine>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { FunctionComponent } from "react";

import { Body1 } from "@fluentui/react-components";
import { PropertyLine } from "./propertyLine";
import type { PropertyLineProps } from "./propertyLine";

import { SyncedSliderLine } from "./syncedSliderLine";

import { Vector4 } from "core/Maths/math.vector";
import type { Vector3 } from "core/Maths/math.vector";

type VectorSliderProps = {
vector: Vector3 | Vector4;
min?: number;
max?: number;
step?: number;
};

const VectorSliders: FunctionComponent<VectorSliderProps> = (props) => {
const { vector, ...sliderProps } = props;
return (
<>
<SyncedSliderLine label="X" propertyKey="x" target={vector} {...sliderProps} />
<SyncedSliderLine label="Y" propertyKey="y" target={vector} {...sliderProps} />
<SyncedSliderLine label="Z" propertyKey="z" target={vector} {...sliderProps} />
{vector instanceof Vector4 && <SyncedSliderLine label="W" propertyKey="w" target={vector} {...sliderProps} />}
</>
);
};

/**
* Reusable component which renders a vector property line containing a label, vector value, and expandable XYZW values
* The expanded section contains a slider/input box for each component of the vector (x, y, z, w)
* @param props
* @returns
*/
export const VectorPropertyLine: FunctionComponent<VectorSliderProps & PropertyLineProps> = (props) => {
return (
<PropertyLine {...props} expandedContent={<VectorSliders {...props} />}>
<Body1>{props.vector.toString()}</Body1>
</PropertyLine>
);
};
Loading
Loading