@babylonjs/shared-ui-components 8.44.0 → 8.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/constToOptionsMaps.d.ts +7 -0
- package/constToOptionsMaps.js +9 -0
- package/constToOptionsMaps.js.map +1 -1
- package/fluent/hoc/fluentToolWrapper.d.ts +4 -0
- package/fluent/hoc/fluentToolWrapper.js +2 -1
- package/fluent/hoc/fluentToolWrapper.js.map +1 -1
- package/fluent/hoc/propertyLines/entitySelectorPropertyLine.d.ts +4 -0
- package/fluent/hoc/propertyLines/entitySelectorPropertyLine.js +2 -0
- package/fluent/hoc/propertyLines/entitySelectorPropertyLine.js.map +1 -1
- package/fluent/hoc/propertyLines/propertyLine.js +9 -1
- package/fluent/hoc/propertyLines/propertyLine.js.map +1 -1
- package/fluent/primitives/button.d.ts +3 -2
- package/fluent/primitives/button.js.map +1 -1
- package/fluent/primitives/comboBox.js +6 -1
- package/fluent/primitives/comboBox.js.map +1 -1
- package/fluent/primitives/contextMenu.d.ts +105 -0
- package/fluent/primitives/contextMenu.js +56 -0
- package/fluent/primitives/contextMenu.js.map +1 -0
- package/fluent/primitives/entitySelector.d.ts +10 -2
- package/fluent/primitives/entitySelector.js +41 -5
- package/fluent/primitives/entitySelector.js.map +1 -1
- package/fluent/primitives/link.d.ts +19 -2
- package/fluent/primitives/link.js +5 -3
- package/fluent/primitives/link.js.map +1 -1
- package/fluent/primitives/materialSelector.d.ts +2 -1
- package/fluent/primitives/materialSelector.js.map +1 -1
- package/fluent/primitives/nodeSelector.d.ts +2 -1
- package/fluent/primitives/nodeSelector.js.map +1 -1
- package/fluent/primitives/skeletonSelector.d.ts +22 -0
- package/fluent/primitives/skeletonSelector.js +16 -0
- package/fluent/primitives/skeletonSelector.js.map +1 -0
- package/fluent/primitives/textureSelector.d.ts +2 -1
- package/fluent/primitives/textureSelector.js +3 -3
- package/fluent/primitives/textureSelector.js.map +1 -1
- package/package.json +1 -1
package/constToOptionsMaps.d.ts
CHANGED
|
@@ -21,3 +21,10 @@ export declare const AlphaModeOptions: {
|
|
|
21
21
|
label: string;
|
|
22
22
|
value: number;
|
|
23
23
|
}[];
|
|
24
|
+
/**
|
|
25
|
+
* Used to populate the billboardMode dropdown for particle systems.
|
|
26
|
+
*/
|
|
27
|
+
export declare const ParticleBillboardModeOptions: {
|
|
28
|
+
label: string;
|
|
29
|
+
value: number;
|
|
30
|
+
}[];
|
package/constToOptionsMaps.js
CHANGED
|
@@ -39,4 +39,13 @@ export const AlphaModeOptions = [
|
|
|
39
39
|
{ label: "Subtract", value: Constants.ALPHA_SUBTRACT },
|
|
40
40
|
{ label: "Multiply", value: Constants.ALPHA_MULTIPLY },
|
|
41
41
|
].concat(CommonBlendModes);
|
|
42
|
+
/**
|
|
43
|
+
* Used to populate the billboardMode dropdown for particle systems.
|
|
44
|
+
*/
|
|
45
|
+
export const ParticleBillboardModeOptions = [
|
|
46
|
+
{ label: "All", value: ParticleSystem.BILLBOARDMODE_ALL },
|
|
47
|
+
{ label: "Y", value: ParticleSystem.BILLBOARDMODE_Y },
|
|
48
|
+
{ label: "Stretched", value: ParticleSystem.BILLBOARDMODE_STRETCHED },
|
|
49
|
+
{ label: "Stretched Local", value: ParticleSystem.BILLBOARDMODE_STRETCHED_LOCAL },
|
|
50
|
+
];
|
|
42
51
|
//# sourceMappingURL=constToOptionsMaps.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constToOptionsMaps.js","sourceRoot":"","sources":["../../../dev/sharedUiComponents/src/constToOptionsMaps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,6CAA+B;AACnD,OAAO,EAAE,cAAc,EAAE,oDAAsC;AAE/D;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC5B,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,eAAe,EAAE;IACxD,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,SAAS,CAAC,mBAAmB,EAAE;IACjE,EAAE,KAAK,EAAE,4BAA4B,EAAE,KAAK,EAAE,SAAS,CAAC,8BAA8B,EAAE;IACxF,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,CAAC,gBAAgB,EAAE;IAC3D,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,CAAC,mBAAmB,EAAE;IAChE,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,SAAS,CAAC,kBAAkB,EAAE;IAChE,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,SAAS,CAAC,qBAAqB,EAAE;IACtE,EAAE,KAAK,EAAE,iCAAiC,EAAE,KAAK,EAAE,SAAS,CAAC,6BAA6B,EAAE;IAC5F,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,SAAS,CAAC,oBAAoB,EAAE;IAClE,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,eAAe,EAAE;IACxD,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,SAAS,CAAC,sBAAsB,EAAE;CACzE,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC5B,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,CAAC,aAAa,EAAE;IACrD,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,CAAC,kBAAkB,EAAE;IAC/D,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,CAAC,qBAAqB,EAAE;IACtE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,CAAC,gBAAgB,EAAE;IAC5D,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,CAAC,kBAAkB,EAAE;IAC/D,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,CAAC,kBAAkB,EAAE;CAClE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAE3B;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC5B,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,aAAa,EAAE;IACpD,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,YAAY,EAAE;IACnD,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,SAAS,EAAE;IAC5C,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,cAAc,EAAE;IACtD,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,cAAc,EAAE;CACzD,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC","sourcesContent":["import { Constants } from \"core/Engines/constants\";\r\nimport { ParticleSystem } from \"core/Particles/particleSystem\";\r\n\r\n/**\r\n * Used by both particleSystem and alphaBlendModes\r\n */\r\nexport const CommonBlendModes = [\r\n { label: \"Maximized\", value: Constants.ALPHA_MAXIMIZED },\r\n { label: \"Pre-multiplied\", value: Constants.ALPHA_PREMULTIPLIED },\r\n { label: \"Pre-multiplied Porter Duff\", value: Constants.ALPHA_PREMULTIPLIED_PORTERDUFF },\r\n { label: \"Screen Mode\", value: Constants.ALPHA_SCREENMODE },\r\n { label: \"OneOne OneOne\", value: Constants.ALPHA_ONEONE_ONEONE },\r\n { label: \"Alpha to Color\", value: Constants.ALPHA_ALPHATOCOLOR },\r\n { label: \"Reverse One Minus\", value: Constants.ALPHA_REVERSEONEMINUS },\r\n { label: \"Source+Dest * (1 - SourceAlpha)\", value: Constants.ALPHA_SRC_DSTONEMINUSSRCALPHA },\r\n { label: \"OneOne OneZero\", value: Constants.ALPHA_ONEONE_ONEZERO },\r\n { label: \"Exclusion\", value: Constants.ALPHA_EXCLUSION },\r\n { label: \"Layer Accumulate\", value: Constants.ALPHA_LAYER_ACCUMULATE },\r\n];\r\n\r\n/**\r\n * Used to populated the blendMode dropdown in our various tools (Node Editor, Inspector, etc.)\r\n * The below ParticleSystem consts were defined before new Engine alpha blend modes were added, so we have to reference\r\n * the ParticleSystem.FOO consts explicitly (as the underlying const values are different - they get mapped to engine consts within baseParticleSystem.ts)\r\n */\r\nexport const BlendModeOptions = [\r\n { label: \"Add\", value: ParticleSystem.BLENDMODE_ADD },\r\n { label: \"Multiply\", value: ParticleSystem.BLENDMODE_MULTIPLY },\r\n { label: \"Multiply Add\", value: ParticleSystem.BLENDMODE_MULTIPLYADD },\r\n { label: \"One One\", value: ParticleSystem.BLENDMODE_ONEONE },\r\n { label: \"Standard\", value: ParticleSystem.BLENDMODE_STANDARD },\r\n { label: \"Subtract\", value: ParticleSystem.BLENDMODE_SUBTRACT },\r\n].concat(CommonBlendModes);\r\n\r\n/**\r\n * Used to populated the alphaMode dropdown in our various tools (Node Editor, Inspector, etc.)\r\n */\r\nexport const AlphaModeOptions = [\r\n { label: \"Combine\", value: Constants.ALPHA_COMBINE },\r\n { label: \"One One\", value: Constants.ALPHA_ONEONE },\r\n { label: \"Add\", value: Constants.ALPHA_ADD },\r\n { label: \"Subtract\", value: Constants.ALPHA_SUBTRACT },\r\n { label: \"Multiply\", value: Constants.ALPHA_MULTIPLY },\r\n].concat(CommonBlendModes);\r\n"]}
|
|
1
|
+
{"version":3,"file":"constToOptionsMaps.js","sourceRoot":"","sources":["../../../dev/sharedUiComponents/src/constToOptionsMaps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,6CAA+B;AACnD,OAAO,EAAE,cAAc,EAAE,oDAAsC;AAE/D;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC5B,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,eAAe,EAAE;IACxD,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,SAAS,CAAC,mBAAmB,EAAE;IACjE,EAAE,KAAK,EAAE,4BAA4B,EAAE,KAAK,EAAE,SAAS,CAAC,8BAA8B,EAAE;IACxF,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,CAAC,gBAAgB,EAAE;IAC3D,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,CAAC,mBAAmB,EAAE;IAChE,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,SAAS,CAAC,kBAAkB,EAAE;IAChE,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,SAAS,CAAC,qBAAqB,EAAE;IACtE,EAAE,KAAK,EAAE,iCAAiC,EAAE,KAAK,EAAE,SAAS,CAAC,6BAA6B,EAAE;IAC5F,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,SAAS,CAAC,oBAAoB,EAAE;IAClE,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,eAAe,EAAE;IACxD,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,SAAS,CAAC,sBAAsB,EAAE;CACzE,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC5B,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,CAAC,aAAa,EAAE;IACrD,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,CAAC,kBAAkB,EAAE;IAC/D,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,CAAC,qBAAqB,EAAE;IACtE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,CAAC,gBAAgB,EAAE;IAC5D,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,CAAC,kBAAkB,EAAE;IAC/D,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,CAAC,kBAAkB,EAAE;CAClE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAE3B;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC5B,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,aAAa,EAAE;IACpD,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,YAAY,EAAE;IACnD,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,SAAS,EAAE;IAC5C,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,cAAc,EAAE;IACtD,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,cAAc,EAAE;CACzD,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAE3B;;GAEG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG;IACxC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,CAAC,iBAAiB,EAAE;IACzD,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,eAAe,EAAE;IACrD,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,CAAC,uBAAuB,EAAE;IACrE,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,cAAc,CAAC,6BAA6B,EAAE;CACpF,CAAC","sourcesContent":["import { Constants } from \"core/Engines/constants\";\r\nimport { ParticleSystem } from \"core/Particles/particleSystem\";\r\n\r\n/**\r\n * Used by both particleSystem and alphaBlendModes\r\n */\r\nexport const CommonBlendModes = [\r\n { label: \"Maximized\", value: Constants.ALPHA_MAXIMIZED },\r\n { label: \"Pre-multiplied\", value: Constants.ALPHA_PREMULTIPLIED },\r\n { label: \"Pre-multiplied Porter Duff\", value: Constants.ALPHA_PREMULTIPLIED_PORTERDUFF },\r\n { label: \"Screen Mode\", value: Constants.ALPHA_SCREENMODE },\r\n { label: \"OneOne OneOne\", value: Constants.ALPHA_ONEONE_ONEONE },\r\n { label: \"Alpha to Color\", value: Constants.ALPHA_ALPHATOCOLOR },\r\n { label: \"Reverse One Minus\", value: Constants.ALPHA_REVERSEONEMINUS },\r\n { label: \"Source+Dest * (1 - SourceAlpha)\", value: Constants.ALPHA_SRC_DSTONEMINUSSRCALPHA },\r\n { label: \"OneOne OneZero\", value: Constants.ALPHA_ONEONE_ONEZERO },\r\n { label: \"Exclusion\", value: Constants.ALPHA_EXCLUSION },\r\n { label: \"Layer Accumulate\", value: Constants.ALPHA_LAYER_ACCUMULATE },\r\n];\r\n\r\n/**\r\n * Used to populated the blendMode dropdown in our various tools (Node Editor, Inspector, etc.)\r\n * The below ParticleSystem consts were defined before new Engine alpha blend modes were added, so we have to reference\r\n * the ParticleSystem.FOO consts explicitly (as the underlying const values are different - they get mapped to engine consts within baseParticleSystem.ts)\r\n */\r\nexport const BlendModeOptions = [\r\n { label: \"Add\", value: ParticleSystem.BLENDMODE_ADD },\r\n { label: \"Multiply\", value: ParticleSystem.BLENDMODE_MULTIPLY },\r\n { label: \"Multiply Add\", value: ParticleSystem.BLENDMODE_MULTIPLYADD },\r\n { label: \"One One\", value: ParticleSystem.BLENDMODE_ONEONE },\r\n { label: \"Standard\", value: ParticleSystem.BLENDMODE_STANDARD },\r\n { label: \"Subtract\", value: ParticleSystem.BLENDMODE_SUBTRACT },\r\n].concat(CommonBlendModes);\r\n\r\n/**\r\n * Used to populated the alphaMode dropdown in our various tools (Node Editor, Inspector, etc.)\r\n */\r\nexport const AlphaModeOptions = [\r\n { label: \"Combine\", value: Constants.ALPHA_COMBINE },\r\n { label: \"One One\", value: Constants.ALPHA_ONEONE },\r\n { label: \"Add\", value: Constants.ALPHA_ADD },\r\n { label: \"Subtract\", value: Constants.ALPHA_SUBTRACT },\r\n { label: \"Multiply\", value: Constants.ALPHA_MULTIPLY },\r\n].concat(CommonBlendModes);\r\n\r\n/**\r\n * Used to populate the billboardMode dropdown for particle systems.\r\n */\r\nexport const ParticleBillboardModeOptions = [\r\n { label: \"All\", value: ParticleSystem.BILLBOARDMODE_ALL },\r\n { label: \"Y\", value: ParticleSystem.BILLBOARDMODE_Y },\r\n { label: \"Stretched\", value: ParticleSystem.BILLBOARDMODE_STRETCHED },\r\n { label: \"Stretched Local\", value: ParticleSystem.BILLBOARDMODE_STRETCHED_LOCAL },\r\n];\r\n"]}
|
|
@@ -18,6 +18,10 @@ export type ToolHostProps = {
|
|
|
18
18
|
* Name of the tool displayed in the UX
|
|
19
19
|
*/
|
|
20
20
|
toolName: string;
|
|
21
|
+
/**
|
|
22
|
+
* Override the qsp detection for fluent
|
|
23
|
+
*/
|
|
24
|
+
useFluent?: boolean;
|
|
21
25
|
};
|
|
22
26
|
export declare const ToolContext: import("react").Context<{
|
|
23
27
|
readonly useFluent: boolean;
|
|
@@ -10,7 +10,8 @@ export const ToolContext = createContext({ useFluent: false, disableCopy: false,
|
|
|
10
10
|
*/
|
|
11
11
|
export const FluentToolWrapper = (props) => {
|
|
12
12
|
const url = new URL(window.location.href);
|
|
13
|
-
const
|
|
13
|
+
const useFluentFromUrl = url.searchParams.has("newUX") || url.hash.includes("newUX");
|
|
14
|
+
const useFluent = props.useFluent ?? useFluentFromUrl;
|
|
14
15
|
const contextValue = {
|
|
15
16
|
useFluent,
|
|
16
17
|
disableCopy: !!props.disableCopy,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluentToolWrapper.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/hoc/fluentToolWrapper.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"fluentToolWrapper.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/hoc/fluentToolWrapper.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AA8B1E,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC,EAAE,SAAS,EAAE,KAAgB,EAAE,WAAW,EAAE,KAAgB,EAAE,QAAQ,EAAE,EAAY,EAAE,IAAI,EAAE,SAA+B,EAAW,CAAC,CAAC;AAEjL;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAwD,CAAC,KAAK,EAAE,EAAE;IAC5F,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,gBAAgB,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACrF,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,gBAAgB,CAAC;IACtD,MAAM,YAAY,GAAG;QACjB,SAAS;QACT,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW;QAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,IAAI,EAAE,KAAK,CAAC,IAAI;KACnB,CAAC;IACF,OAAO,SAAS,CAAC,CAAC,CAAC,CACf,KAAC,cAAc,IAAC,KAAK,EAAE,KAAK,CAAC,WAAW,IAAI,YAAY,YACpD,KAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,YAAY,YAAG,KAAK,CAAC,QAAQ,GAAwB,GACrE,CACpB,CAAC,CAAC,CAAC,CACA,KAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,YAAY,YAAG,KAAK,CAAC,QAAQ,GAAwB,CACrF,CAAC;AACN,CAAC,CAAC","sourcesContent":["import type { PropsWithChildren, FunctionComponent } from \"react\";\r\nimport { createContext } from \"react\";\r\nimport type { Theme } from \"@fluentui/react-components\";\r\nimport { FluentProvider, webDarkTheme } from \"@fluentui/react-components\";\r\n\r\nexport type UiSize = \"small\" | \"medium\";\r\nexport type ToolHostProps = {\r\n /**\r\n * Will ensure all of the controls within the tool are of the same scale\r\n */\r\n size?: UiSize;\r\n\r\n /**\r\n * Allows host to pass in a theme\r\n */\r\n customTheme?: Theme;\r\n\r\n /**\r\n * Can be set to true to disable the copy button in the tool's property lines. Default is false (copy enabled)\r\n */\r\n disableCopy?: boolean;\r\n\r\n /**\r\n * Name of the tool displayed in the UX\r\n */\r\n toolName: string;\r\n\r\n /**\r\n * Override the qsp detection for fluent\r\n */\r\n useFluent?: boolean;\r\n};\r\n\r\nexport const ToolContext = createContext({ useFluent: false as boolean, disableCopy: false as boolean, toolName: \"\" as string, size: undefined as UiSize | undefined } as const);\r\n\r\n/**\r\n * 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\r\n * Today we will only enable fluent if the URL has the `newUX` query parameter is truthy\r\n * @param props\r\n * @returns\r\n */\r\nexport const FluentToolWrapper: FunctionComponent<PropsWithChildren<ToolHostProps>> = (props) => {\r\n const url = new URL(window.location.href);\r\n const useFluentFromUrl = url.searchParams.has(\"newUX\") || url.hash.includes(\"newUX\");\r\n const useFluent = props.useFluent ?? useFluentFromUrl;\r\n const contextValue = {\r\n useFluent,\r\n disableCopy: !!props.disableCopy,\r\n toolName: props.toolName,\r\n size: props.size,\r\n };\r\n return useFluent ? (\r\n <FluentProvider theme={props.customTheme || webDarkTheme}>\r\n <ToolContext.Provider value={contextValue}>{props.children}</ToolContext.Provider>\r\n </FluentProvider>\r\n ) : (\r\n <ToolContext.Provider value={contextValue}>{props.children}</ToolContext.Provider>\r\n );\r\n};\r\n"]}
|
|
@@ -4,12 +4,16 @@ import type { PropertyLineProps } from "./propertyLine.js";
|
|
|
4
4
|
import type { NodeSelectorProps } from "../../primitives/nodeSelector.js";
|
|
5
5
|
import type { MaterialSelectorProps } from "../../primitives/materialSelector.js";
|
|
6
6
|
import type { TextureSelectorProps } from "../../primitives/textureSelector.js";
|
|
7
|
+
import type { SkeletonSelectorProps } from "../../primitives/skeletonSelector.js";
|
|
7
8
|
import type { Material } from "@babylonjs/core/Materials/material.js";
|
|
8
9
|
import type { BaseTexture } from "@babylonjs/core/Materials/Textures/baseTexture.js";
|
|
10
|
+
import type { Skeleton } from "@babylonjs/core/Bones/skeleton.js";
|
|
9
11
|
type NodeSelectorPropertyLineProps = PropertyLineProps<Nullable<Node>> & NodeSelectorProps;
|
|
10
12
|
type MaterialSelectorPropertyLineProps = PropertyLineProps<Nullable<Material>> & MaterialSelectorProps;
|
|
11
13
|
type TextureSelectorPropertyLineProps = PropertyLineProps<Nullable<BaseTexture>> & TextureSelectorProps;
|
|
14
|
+
type SkeletonSelectorPropertyLineProps = PropertyLineProps<Nullable<Skeleton>> & SkeletonSelectorProps;
|
|
12
15
|
export declare const NodeSelectorPropertyLine: (props: NodeSelectorPropertyLineProps) => import("react/jsx-runtime").JSX.Element;
|
|
13
16
|
export declare const MaterialSelectorPropertyLine: (props: MaterialSelectorPropertyLineProps) => import("react/jsx-runtime").JSX.Element;
|
|
14
17
|
export declare const TextureSelectorPropertyLine: (props: TextureSelectorPropertyLineProps) => import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export declare const SkeletonSelectorPropertyLine: (props: SkeletonSelectorPropertyLineProps) => import("react/jsx-runtime").JSX.Element;
|
|
15
19
|
export {};
|
|
@@ -3,7 +3,9 @@ import { MaterialSelector } from "../../primitives/materialSelector.js";
|
|
|
3
3
|
import { PropertyLine } from "./propertyLine.js";
|
|
4
4
|
import { NodeSelector } from "../../primitives/nodeSelector.js";
|
|
5
5
|
import { TextureSelector } from "../../primitives/textureSelector.js";
|
|
6
|
+
import { SkeletonSelector } from "../../primitives/skeletonSelector.js";
|
|
6
7
|
export const NodeSelectorPropertyLine = (props) => _jsx(PropertyLine, { ...props, children: _jsx(NodeSelector, { ...props }) });
|
|
7
8
|
export const MaterialSelectorPropertyLine = (props) => _jsx(PropertyLine, { ...props, children: _jsx(MaterialSelector, { ...props }) });
|
|
8
9
|
export const TextureSelectorPropertyLine = (props) => _jsx(PropertyLine, { ...props, children: _jsx(TextureSelector, { ...props }) });
|
|
10
|
+
export const SkeletonSelectorPropertyLine = (props) => _jsx(PropertyLine, { ...props, children: _jsx(SkeletonSelector, { ...props }) });
|
|
9
11
|
//# sourceMappingURL=entitySelectorPropertyLine.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entitySelectorPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/entitySelectorPropertyLine.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"entitySelectorPropertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/entitySelectorPropertyLine.tsx"],"names":[],"mappings":";AAWA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAOrE,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,KAAoC,EAAE,EAAE,CAAC,KAAC,YAAY,OAAK,KAAK,EAAE,QAAQ,EAAE,KAAC,YAAY,OAAK,KAAK,GAAI,GAAI,CAAC;AACrJ,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,KAAwC,EAAE,EAAE,CAAC,KAAC,YAAY,OAAK,KAAK,EAAE,QAAQ,EAAE,KAAC,gBAAgB,OAAK,KAAK,GAAI,GAAI,CAAC;AACjK,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,KAAuC,EAAE,EAAE,CAAC,KAAC,YAAY,OAAK,KAAK,EAAE,QAAQ,EAAE,KAAC,eAAe,OAAK,KAAK,GAAI,GAAI,CAAC;AAC9J,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,KAAwC,EAAE,EAAE,CAAC,KAAC,YAAY,OAAK,KAAK,EAAE,QAAQ,EAAE,KAAC,gBAAgB,OAAK,KAAK,GAAI,GAAI,CAAC","sourcesContent":["import type { Node } from \"core/node\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { PropertyLineProps } from \"./propertyLine\";\r\nimport type { NodeSelectorProps } from \"../../primitives/nodeSelector\";\r\nimport type { MaterialSelectorProps } from \"../../primitives/materialSelector\";\r\nimport type { TextureSelectorProps } from \"../../primitives/textureSelector\";\r\nimport type { SkeletonSelectorProps } from \"../../primitives/skeletonSelector\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { Skeleton } from \"core/Bones/skeleton\";\r\n\r\nimport { MaterialSelector } from \"../../primitives/materialSelector\";\r\nimport { PropertyLine } from \"./propertyLine\";\r\nimport { NodeSelector } from \"../../primitives/nodeSelector\";\r\nimport { TextureSelector } from \"../../primitives/textureSelector\";\r\nimport { SkeletonSelector } from \"../../primitives/skeletonSelector\";\r\n\r\ntype NodeSelectorPropertyLineProps = PropertyLineProps<Nullable<Node>> & NodeSelectorProps;\r\ntype MaterialSelectorPropertyLineProps = PropertyLineProps<Nullable<Material>> & MaterialSelectorProps;\r\ntype TextureSelectorPropertyLineProps = PropertyLineProps<Nullable<BaseTexture>> & TextureSelectorProps;\r\ntype SkeletonSelectorPropertyLineProps = PropertyLineProps<Nullable<Skeleton>> & SkeletonSelectorProps;\r\n\r\nexport const NodeSelectorPropertyLine = (props: NodeSelectorPropertyLineProps) => <PropertyLine {...props} children={<NodeSelector {...props} />} />;\r\nexport const MaterialSelectorPropertyLine = (props: MaterialSelectorPropertyLineProps) => <PropertyLine {...props} children={<MaterialSelector {...props} />} />;\r\nexport const TextureSelectorPropertyLine = (props: TextureSelectorPropertyLineProps) => <PropertyLine {...props} children={<TextureSelector {...props} />} />;\r\nexport const SkeletonSelectorPropertyLine = (props: SkeletonSelectorPropertyLineProps) => <PropertyLine {...props} children={<SkeletonSelector {...props} />} />;\r\n"]}
|
|
@@ -33,10 +33,18 @@ const usePropertyLineStyles = makeStyles({
|
|
|
33
33
|
},
|
|
34
34
|
rightContent: {
|
|
35
35
|
flex: "0 1 auto",
|
|
36
|
+
minWidth: 0,
|
|
37
|
+
overflow: "hidden",
|
|
36
38
|
display: "flex",
|
|
37
39
|
alignItems: "center",
|
|
38
40
|
justifyContent: "flex-end",
|
|
39
41
|
},
|
|
42
|
+
childWrapper: {
|
|
43
|
+
minWidth: 0,
|
|
44
|
+
overflow: "hidden",
|
|
45
|
+
textOverflow: "ellipsis",
|
|
46
|
+
whiteSpace: "nowrap",
|
|
47
|
+
},
|
|
40
48
|
infoPopup: {
|
|
41
49
|
whiteSpace: "normal",
|
|
42
50
|
wordBreak: "break-word",
|
|
@@ -84,7 +92,7 @@ export const PropertyLine = forwardRef((props, ref) => {
|
|
|
84
92
|
cachedVal.current = props.value;
|
|
85
93
|
props.onChange(null);
|
|
86
94
|
}
|
|
87
|
-
}, title: "Toggle null state" })), processedChildren, onCopy && !disableCopy && (_jsx(Button, { className: classes.copy, title: "Copy to clipboard", appearance: "transparent", icon: size === "small" ? Copy16Regular : Copy20Regular, onClick: () => copyCommandToClipboard(onCopy()) }))] })] }), expandedContent && (_jsx(Collapse, { visible: !!expanded, children: _jsx("div", { className: classes.expandedContentDiv, children: expandedContent }) }))] }));
|
|
95
|
+
}, title: "Toggle null state" })), _jsx("div", { className: classes.childWrapper, children: processedChildren }), onCopy && !disableCopy && (_jsx(Button, { className: classes.copy, title: "Copy to clipboard", appearance: "transparent", icon: size === "small" ? Copy16Regular : Copy20Regular, onClick: () => copyCommandToClipboard(onCopy()) }))] })] }), expandedContent && (_jsx(Collapse, { visible: !!expanded, children: _jsx("div", { className: classes.expandedContentDiv, children: expandedContent }) }))] }));
|
|
88
96
|
});
|
|
89
97
|
const useLineStyles = makeStyles({
|
|
90
98
|
container: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"propertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/propertyLine.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Body1, InfoLabel, Checkbox, makeStyles, Body1Strong, tokens, mergeClasses } from \"@fluentui/react-components\";\r\nimport {\r\n ChevronCircleDown20Regular,\r\n ChevronCircleDown16Regular,\r\n ChevronCircleRight16Regular,\r\n ChevronCircleRight20Regular,\r\n Copy16Regular,\r\n Copy20Regular,\r\n} from \"@fluentui/react-icons\";\r\nimport type { FunctionComponent, HTMLProps, PropsWithChildren } from \"react\";\r\nimport { useContext, useState, forwardRef, cloneElement, isValidElement, useRef } from \"react\";\r\nimport { Collapse } from \"../../primitives/collapse\";\r\nimport { copyCommandToClipboard } from \"../../../copyCommandToClipboard\";\r\nimport { ToolContext } from \"../fluentToolWrapper\";\r\nimport type { PrimitiveProps } from \"../../primitives/primitive\";\r\nimport { Link } from \"../../primitives/link\";\r\nimport { ToggleButton } from \"../../primitives/toggleButton\";\r\nimport { Button } from \"../../primitives/button\";\r\nimport { CustomTokens } from \"../../primitives/utils\";\r\n\r\nconst usePropertyLineStyles = makeStyles({\r\n baseLine: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-start\",\r\n width: \"100%\",\r\n },\r\n infoLabel: {\r\n display: \"flex\",\r\n flex: \"1 1 0\", // grow=1, shrink =1, basis = 0 initial size before\r\n minWidth: CustomTokens.labelMinWidth,\r\n textAlign: \"left\",\r\n },\r\n labelSlot: {\r\n display: \"flex\",\r\n minWidth: 0,\r\n },\r\n labelText: {\r\n whiteSpace: \"nowrap\",\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n },\r\n rightContent: {\r\n flex: \"0 1 auto\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-end\",\r\n },\r\n infoPopup: {\r\n whiteSpace: \"normal\",\r\n wordBreak: \"break-word\",\r\n },\r\n copy: {\r\n marginRight: CustomTokens.rightAlignOffset, // Accounts for the padding baked into fluent button / ensures propertyLine looks visually aligned at the right\r\n },\r\n expandedContentDiv: {\r\n overflow: \"hidden\",\r\n },\r\n});\r\n\r\ntype BasePropertyLineProps = {\r\n /**\r\n * The name of the property to display in the property line.\r\n */\r\n label: string;\r\n /**\r\n * Optional description for the property, shown on hover of the info icon\r\n */\r\n description?: string;\r\n /**\r\n * Optional function returning a string to copy to clipboard.\r\n */\r\n onCopy?: () => string;\r\n /**\r\n * Link to the documentation for this property, available from the info icon either linked from the description (if provided) or default 'docs' text\r\n */\r\n docLink?: string;\r\n};\r\n\r\n// Only require value/onChange/defaultValue props if nullable is true\r\ntype NullableProperty<ValueT> = {\r\n nullable: true;\r\n ignoreNullable: false;\r\n value: ValueT;\r\n onChange: (value: ValueT) => void;\r\n defaultValue?: ValueT;\r\n};\r\n\r\ntype IgnoreNullable<ValueT> = {\r\n ignoreNullable: true;\r\n nullable: false;\r\n value: ValueT;\r\n onChange: (value: ValueT) => void;\r\n defaultValue: ValueT;\r\n};\r\n\r\ntype NonNullableProperty = {\r\n nullable?: false;\r\n ignoreNullable?: false;\r\n};\r\n\r\n// Only expect optional expandByDefault prop if expandedContent is defined\r\ntype ExpandableProperty = {\r\n /**\r\n * If supplied, an 'expand' icon will be shown which, when clicked, renders this component within the property line.\r\n */\r\n expandedContent: JSX.Element;\r\n\r\n /**\r\n * If true, the expanded content will be shown by default.\r\n */\r\n expandByDefault?: boolean;\r\n};\r\n\r\n// If expanded content is undefined, don't expect expandByDefault prop\r\ntype NonExpandableProperty = {\r\n expandedContent?: undefined;\r\n};\r\n\r\nexport type PropertyLineProps<ValueT> = BasePropertyLineProps &\r\n (NullableProperty<ValueT> | NonNullableProperty | IgnoreNullable<ValueT>) &\r\n (ExpandableProperty | NonExpandableProperty);\r\n\r\n/**\r\n * A reusable component that renders a property line with a label and child content, and an optional description, copy button, and expandable section.\r\n *\r\n * @param props - The properties for the PropertyLine component.\r\n * @returns A React element representing the property line.\r\n *\r\n */\r\nexport const PropertyLine = forwardRef<HTMLDivElement, PropsWithChildren<PropertyLineProps<any>>>((props, ref) => {\r\n PropertyLine.displayName = \"PropertyLine\";\r\n const { disableCopy, size } = useContext(ToolContext);\r\n const classes = usePropertyLineStyles();\r\n const { label, onCopy, expandedContent, children, nullable, ignoreNullable } = props;\r\n\r\n const [expanded, setExpanded] = useState(\"expandByDefault\" in props ? props.expandByDefault : false);\r\n const cachedVal = useRef(nullable ? props.value : null);\r\n\r\n const description = props.docLink ? <Link url={props.docLink} value={props.description ?? \"Docs\"} /> : props.description;\r\n\r\n // Process children to handle nullable state -- creating component in disabled state with default value in lieu of null value\r\n const processedChildren =\r\n (nullable || ignoreNullable) && isValidElement(children)\r\n ? cloneElement(children, {\r\n ...children.props,\r\n disabled: children.props.disabled || (nullable && props.value == null),\r\n value: props.value ?? props.defaultValue,\r\n defaultValue: undefined, // Don't pass defaultValue to children as there is no guarantee how this will be used and we can't mix controlled + uncontrolled state\r\n })\r\n : children;\r\n\r\n return (\r\n <LineContainer ref={ref}>\r\n <div className={classes.baseLine}>\r\n <InfoLabel\r\n size={size}\r\n className={classes.infoLabel}\r\n label={{ className: classes.labelSlot }}\r\n info={description ? <div className={classes.infoPopup}>{description}</div> : undefined}\r\n title={label}\r\n >\r\n <Body1Strong className={classes.labelText}>{label}</Body1Strong>\r\n </InfoLabel>\r\n <div className={classes.rightContent}>\r\n {expandedContent && (\r\n <ToggleButton\r\n title=\"Expand/Collapse property\"\r\n appearance=\"transparent\"\r\n checkedIcon={size === \"small\" ? ChevronCircleDown16Regular : ChevronCircleDown20Regular}\r\n uncheckedIcon={size === \"small\" ? ChevronCircleRight16Regular : ChevronCircleRight20Regular}\r\n value={expanded === true}\r\n onChange={setExpanded}\r\n />\r\n )}\r\n\r\n {nullable && !ignoreNullable && (\r\n // If this is a nullableProperty and ignoreNullable was not sent, display a checkbox used to toggle null ('checked' means 'non null')\r\n <Checkbox\r\n checked={!(props.value == null)}\r\n onChange={(_, data) => {\r\n if (data.checked) {\r\n // if checked this means we are returning to non-null, use cached value if exists. If no cached value, use default value\r\n cachedVal.current != null ? props.onChange(cachedVal.current) : props.onChange(props.defaultValue);\r\n } else {\r\n // if moving to un-checked state, this means moving to null value. Cache the old value and tell props.onChange(null)\r\n cachedVal.current = props.value;\r\n props.onChange(null);\r\n }\r\n }}\r\n title=\"Toggle null state\"\r\n />\r\n )}\r\n {processedChildren}\r\n {onCopy && !disableCopy && (\r\n <Button\r\n className={classes.copy}\r\n title=\"Copy to clipboard\"\r\n appearance=\"transparent\"\r\n icon={size === \"small\" ? Copy16Regular : Copy20Regular}\r\n onClick={() => copyCommandToClipboard(onCopy())}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n {expandedContent && (\r\n <Collapse visible={!!expanded}>\r\n <div className={classes.expandedContentDiv}>{expandedContent}</div>\r\n </Collapse>\r\n )}\r\n </LineContainer>\r\n );\r\n});\r\n\r\nconst useLineStyles = makeStyles({\r\n container: {\r\n width: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"column\", // Stack line + expanded content\r\n minHeight: CustomTokens.lineHeight,\r\n boxSizing: \"border-box\",\r\n justifyContent: \"center\",\r\n paddingTop: tokens.spacingVerticalXXS,\r\n paddingBottom: tokens.spacingVerticalXXS,\r\n },\r\n containerSmall: {\r\n minHeight: CustomTokens.lineHeightSmall,\r\n },\r\n});\r\n\r\nexport const LineContainer = forwardRef<HTMLDivElement, PropsWithChildren<HTMLProps<HTMLDivElement>>>((props, ref) => {\r\n const { size } = useContext(ToolContext);\r\n const classes = useLineStyles();\r\n\r\n return (\r\n <div ref={ref} className={mergeClasses(classes.container, size == \"small\" ? classes.containerSmall : undefined)} {...props}>\r\n {props.children}\r\n </div>\r\n );\r\n});\r\n\r\nexport const PlaceholderPropertyLine: FunctionComponent<PrimitiveProps<any> & PropertyLineProps<any>> = (props) => {\r\n return (\r\n <PropertyLine {...props}>\r\n <Body1>{props.value}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"propertyLine.js","sourceRoot":"","sources":["../../../../../../dev/sharedUiComponents/src/fluent/hoc/propertyLines/propertyLine.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Body1, InfoLabel, Checkbox, makeStyles, Body1Strong, tokens, mergeClasses } from \"@fluentui/react-components\";\r\nimport {\r\n ChevronCircleDown20Regular,\r\n ChevronCircleDown16Regular,\r\n ChevronCircleRight16Regular,\r\n ChevronCircleRight20Regular,\r\n Copy16Regular,\r\n Copy20Regular,\r\n} from \"@fluentui/react-icons\";\r\nimport type { FunctionComponent, HTMLProps, PropsWithChildren } from \"react\";\r\nimport { useContext, useState, forwardRef, cloneElement, isValidElement, useRef } from \"react\";\r\nimport { Collapse } from \"../../primitives/collapse\";\r\nimport { copyCommandToClipboard } from \"../../../copyCommandToClipboard\";\r\nimport { ToolContext } from \"../fluentToolWrapper\";\r\nimport type { PrimitiveProps } from \"../../primitives/primitive\";\r\nimport { Link } from \"../../primitives/link\";\r\nimport { ToggleButton } from \"../../primitives/toggleButton\";\r\nimport { Button } from \"../../primitives/button\";\r\nimport { CustomTokens } from \"../../primitives/utils\";\r\n\r\nconst usePropertyLineStyles = makeStyles({\r\n baseLine: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-start\",\r\n width: \"100%\",\r\n },\r\n infoLabel: {\r\n display: \"flex\",\r\n flex: \"1 1 0\", // grow=1, shrink =1, basis = 0 initial size before\r\n minWidth: CustomTokens.labelMinWidth,\r\n textAlign: \"left\",\r\n },\r\n labelSlot: {\r\n display: \"flex\",\r\n minWidth: 0,\r\n },\r\n labelText: {\r\n whiteSpace: \"nowrap\",\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n },\r\n rightContent: {\r\n flex: \"0 1 auto\",\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-end\",\r\n },\r\n childWrapper: {\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n },\r\n infoPopup: {\r\n whiteSpace: \"normal\",\r\n wordBreak: \"break-word\",\r\n },\r\n copy: {\r\n marginRight: CustomTokens.rightAlignOffset, // Accounts for the padding baked into fluent button / ensures propertyLine looks visually aligned at the right\r\n },\r\n expandedContentDiv: {\r\n overflow: \"hidden\",\r\n },\r\n});\r\n\r\ntype BasePropertyLineProps = {\r\n /**\r\n * The name of the property to display in the property line.\r\n */\r\n label: string;\r\n /**\r\n * Optional description for the property, shown on hover of the info icon\r\n */\r\n description?: string;\r\n /**\r\n * Optional function returning a string to copy to clipboard.\r\n */\r\n onCopy?: () => string;\r\n /**\r\n * Link to the documentation for this property, available from the info icon either linked from the description (if provided) or default 'docs' text\r\n */\r\n docLink?: string;\r\n};\r\n\r\n// Only require value/onChange/defaultValue props if nullable is true\r\ntype NullableProperty<ValueT> = {\r\n nullable: true;\r\n ignoreNullable: false;\r\n value: ValueT;\r\n onChange: (value: ValueT) => void;\r\n defaultValue?: ValueT;\r\n};\r\n\r\ntype IgnoreNullable<ValueT> = {\r\n ignoreNullable: true;\r\n nullable: false;\r\n value: ValueT;\r\n onChange: (value: ValueT) => void;\r\n defaultValue: ValueT;\r\n};\r\n\r\ntype NonNullableProperty = {\r\n nullable?: false;\r\n ignoreNullable?: false;\r\n};\r\n\r\n// Only expect optional expandByDefault prop if expandedContent is defined\r\ntype ExpandableProperty = {\r\n /**\r\n * If supplied, an 'expand' icon will be shown which, when clicked, renders this component within the property line.\r\n */\r\n expandedContent: JSX.Element;\r\n\r\n /**\r\n * If true, the expanded content will be shown by default.\r\n */\r\n expandByDefault?: boolean;\r\n};\r\n\r\n// If expanded content is undefined, don't expect expandByDefault prop\r\ntype NonExpandableProperty = {\r\n expandedContent?: undefined;\r\n};\r\n\r\nexport type PropertyLineProps<ValueT> = BasePropertyLineProps &\r\n (NullableProperty<ValueT> | NonNullableProperty | IgnoreNullable<ValueT>) &\r\n (ExpandableProperty | NonExpandableProperty);\r\n\r\n/**\r\n * A reusable component that renders a property line with a label and child content, and an optional description, copy button, and expandable section.\r\n *\r\n * @param props - The properties for the PropertyLine component.\r\n * @returns A React element representing the property line.\r\n *\r\n */\r\nexport const PropertyLine = forwardRef<HTMLDivElement, PropsWithChildren<PropertyLineProps<any>>>((props, ref) => {\r\n PropertyLine.displayName = \"PropertyLine\";\r\n const { disableCopy, size } = useContext(ToolContext);\r\n const classes = usePropertyLineStyles();\r\n const { label, onCopy, expandedContent, children, nullable, ignoreNullable } = props;\r\n\r\n const [expanded, setExpanded] = useState(\"expandByDefault\" in props ? props.expandByDefault : false);\r\n const cachedVal = useRef(nullable ? props.value : null);\r\n\r\n const description = props.docLink ? <Link url={props.docLink} value={props.description ?? \"Docs\"} /> : props.description;\r\n\r\n // Process children to handle nullable state -- creating component in disabled state with default value in lieu of null value\r\n const processedChildren =\r\n (nullable || ignoreNullable) && isValidElement(children)\r\n ? cloneElement(children, {\r\n ...children.props,\r\n disabled: children.props.disabled || (nullable && props.value == null),\r\n value: props.value ?? props.defaultValue,\r\n defaultValue: undefined, // Don't pass defaultValue to children as there is no guarantee how this will be used and we can't mix controlled + uncontrolled state\r\n })\r\n : children;\r\n\r\n return (\r\n <LineContainer ref={ref}>\r\n <div className={classes.baseLine}>\r\n <InfoLabel\r\n size={size}\r\n className={classes.infoLabel}\r\n label={{ className: classes.labelSlot }}\r\n info={description ? <div className={classes.infoPopup}>{description}</div> : undefined}\r\n title={label}\r\n >\r\n <Body1Strong className={classes.labelText}>{label}</Body1Strong>\r\n </InfoLabel>\r\n <div className={classes.rightContent}>\r\n {expandedContent && (\r\n <ToggleButton\r\n title=\"Expand/Collapse property\"\r\n appearance=\"transparent\"\r\n checkedIcon={size === \"small\" ? ChevronCircleDown16Regular : ChevronCircleDown20Regular}\r\n uncheckedIcon={size === \"small\" ? ChevronCircleRight16Regular : ChevronCircleRight20Regular}\r\n value={expanded === true}\r\n onChange={setExpanded}\r\n />\r\n )}\r\n\r\n {nullable && !ignoreNullable && (\r\n // If this is a nullableProperty and ignoreNullable was not sent, display a checkbox used to toggle null ('checked' means 'non null')\r\n <Checkbox\r\n checked={!(props.value == null)}\r\n onChange={(_, data) => {\r\n if (data.checked) {\r\n // if checked this means we are returning to non-null, use cached value if exists. If no cached value, use default value\r\n cachedVal.current != null ? props.onChange(cachedVal.current) : props.onChange(props.defaultValue);\r\n } else {\r\n // if moving to un-checked state, this means moving to null value. Cache the old value and tell props.onChange(null)\r\n cachedVal.current = props.value;\r\n props.onChange(null);\r\n }\r\n }}\r\n title=\"Toggle null state\"\r\n />\r\n )}\r\n <div className={classes.childWrapper}>{processedChildren}</div>\r\n {onCopy && !disableCopy && (\r\n <Button\r\n className={classes.copy}\r\n title=\"Copy to clipboard\"\r\n appearance=\"transparent\"\r\n icon={size === \"small\" ? Copy16Regular : Copy20Regular}\r\n onClick={() => copyCommandToClipboard(onCopy())}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n {expandedContent && (\r\n <Collapse visible={!!expanded}>\r\n <div className={classes.expandedContentDiv}>{expandedContent}</div>\r\n </Collapse>\r\n )}\r\n </LineContainer>\r\n );\r\n});\r\n\r\nconst useLineStyles = makeStyles({\r\n container: {\r\n width: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"column\", // Stack line + expanded content\r\n minHeight: CustomTokens.lineHeight,\r\n boxSizing: \"border-box\",\r\n justifyContent: \"center\",\r\n paddingTop: tokens.spacingVerticalXXS,\r\n paddingBottom: tokens.spacingVerticalXXS,\r\n },\r\n containerSmall: {\r\n minHeight: CustomTokens.lineHeightSmall,\r\n },\r\n});\r\n\r\nexport const LineContainer = forwardRef<HTMLDivElement, PropsWithChildren<HTMLProps<HTMLDivElement>>>((props, ref) => {\r\n const { size } = useContext(ToolContext);\r\n const classes = useLineStyles();\r\n\r\n return (\r\n <div ref={ref} className={mergeClasses(classes.container, size == \"small\" ? classes.containerSmall : undefined)} {...props}>\r\n {props.children}\r\n </div>\r\n );\r\n});\r\n\r\nexport const PlaceholderPropertyLine: FunctionComponent<PrimitiveProps<any> & PropertyLineProps<any>> = (props) => {\r\n return (\r\n <PropertyLine {...props}>\r\n <Body1>{props.value}</Body1>\r\n </PropertyLine>\r\n );\r\n};\r\n"]}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
import type { MouseEvent } from "react";
|
|
1
2
|
import type { FluentIcon } from "@fluentui/react-icons";
|
|
2
3
|
import type { BasePrimitiveProps } from "./primitive.js";
|
|
3
4
|
export type ButtonProps = BasePrimitiveProps & {
|
|
4
|
-
onClick?: () => void;
|
|
5
|
+
onClick?: (e?: MouseEvent<HTMLButtonElement>) => void;
|
|
5
6
|
icon?: FluentIcon;
|
|
6
7
|
appearance?: "subtle" | "transparent" | "primary";
|
|
7
8
|
label?: string;
|
|
8
9
|
};
|
|
9
10
|
export declare const Button: import("react").ForwardRefExoticComponent<BasePrimitiveProps & {
|
|
10
|
-
onClick?: () => void;
|
|
11
|
+
onClick?: (e?: MouseEvent<HTMLButtonElement>) => void;
|
|
11
12
|
icon?: FluentIcon;
|
|
12
13
|
appearance?: "subtle" | "transparent" | "primary";
|
|
13
14
|
label?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/button.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"button.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/button.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAG/C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AASvD,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAiC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IAC5E,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACzC,gEAAgE;IAChE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,WAAW,EAAE,GAAG,KAAK,CAAC;IACpD,OAAO,CACH,KAAC,YAAY,IAAC,GAAG,EAAE,GAAG,EAAE,YAAY,EAAC,OAAO,KAAK,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,KAAC,IAAI,KAAG,YAC3F,KAAK,IAAI,KAAK,CAAC,KAAK,GACV,CAClB,CAAC;AACN,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC","sourcesContent":["import { Button as FluentButton } from \"@fluentui/react-components\";\r\nimport type { MouseEvent } from \"react\";\r\nimport { forwardRef, useContext } from \"react\";\r\nimport type { FluentIcon } from \"@fluentui/react-icons\";\r\nimport type { BasePrimitiveProps } from \"./primitive\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\n\r\nexport type ButtonProps = BasePrimitiveProps & {\r\n onClick?: (e?: MouseEvent<HTMLButtonElement>) => void;\r\n icon?: FluentIcon;\r\n appearance?: \"subtle\" | \"transparent\" | \"primary\";\r\n label?: string;\r\n};\r\n\r\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {\r\n const { size } = useContext(ToolContext);\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n const { icon: Icon, label, ...buttonProps } = props;\r\n return (\r\n <FluentButton ref={ref} iconPosition=\"after\" {...buttonProps} size={size} icon={Icon && <Icon />}>\r\n {label && props.label}\r\n </FluentButton>\r\n );\r\n});\r\n\r\nButton.displayName = \"Button\";\r\n"]}
|
|
@@ -19,6 +19,11 @@ const useStyles = makeStyles({
|
|
|
19
19
|
input: {
|
|
20
20
|
minWidth: 0,
|
|
21
21
|
},
|
|
22
|
+
listbox: {
|
|
23
|
+
width: "fit-content",
|
|
24
|
+
minWidth: "fit-content",
|
|
25
|
+
maxWidth: "350px",
|
|
26
|
+
},
|
|
22
27
|
});
|
|
23
28
|
/**
|
|
24
29
|
* Wrapper around a Fluent ComboBox that allows for filtering options.
|
|
@@ -48,6 +53,6 @@ export const ComboBox = (props) => {
|
|
|
48
53
|
setQuery(data.optionText ?? "");
|
|
49
54
|
data.optionValue && props.onChange(data.optionValue);
|
|
50
55
|
};
|
|
51
|
-
return (_jsxs("div", { className: styles.root, children: [_jsx("label", { id: comboId, children: props.label }), _jsx(FluentComboBox, { size: size, root: { className: styles.comboBox }, input: { className: styles.input }, onOptionSelect: onOptionSelect, "aria-labelledby": comboId, placeholder: "Search..", onChange: (ev) => setQuery(ev.target.value), value: query, children: children })] }));
|
|
56
|
+
return (_jsxs("div", { className: styles.root, children: [_jsx("label", { id: comboId, children: props.label }), _jsx(FluentComboBox, { size: size, root: { className: styles.comboBox }, input: { className: styles.input }, listbox: { className: styles.listbox }, onOptionSelect: onOptionSelect, "aria-labelledby": comboId, placeholder: "Search..", onChange: (ev) => setQuery(ev.target.value), value: query, children: children })] }));
|
|
52
57
|
};
|
|
53
58
|
//# sourceMappingURL=comboBox.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comboBox.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/comboBox.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { FunctionComponent } from \"react\";\r\nimport { useState, useContext, useEffect } from \"react\";\r\nimport { Combobox as FluentComboBox, makeStyles, useComboboxFilter, useId, Option } from \"@fluentui/react-components\";\r\nimport type { OptionOnSelectData, SelectionEvents } from \"@fluentui/react-components\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\nimport { CustomTokens } from \"./utils\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\n\r\nconst useStyles = makeStyles({\r\n root: {\r\n display: \"grid\",\r\n gridTemplateRows: \"repeat(1fr)\",\r\n justifyItems: \"start\",\r\n gap: \"2px\",\r\n maxWidth: \"400px\",\r\n },\r\n comboBox: {\r\n width: CustomTokens.inputWidth,\r\n minWidth: CustomTokens.inputWidth,\r\n boxSizing: \"border-box\",\r\n },\r\n input: {\r\n minWidth: 0,\r\n },\r\n});\r\n\r\n/**\r\n * An option object for the ComboBox with separate label and value.\r\n */\r\nexport type ComboBoxOption = {\r\n /**\r\n * Defines the visible part of the option\r\n */\r\n label: string;\r\n /**\r\n * Defines the value part of the option\r\n */\r\n value: string;\r\n};\r\n\r\nexport type ComboBoxProps = PrimitiveProps<string> & {\r\n /**\r\n * Label for the ComboBox\r\n */\r\n label: string;\r\n /**\r\n * Options to display as label/value pairs\r\n */\r\n options: ComboBoxOption[];\r\n};\r\n\r\n/**\r\n * Wrapper around a Fluent ComboBox that allows for filtering options.\r\n * @param props\r\n * @returns\r\n */\r\nexport const ComboBox: FunctionComponent<ComboBoxProps> = (props) => {\r\n ComboBox.displayName = \"ComboBox\";\r\n const comboId = useId();\r\n const styles = useStyles();\r\n const { size } = useContext(ToolContext);\r\n\r\n // Find the label for the current value\r\n const getLabel = (value: string) => props.options.find((opt) => opt.value === value)?.label ?? \"\";\r\n\r\n const [query, setQuery] = useState(getLabel(props.value ?? \"\"));\r\n\r\n useEffect(() => {\r\n setQuery(getLabel(props.value ?? \"\"));\r\n }, [props.value, props.options]);\r\n\r\n // Convert to Fluent's { children, value } format\r\n const normalizedOptions = props.options.map((opt) => ({ children: opt.label, value: opt.value }));\r\n\r\n const children = useComboboxFilter(query, normalizedOptions, {\r\n noOptionsMessage: \"No items match your search.\",\r\n optionToReactKey: (option) => option.value,\r\n optionToText: (option) => option.children,\r\n renderOption: (option) => (\r\n <Option key={option.value} value={option.value} text={option.children}>\r\n {option.children}\r\n </Option>\r\n ),\r\n });\r\n\r\n const onOptionSelect = (_e: SelectionEvents, data: OptionOnSelectData) => {\r\n setQuery(data.optionText ?? \"\");\r\n data.optionValue && props.onChange(data.optionValue);\r\n };\r\n\r\n return (\r\n <div className={styles.root}>\r\n <label id={comboId}>{props.label}</label>\r\n <FluentComboBox\r\n size={size}\r\n root={{ className: styles.comboBox }}\r\n input={{ className: styles.input }}\r\n onOptionSelect={onOptionSelect}\r\n aria-labelledby={comboId}\r\n placeholder=\"Search..\"\r\n onChange={(ev) => setQuery(ev.target.value)}\r\n value={query}\r\n >\r\n {children}\r\n </FluentComboBox>\r\n </div>\r\n );\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"comboBox.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/comboBox.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACxD,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,UAAU,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEtH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,MAAM,SAAS,GAAG,UAAU,CAAC;IACzB,IAAI,EAAE;QACF,OAAO,EAAE,MAAM;QACf,gBAAgB,EAAE,aAAa;QAC/B,YAAY,EAAE,OAAO;QACrB,GAAG,EAAE,KAAK;QACV,QAAQ,EAAE,OAAO;KACpB;IACD,QAAQ,EAAE;QACN,KAAK,EAAE,YAAY,CAAC,UAAU;QAC9B,QAAQ,EAAE,YAAY,CAAC,UAAU;QACjC,SAAS,EAAE,YAAY;KAC1B;IACD,KAAK,EAAE;QACH,QAAQ,EAAE,CAAC;KACd;IACD,OAAO,EAAE;QACL,KAAK,EAAE,aAAa;QACpB,QAAQ,EAAE,aAAa;QACvB,QAAQ,EAAE,OAAO;KACpB;CACJ,CAAC,CAAC;AA2BH;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAqC,CAAC,KAAK,EAAE,EAAE;IAChE,QAAQ,CAAC,WAAW,GAAG,UAAU,CAAC;IAClC,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAEzC,uCAAuC;IACvC,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;IAElG,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;IAEhE,SAAS,CAAC,GAAG,EAAE;QACX,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAEjC,iDAAiD;IACjD,MAAM,iBAAiB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAElG,MAAM,QAAQ,GAAG,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,EAAE;QACzD,gBAAgB,EAAE,6BAA6B;QAC/C,gBAAgB,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK;QAC1C,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ;QACzC,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CACtB,KAAC,MAAM,IAAoB,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,YAChE,MAAM,CAAC,QAAQ,IADP,MAAM,CAAC,KAAK,CAEhB,CACZ;KACJ,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,CAAC,EAAmB,EAAE,IAAwB,EAAE,EAAE;QACrE,QAAQ,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzD,CAAC,CAAC;IAEF,OAAO,CACH,eAAK,SAAS,EAAE,MAAM,CAAC,IAAI,aACvB,gBAAO,EAAE,EAAE,OAAO,YAAG,KAAK,CAAC,KAAK,GAAS,EACzC,KAAC,cAAc,IACX,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,EACpC,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,EAClC,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,EACtC,cAAc,EAAE,cAAc,qBACb,OAAO,EACxB,WAAW,EAAC,UAAU,EACtB,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAC3C,KAAK,EAAE,KAAK,YAEX,QAAQ,GACI,IACf,CACT,CAAC;AACN,CAAC,CAAC","sourcesContent":["import type { FunctionComponent } from \"react\";\r\nimport { useState, useContext, useEffect } from \"react\";\r\nimport { Combobox as FluentComboBox, makeStyles, useComboboxFilter, useId, Option } from \"@fluentui/react-components\";\r\nimport type { OptionOnSelectData, SelectionEvents } from \"@fluentui/react-components\";\r\nimport { ToolContext } from \"../hoc/fluentToolWrapper\";\r\nimport { CustomTokens } from \"./utils\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\n\r\nconst useStyles = makeStyles({\r\n root: {\r\n display: \"grid\",\r\n gridTemplateRows: \"repeat(1fr)\",\r\n justifyItems: \"start\",\r\n gap: \"2px\",\r\n maxWidth: \"400px\",\r\n },\r\n comboBox: {\r\n width: CustomTokens.inputWidth,\r\n minWidth: CustomTokens.inputWidth,\r\n boxSizing: \"border-box\",\r\n },\r\n input: {\r\n minWidth: 0,\r\n },\r\n listbox: {\r\n width: \"fit-content\",\r\n minWidth: \"fit-content\",\r\n maxWidth: \"350px\",\r\n },\r\n});\r\n\r\n/**\r\n * An option object for the ComboBox with separate label and value.\r\n */\r\nexport type ComboBoxOption = {\r\n /**\r\n * Defines the visible part of the option\r\n */\r\n label: string;\r\n /**\r\n * Defines the value part of the option\r\n */\r\n value: string;\r\n};\r\n\r\nexport type ComboBoxProps = PrimitiveProps<string> & {\r\n /**\r\n * Label for the ComboBox\r\n */\r\n label: string;\r\n /**\r\n * Options to display as label/value pairs\r\n */\r\n options: ComboBoxOption[];\r\n};\r\n\r\n/**\r\n * Wrapper around a Fluent ComboBox that allows for filtering options.\r\n * @param props\r\n * @returns\r\n */\r\nexport const ComboBox: FunctionComponent<ComboBoxProps> = (props) => {\r\n ComboBox.displayName = \"ComboBox\";\r\n const comboId = useId();\r\n const styles = useStyles();\r\n const { size } = useContext(ToolContext);\r\n\r\n // Find the label for the current value\r\n const getLabel = (value: string) => props.options.find((opt) => opt.value === value)?.label ?? \"\";\r\n\r\n const [query, setQuery] = useState(getLabel(props.value ?? \"\"));\r\n\r\n useEffect(() => {\r\n setQuery(getLabel(props.value ?? \"\"));\r\n }, [props.value, props.options]);\r\n\r\n // Convert to Fluent's { children, value } format\r\n const normalizedOptions = props.options.map((opt) => ({ children: opt.label, value: opt.value }));\r\n\r\n const children = useComboboxFilter(query, normalizedOptions, {\r\n noOptionsMessage: \"No items match your search.\",\r\n optionToReactKey: (option) => option.value,\r\n optionToText: (option) => option.children,\r\n renderOption: (option) => (\r\n <Option key={option.value} value={option.value} text={option.children}>\r\n {option.children}\r\n </Option>\r\n ),\r\n });\r\n\r\n const onOptionSelect = (_e: SelectionEvents, data: OptionOnSelectData) => {\r\n setQuery(data.optionText ?? \"\");\r\n data.optionValue && props.onChange(data.optionValue);\r\n };\r\n\r\n return (\r\n <div className={styles.root}>\r\n <label id={comboId}>{props.label}</label>\r\n <FluentComboBox\r\n size={size}\r\n root={{ className: styles.comboBox }}\r\n input={{ className: styles.input }}\r\n listbox={{ className: styles.listbox }}\r\n onOptionSelect={onOptionSelect}\r\n aria-labelledby={comboId}\r\n placeholder=\"Search..\"\r\n onChange={(ev) => setQuery(ev.target.value)}\r\n value={query}\r\n >\r\n {children}\r\n </FluentComboBox>\r\n </div>\r\n );\r\n};\r\n"]}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { MenuProps as FluentMenuProps } from "@fluentui/react-components";
|
|
3
|
+
import type { FluentIcon } from "@fluentui/react-icons";
|
|
4
|
+
import type { BasePrimitiveProps } from "./primitive.js";
|
|
5
|
+
/**
|
|
6
|
+
* Represents a single menu item in the context menu.
|
|
7
|
+
*/
|
|
8
|
+
export type ContextMenuItemProps = {
|
|
9
|
+
/**
|
|
10
|
+
* Unique key for the menu item.
|
|
11
|
+
*/
|
|
12
|
+
key: string;
|
|
13
|
+
/**
|
|
14
|
+
* The text label displayed for the menu item.
|
|
15
|
+
*/
|
|
16
|
+
label: string;
|
|
17
|
+
/**
|
|
18
|
+
* Optional icon to display alongside the menu item.
|
|
19
|
+
*/
|
|
20
|
+
icon?: FluentIcon;
|
|
21
|
+
/**
|
|
22
|
+
* Called when the menu item is clicked.
|
|
23
|
+
*/
|
|
24
|
+
onClick?: () => void;
|
|
25
|
+
/**
|
|
26
|
+
* Whether the menu item is disabled.
|
|
27
|
+
*/
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Optional secondary text displayed alongside the label.
|
|
31
|
+
*/
|
|
32
|
+
secondaryContent?: string;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Represents a divider in the context menu.
|
|
36
|
+
*/
|
|
37
|
+
export type ContextMenuDividerProps = {
|
|
38
|
+
/**
|
|
39
|
+
* Unique key for the divider.
|
|
40
|
+
*/
|
|
41
|
+
key: string;
|
|
42
|
+
/**
|
|
43
|
+
* Indicates this is a divider item.
|
|
44
|
+
*/
|
|
45
|
+
type: "divider";
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Represents a group of menu items with an optional header.
|
|
49
|
+
*/
|
|
50
|
+
export type ContextMenuGroupProps = {
|
|
51
|
+
/**
|
|
52
|
+
* Unique key for the group.
|
|
53
|
+
*/
|
|
54
|
+
key: string;
|
|
55
|
+
/**
|
|
56
|
+
* Indicates this is a group item.
|
|
57
|
+
*/
|
|
58
|
+
type: "group";
|
|
59
|
+
/**
|
|
60
|
+
* Optional header text for the group.
|
|
61
|
+
*/
|
|
62
|
+
header?: string;
|
|
63
|
+
/**
|
|
64
|
+
* The menu items within the group.
|
|
65
|
+
*/
|
|
66
|
+
items: ContextMenuItem[];
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Union type representing all possible menu items.
|
|
70
|
+
*/
|
|
71
|
+
export type ContextMenuItem = ContextMenuItemProps | ContextMenuDividerProps | ContextMenuGroupProps;
|
|
72
|
+
type ContextMenuWithIconProps = {
|
|
73
|
+
/**
|
|
74
|
+
* Icon to use as the trigger button.
|
|
75
|
+
*/
|
|
76
|
+
icon: FluentIcon;
|
|
77
|
+
trigger?: never;
|
|
78
|
+
};
|
|
79
|
+
type ContextMenuWithTriggerProps = {
|
|
80
|
+
icon?: never;
|
|
81
|
+
/**
|
|
82
|
+
* Custom trigger element for opening the menu.
|
|
83
|
+
*/
|
|
84
|
+
trigger: ReactElement;
|
|
85
|
+
};
|
|
86
|
+
export type ContextMenuProps = BasePrimitiveProps & (ContextMenuWithIconProps | ContextMenuWithTriggerProps) & {
|
|
87
|
+
/**
|
|
88
|
+
* Array of menu items to display.
|
|
89
|
+
*/
|
|
90
|
+
items: ContextMenuItem[];
|
|
91
|
+
/**
|
|
92
|
+
* Positioning of the menu relative to the trigger.
|
|
93
|
+
*/
|
|
94
|
+
positioning?: FluentMenuProps["positioning"];
|
|
95
|
+
/**
|
|
96
|
+
* Called when the menu open state changes.
|
|
97
|
+
*/
|
|
98
|
+
onOpenChange?: (open: boolean) => void;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* A wrapper around Fluent UI's Menu component providing a simplified API for context menus.
|
|
102
|
+
* Supports menu items with icons, dividers, and grouped items.
|
|
103
|
+
*/
|
|
104
|
+
export declare const ContextMenu: import("react").ForwardRefExoticComponent<ContextMenuProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
105
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useState } from "react";
|
|
3
|
+
import { Menu, MenuTrigger, MenuPopover, MenuList, MenuItem, MenuDivider, MenuGroup, MenuGroupHeader, makeStyles, tokens } from "@fluentui/react-components";
|
|
4
|
+
import { Button } from "shared-ui-components/fluent/primitives/button";
|
|
5
|
+
const useStyles = makeStyles({
|
|
6
|
+
menuPopover: {
|
|
7
|
+
minWidth: "160px",
|
|
8
|
+
},
|
|
9
|
+
menuItem: {
|
|
10
|
+
cursor: "pointer",
|
|
11
|
+
},
|
|
12
|
+
menuItemIcon: {
|
|
13
|
+
color: tokens.colorNeutralForeground2,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
const IsDivider = (item) => {
|
|
17
|
+
return "type" in item && item.type === "divider";
|
|
18
|
+
};
|
|
19
|
+
const IsGroup = (item) => {
|
|
20
|
+
return "type" in item && item.type === "group";
|
|
21
|
+
};
|
|
22
|
+
const RenderMenuItem = (item, classes) => {
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
24
|
+
const Icon = item.icon;
|
|
25
|
+
return (_jsx(MenuItem, { className: classes.menuItem, icon: Icon ? _jsx(Icon, { className: classes.menuItemIcon }) : undefined, onClick: item.onClick, disabled: item.disabled, secondaryContent: item.secondaryContent, children: item.label }, item.key));
|
|
26
|
+
};
|
|
27
|
+
const RenderMenuItems = (items, classes) => {
|
|
28
|
+
return items.map((item) => {
|
|
29
|
+
if (IsDivider(item)) {
|
|
30
|
+
return _jsx(MenuDivider, {}, item.key);
|
|
31
|
+
}
|
|
32
|
+
if (IsGroup(item)) {
|
|
33
|
+
return (_jsxs(MenuGroup, { children: [item.header && _jsx(MenuGroupHeader, { children: item.header }), RenderMenuItems(item.items, classes)] }, item.key));
|
|
34
|
+
}
|
|
35
|
+
return RenderMenuItem(item, classes);
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* A wrapper around Fluent UI's Menu component providing a simplified API for context menus.
|
|
40
|
+
* Supports menu items with icons, dividers, and grouped items.
|
|
41
|
+
*/
|
|
42
|
+
export const ContextMenu = forwardRef((props, ref) => {
|
|
43
|
+
const { items, onOpenChange, disabled } = props;
|
|
44
|
+
const [open, setOpen] = useState(false);
|
|
45
|
+
const classes = useStyles();
|
|
46
|
+
const handleOpenChange = (_, data) => {
|
|
47
|
+
setOpen(data.open);
|
|
48
|
+
onOpenChange?.(data.open);
|
|
49
|
+
};
|
|
50
|
+
return (_jsxs(Menu, { openOnContext: true, open: open, onOpenChange: handleOpenChange, children: [_jsx(MenuTrigger, { disableButtonEnhancement: true, children: props.trigger ?? (_jsx(Button, { ref: ref, icon: props.icon, onClick: (e) => {
|
|
51
|
+
e?.stopPropagation();
|
|
52
|
+
setOpen(true);
|
|
53
|
+
}, disabled: disabled })) }), _jsx(MenuPopover, { className: classes.menuPopover, children: _jsx(MenuList, { children: RenderMenuItems(items, classes) }) })] }));
|
|
54
|
+
});
|
|
55
|
+
ContextMenu.displayName = "ContextMenu";
|
|
56
|
+
//# sourceMappingURL=contextMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contextMenu.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/contextMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { ReactElement, ReactNode } from \"react\";\r\nimport { forwardRef, useState } from \"react\";\r\nimport { Menu, MenuTrigger, MenuPopover, MenuList, MenuItem, MenuDivider, MenuGroup, MenuGroupHeader, makeStyles, tokens } from \"@fluentui/react-components\";\r\nimport type { MenuProps as FluentMenuProps } from \"@fluentui/react-components\";\r\nimport type { FluentIcon } from \"@fluentui/react-icons\";\r\nimport { Button } from \"shared-ui-components/fluent/primitives/button\";\r\nimport type { BasePrimitiveProps } from \"./primitive\";\r\n\r\nconst useStyles = makeStyles({\r\n menuPopover: {\r\n minWidth: \"160px\",\r\n },\r\n menuItem: {\r\n cursor: \"pointer\",\r\n },\r\n menuItemIcon: {\r\n color: tokens.colorNeutralForeground2,\r\n },\r\n});\r\n\r\n/**\r\n * Represents a single menu item in the context menu.\r\n */\r\nexport type ContextMenuItemProps = {\r\n /**\r\n * Unique key for the menu item.\r\n */\r\n key: string;\r\n /**\r\n * The text label displayed for the menu item.\r\n */\r\n label: string;\r\n /**\r\n * Optional icon to display alongside the menu item.\r\n */\r\n icon?: FluentIcon;\r\n /**\r\n * Called when the menu item is clicked.\r\n */\r\n onClick?: () => void;\r\n /**\r\n * Whether the menu item is disabled.\r\n */\r\n disabled?: boolean;\r\n /**\r\n * Optional secondary text displayed alongside the label.\r\n */\r\n secondaryContent?: string;\r\n};\r\n\r\n/**\r\n * Represents a divider in the context menu.\r\n */\r\nexport type ContextMenuDividerProps = {\r\n /**\r\n * Unique key for the divider.\r\n */\r\n key: string;\r\n /**\r\n * Indicates this is a divider item.\r\n */\r\n type: \"divider\";\r\n};\r\n\r\n/**\r\n * Represents a group of menu items with an optional header.\r\n */\r\nexport type ContextMenuGroupProps = {\r\n /**\r\n * Unique key for the group.\r\n */\r\n key: string;\r\n /**\r\n * Indicates this is a group item.\r\n */\r\n type: \"group\";\r\n /**\r\n * Optional header text for the group.\r\n */\r\n header?: string;\r\n /**\r\n * The menu items within the group.\r\n */\r\n items: ContextMenuItem[];\r\n};\r\n\r\n/**\r\n * Union type representing all possible menu items.\r\n */\r\nexport type ContextMenuItem = ContextMenuItemProps | ContextMenuDividerProps | ContextMenuGroupProps;\r\n\r\ntype ContextMenuWithIconProps = {\r\n /**\r\n * Icon to use as the trigger button.\r\n */\r\n icon: FluentIcon;\r\n trigger?: never;\r\n};\r\n\r\ntype ContextMenuWithTriggerProps = {\r\n icon?: never;\r\n /**\r\n * Custom trigger element for opening the menu.\r\n */\r\n trigger: ReactElement;\r\n};\r\n\r\nexport type ContextMenuProps = BasePrimitiveProps &\r\n (ContextMenuWithIconProps | ContextMenuWithTriggerProps) & {\r\n /**\r\n * Array of menu items to display.\r\n */\r\n items: ContextMenuItem[];\r\n /**\r\n * Positioning of the menu relative to the trigger.\r\n */\r\n positioning?: FluentMenuProps[\"positioning\"];\r\n /**\r\n * Called when the menu open state changes.\r\n */\r\n onOpenChange?: (open: boolean) => void;\r\n };\r\n\r\nconst IsDivider = (item: ContextMenuItem): item is ContextMenuDividerProps => {\r\n return \"type\" in item && item.type === \"divider\";\r\n};\r\n\r\nconst IsGroup = (item: ContextMenuItem): item is ContextMenuGroupProps => {\r\n return \"type\" in item && item.type === \"group\";\r\n};\r\n\r\nconst RenderMenuItem = (item: ContextMenuItemProps, classes: ReturnType<typeof useStyles>) => {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n const Icon = item.icon;\r\n return (\r\n <MenuItem\r\n key={item.key}\r\n className={classes.menuItem}\r\n icon={Icon ? <Icon className={classes.menuItemIcon} /> : undefined}\r\n onClick={item.onClick}\r\n disabled={item.disabled}\r\n secondaryContent={item.secondaryContent}\r\n >\r\n {item.label}\r\n </MenuItem>\r\n );\r\n};\r\n\r\nconst RenderMenuItems = (items: ContextMenuItem[], classes: ReturnType<typeof useStyles>): ReactNode[] => {\r\n return items.map((item) => {\r\n if (IsDivider(item)) {\r\n return <MenuDivider key={item.key} />;\r\n }\r\n\r\n if (IsGroup(item)) {\r\n return (\r\n <MenuGroup key={item.key}>\r\n {item.header && <MenuGroupHeader>{item.header}</MenuGroupHeader>}\r\n {RenderMenuItems(item.items, classes)}\r\n </MenuGroup>\r\n );\r\n }\r\n\r\n return RenderMenuItem(item, classes);\r\n });\r\n};\r\n\r\n/**\r\n * A wrapper around Fluent UI's Menu component providing a simplified API for context menus.\r\n * Supports menu items with icons, dividers, and grouped items.\r\n */\r\nexport const ContextMenu = forwardRef<HTMLButtonElement, ContextMenuProps>((props, ref) => {\r\n const { items, onOpenChange, disabled } = props;\r\n const [open, setOpen] = useState(false);\r\n const classes = useStyles();\r\n\r\n const handleOpenChange = (_: unknown, data: { open: boolean }) => {\r\n setOpen(data.open);\r\n onOpenChange?.(data.open);\r\n };\r\n\r\n return (\r\n <Menu openOnContext open={open} onOpenChange={handleOpenChange}>\r\n <MenuTrigger disableButtonEnhancement>\r\n {props.trigger ?? (\r\n <Button\r\n ref={ref}\r\n icon={props.icon}\r\n onClick={(e) => {\r\n e?.stopPropagation();\r\n setOpen(true);\r\n }}\r\n disabled={disabled}\r\n />\r\n )}\r\n </MenuTrigger>\r\n <MenuPopover className={classes.menuPopover}>\r\n <MenuList>{RenderMenuItems(items, classes)}</MenuList>\r\n </MenuPopover>\r\n </Menu>\r\n );\r\n});\r\n\r\nContextMenu.displayName = \"ContextMenu\";\r\n"]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { Nullable } from "@babylonjs/core/types.js";
|
|
2
|
-
import type { PrimitiveProps } from "./primitive.js";
|
|
2
|
+
import type { ImmutablePrimitiveProps, PrimitiveProps } from "./primitive.js";
|
|
3
3
|
type Entity = {
|
|
4
4
|
uniqueId: number;
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
7
7
|
* Props for the EntitySelector component
|
|
8
8
|
*/
|
|
9
|
-
export type EntitySelectorProps<T extends Entity> = PrimitiveProps<Nullable<T>> & {
|
|
9
|
+
export type EntitySelectorProps<T extends Entity> = (PrimitiveProps<Nullable<T>> | ImmutablePrimitiveProps<Nullable<T>>) & {
|
|
10
10
|
/**
|
|
11
11
|
* Function to get the list of entities to choose from
|
|
12
12
|
*/
|
|
@@ -19,6 +19,14 @@ export type EntitySelectorProps<T extends Entity> = PrimitiveProps<Nullable<T>>
|
|
|
19
19
|
* Optional filter function to filter which entities are shown
|
|
20
20
|
*/
|
|
21
21
|
filter?: (entity: T) => boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Callback when the entity link is clicked
|
|
24
|
+
*/
|
|
25
|
+
onLink: (entity: T) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Optional default value that enables clearing the current linked entity
|
|
28
|
+
*/
|
|
29
|
+
defaultValue?: T;
|
|
22
30
|
};
|
|
23
31
|
/**
|
|
24
32
|
* A generic primitive component with a ComboBox for selecting from a list of entities.
|
|
@@ -1,6 +1,26 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo } from "react";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useState } from "react";
|
|
3
|
+
import { LinkDismissRegular, LinkEditRegular } from "@fluentui/react-icons";
|
|
3
4
|
import { ComboBox } from "./comboBox.js";
|
|
5
|
+
import { Link } from "./link.js";
|
|
6
|
+
import { Button } from "./button.js";
|
|
7
|
+
import { makeStyles, tokens, Tooltip } from "@fluentui/react-components";
|
|
8
|
+
const useStyles = makeStyles({
|
|
9
|
+
linkDiv: {
|
|
10
|
+
display: "flex",
|
|
11
|
+
flexDirection: "row",
|
|
12
|
+
alignItems: "center",
|
|
13
|
+
gap: tokens.spacingHorizontalS,
|
|
14
|
+
minWidth: 0,
|
|
15
|
+
overflow: "hidden",
|
|
16
|
+
},
|
|
17
|
+
link: {
|
|
18
|
+
minWidth: 0,
|
|
19
|
+
overflow: "hidden",
|
|
20
|
+
textOverflow: "ellipsis",
|
|
21
|
+
whiteSpace: "nowrap",
|
|
22
|
+
},
|
|
23
|
+
});
|
|
4
24
|
/**
|
|
5
25
|
* A generic primitive component with a ComboBox for selecting from a list of entities.
|
|
6
26
|
* Supports entities with duplicate names by using uniqueId for identity.
|
|
@@ -8,7 +28,9 @@ import { ComboBox } from "./comboBox.js";
|
|
|
8
28
|
* @returns EntitySelector component
|
|
9
29
|
*/
|
|
10
30
|
export function EntitySelector(props) {
|
|
11
|
-
const { value,
|
|
31
|
+
const { value, onLink, getEntities, getName, filter, defaultValue } = props;
|
|
32
|
+
const onChange = props.onChange;
|
|
33
|
+
const classes = useStyles();
|
|
12
34
|
// Build options with uniqueId as key
|
|
13
35
|
const options = useMemo(() => {
|
|
14
36
|
return getEntities()
|
|
@@ -19,13 +41,27 @@ export function EntitySelector(props) {
|
|
|
19
41
|
}))
|
|
20
42
|
.sort((a, b) => a.label.localeCompare(b.label));
|
|
21
43
|
}, [getEntities, getName, filter]);
|
|
44
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
22
45
|
const handleEntitySelect = (key) => {
|
|
23
46
|
const entity = getEntities().find((e) => e.uniqueId.toString() === key);
|
|
24
|
-
onChange(entity ?? null);
|
|
47
|
+
onChange?.(entity ?? null);
|
|
48
|
+
setIsEditing(false);
|
|
25
49
|
};
|
|
26
50
|
// Get current entity key for display
|
|
27
51
|
const currentKey = value ? value.uniqueId.toString() : "";
|
|
28
|
-
|
|
52
|
+
if (value && !isEditing) {
|
|
53
|
+
// If there is a value and we are not editing, show the link view
|
|
54
|
+
return (_jsxs("div", { className: classes.linkDiv, children: [_jsx(Tooltip, { content: getName(value), relationship: "label", children: _jsx(Link, { className: classes.link, value: getName(value), onLink: () => onLink(value) }) }), onChange &&
|
|
55
|
+
(defaultValue !== undefined ? (
|
|
56
|
+
// If the defaultValue is specified, then allow resetting to the default
|
|
57
|
+
_jsx(Button, { icon: LinkDismissRegular, onClick: () => onChange(defaultValue) })) : (
|
|
58
|
+
// Otherwise, just allow editing to a new value
|
|
59
|
+
_jsx(Button, { icon: LinkEditRegular, onClick: () => setIsEditing(true) })))] }));
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
// Otherwise, show the ComboBox for selection
|
|
63
|
+
return _jsx(ComboBox, { label: "", options: options, value: currentKey, onChange: handleEntitySelect });
|
|
64
|
+
}
|
|
29
65
|
}
|
|
30
66
|
EntitySelector.displayName = "EntitySelector";
|
|
31
67
|
//# sourceMappingURL=entitySelector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entitySelector.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/entitySelector.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"entitySelector.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/entitySelector.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { Nullable } from \"core/types\";\r\nimport type { ImmutablePrimitiveProps, PrimitiveProps } from \"./primitive\";\r\n\r\nimport { useMemo, useState } from \"react\";\r\nimport { LinkDismissRegular, LinkEditRegular } from \"@fluentui/react-icons\";\r\nimport { ComboBox } from \"./comboBox\";\r\nimport { Link } from \"./link\";\r\nimport { Button } from \"./button\";\r\nimport { makeStyles, tokens, Tooltip } from \"@fluentui/react-components\";\r\n\r\ntype Entity = { uniqueId: number };\r\n\r\n/**\r\n * Props for the EntitySelector component\r\n */\r\nexport type EntitySelectorProps<T extends Entity> = (PrimitiveProps<Nullable<T>> | ImmutablePrimitiveProps<Nullable<T>>) & {\r\n /**\r\n * Function to get the list of entities to choose from\r\n */\r\n getEntities: () => T[];\r\n /**\r\n * Function to get the display name from an entity\r\n */\r\n getName: (entity: T) => string;\r\n /**\r\n * Optional filter function to filter which entities are shown\r\n */\r\n filter?: (entity: T) => boolean;\r\n /**\r\n * Callback when the entity link is clicked\r\n */\r\n onLink: (entity: T) => void;\r\n /**\r\n * Optional default value that enables clearing the current linked entity\r\n */\r\n defaultValue?: T;\r\n};\r\n\r\nconst useStyles = makeStyles({\r\n linkDiv: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n alignItems: \"center\",\r\n gap: tokens.spacingHorizontalS,\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n },\r\n link: {\r\n minWidth: 0,\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n },\r\n});\r\n\r\n/**\r\n * A generic primitive component with a ComboBox for selecting from a list of entities.\r\n * Supports entities with duplicate names by using uniqueId for identity.\r\n * @param props ChooseEntityProps\r\n * @returns EntitySelector component\r\n */\r\nexport function EntitySelector<T extends Entity>(props: EntitySelectorProps<T>): JSX.Element {\r\n const { value, onLink, getEntities, getName, filter, defaultValue } = props;\r\n\r\n const onChange = (props as PrimitiveProps<Nullable<T>>).onChange as PrimitiveProps<Nullable<T>>[\"onChange\"] | undefined;\r\n\r\n const classes = useStyles();\r\n\r\n // Build options with uniqueId as key\r\n const options = useMemo(() => {\r\n return getEntities()\r\n .filter((e) => e.uniqueId !== undefined && (!filter || filter(e)))\r\n .map((entity) => ({\r\n label: getName(entity),\r\n value: entity.uniqueId.toString(),\r\n }))\r\n .sort((a, b) => a.label.localeCompare(b.label));\r\n }, [getEntities, getName, filter]);\r\n\r\n const [isEditing, setIsEditing] = useState(false);\r\n\r\n const handleEntitySelect = (key: string) => {\r\n const entity = getEntities().find((e) => e.uniqueId.toString() === key);\r\n onChange?.(entity ?? null);\r\n setIsEditing(false);\r\n };\r\n\r\n // Get current entity key for display\r\n const currentKey = value ? value.uniqueId.toString() : \"\";\r\n\r\n if (value && !isEditing) {\r\n // If there is a value and we are not editing, show the link view\r\n return (\r\n <div className={classes.linkDiv}>\r\n <Tooltip content={getName(value)} relationship=\"label\">\r\n <Link className={classes.link} value={getName(value)} onLink={() => onLink(value)} />\r\n </Tooltip>\r\n {/* Only allow changing the linked entity if an onChange handler is provided */}\r\n {onChange &&\r\n (defaultValue !== undefined ? (\r\n // If the defaultValue is specified, then allow resetting to the default\r\n <Button icon={LinkDismissRegular} onClick={() => onChange(defaultValue)} />\r\n ) : (\r\n // Otherwise, just allow editing to a new value\r\n <Button icon={LinkEditRegular} onClick={() => setIsEditing(true)} />\r\n ))}\r\n </div>\r\n );\r\n } else {\r\n // Otherwise, show the ComboBox for selection\r\n return <ComboBox label=\"\" options={options} value={currentKey} onChange={handleEntitySelect} />;\r\n }\r\n}\r\nEntitySelector.displayName = \"EntitySelector\";\r\n"]}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { FunctionComponent, PropsWithChildren } from "react";
|
|
2
1
|
import type { ImmutablePrimitiveProps } from "./primitive.js";
|
|
3
2
|
export type LinkProps = ImmutablePrimitiveProps<string> & {
|
|
4
3
|
/**
|
|
@@ -14,4 +13,22 @@ export type LinkProps = ImmutablePrimitiveProps<string> & {
|
|
|
14
13
|
*/
|
|
15
14
|
target?: "current" | "new";
|
|
16
15
|
};
|
|
17
|
-
export declare const Link:
|
|
16
|
+
export declare const Link: import("react").ForwardRefExoticComponent<import("./primitive.js").BasePrimitiveProps & {
|
|
17
|
+
value: string;
|
|
18
|
+
infoLabel?: import("./infoLabel.js").InfoLabelParentProps;
|
|
19
|
+
} & {
|
|
20
|
+
/**
|
|
21
|
+
* Used if you want to handle the link click yourself
|
|
22
|
+
*/
|
|
23
|
+
onLink?: () => void;
|
|
24
|
+
/**
|
|
25
|
+
* The URL the link points to
|
|
26
|
+
*/
|
|
27
|
+
url?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Defines whether to open the link in current tab or new tab. Default is new
|
|
30
|
+
*/
|
|
31
|
+
target?: "current" | "new";
|
|
32
|
+
} & {
|
|
33
|
+
children?: import("react").ReactNode | undefined;
|
|
34
|
+
} & import("react").RefAttributes<HTMLAnchorElement>>;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
2
3
|
import { Body1, Link as FluentLink } from "@fluentui/react-components";
|
|
3
|
-
export const Link = (props) => {
|
|
4
|
+
export const Link = forwardRef((props, ref) => {
|
|
4
5
|
const { target, url, onLink, ...rest } = props;
|
|
5
|
-
return (_jsxs(FluentLink, { inline: true, target: target === "current" ? "_self" : "_blank", rel: "noopener noreferrer", href: url, onClick: onLink ?? undefined, ...rest, children: [props.children, _jsx(Body1, { children: props.value })] }));
|
|
6
|
-
};
|
|
6
|
+
return (_jsxs(FluentLink, { ref: ref, inline: true, target: target === "current" ? "_self" : "_blank", rel: "noopener noreferrer", href: url, onClick: onLink ?? undefined, ...rest, children: [props.children, _jsx(Body1, { wrap: false, truncate: true, children: props.value })] }));
|
|
7
|
+
});
|
|
8
|
+
Link.displayName = "Link";
|
|
7
9
|
//# sourceMappingURL=link.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/link.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"link.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/link.tsx"],"names":[],"mappings":";AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAiBvE,MAAM,CAAC,MAAM,IAAI,GAAG,UAAU,CAAkD,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IAC3F,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IAC/C,OAAO,CACH,MAAC,UAAU,IAAC,GAAG,EAAE,GAAG,EAAE,MAAM,QAAC,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAC,qBAAqB,EAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,IAAI,SAAS,KAAM,IAAI,aACtJ,KAAK,CAAC,QAAQ,EACf,KAAC,KAAK,IAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,kBACvB,KAAK,CAAC,KAAK,GACR,IACC,CAChB,CAAC;AACN,CAAC,CAAC,CAAC;AACH,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC","sourcesContent":["import type { PropsWithChildren } from \"react\";\r\n\r\nimport type { ImmutablePrimitiveProps } from \"./primitive\";\r\n\r\nimport { forwardRef } from \"react\";\r\nimport { Body1, Link as FluentLink } from \"@fluentui/react-components\";\r\n\r\nexport type LinkProps = ImmutablePrimitiveProps<string> & {\r\n /**\r\n * Used if you want to handle the link click yourself\r\n */\r\n onLink?: () => void;\r\n /**\r\n * The URL the link points to\r\n */\r\n url?: string;\r\n /**\r\n * Defines whether to open the link in current tab or new tab. Default is new\r\n */\r\n target?: \"current\" | \"new\";\r\n};\r\n\r\nexport const Link = forwardRef<HTMLAnchorElement, PropsWithChildren<LinkProps>>((props, ref) => {\r\n const { target, url, onLink, ...rest } = props;\r\n return (\r\n <FluentLink ref={ref} inline target={target === \"current\" ? \"_self\" : \"_blank\"} rel=\"noopener noreferrer\" href={url} onClick={onLink ?? undefined} {...rest}>\r\n {props.children}\r\n <Body1 wrap={false} truncate>\r\n {props.value}\r\n </Body1>\r\n </FluentLink>\r\n );\r\n});\r\nLink.displayName = \"Link\";\r\n"]}
|
|
@@ -3,6 +3,7 @@ import type { Scene } from "@babylonjs/core/scene.js";
|
|
|
3
3
|
import type { Nullable } from "@babylonjs/core/types.js";
|
|
4
4
|
import type { Material } from "@babylonjs/core/Materials/material.js";
|
|
5
5
|
import type { PrimitiveProps } from "./primitive.js";
|
|
6
|
+
import type { EntitySelectorProps } from "./entitySelector.js";
|
|
6
7
|
export type MaterialSelectorProps = PrimitiveProps<Nullable<Material>> & {
|
|
7
8
|
/**
|
|
8
9
|
* The scene to get materials from
|
|
@@ -12,7 +13,7 @@ export type MaterialSelectorProps = PrimitiveProps<Nullable<Material>> & {
|
|
|
12
13
|
* Optional filter function to filter which materials are shown
|
|
13
14
|
*/
|
|
14
15
|
filter?: (material: Material) => boolean;
|
|
15
|
-
}
|
|
16
|
+
} & Omit<EntitySelectorProps<Material>, "getEntities" | "getName">;
|
|
16
17
|
/**
|
|
17
18
|
* A primitive component with a ComboBox for selecting from existing scene materials.
|
|
18
19
|
* @param props MaterialSelectorProps
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"materialSelector.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/materialSelector.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"materialSelector.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/materialSelector.tsx"],"names":[],"mappings":";AAOA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAalD;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAA6C,CAAC,KAAK,EAAE,EAAE;IAChF,gBAAgB,CAAC,WAAW,GAAG,kBAAkB,CAAC;IAClD,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IAEjC,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3E,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,QAAkB,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAEvE,OAAO,KAAC,cAAc,OAAK,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAI,CAAC;AACrF,CAAC,CAAC","sourcesContent":["import type { FunctionComponent } from \"react\";\r\nimport type { Scene } from \"core/scene\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport type { EntitySelectorProps } from \"./entitySelector\";\r\n\r\nimport { useCallback } from \"react\";\r\nimport { EntitySelector } from \"./entitySelector\";\r\n\r\nexport type MaterialSelectorProps = PrimitiveProps<Nullable<Material>> & {\r\n /**\r\n * The scene to get materials from\r\n */\r\n scene: Scene;\r\n /**\r\n * Optional filter function to filter which materials are shown\r\n */\r\n filter?: (material: Material) => boolean;\r\n} & Omit<EntitySelectorProps<Material>, \"getEntities\" | \"getName\">;\r\n\r\n/**\r\n * A primitive component with a ComboBox for selecting from existing scene materials.\r\n * @param props MaterialSelectorProps\r\n * @returns MaterialSelector component\r\n */\r\nexport const MaterialSelector: FunctionComponent<MaterialSelectorProps> = (props) => {\r\n MaterialSelector.displayName = \"MaterialSelector\";\r\n const { scene, ...rest } = props;\r\n\r\n const getMaterials = useCallback(() => scene.materials, [scene.materials]);\r\n const getName = useCallback((material: Material) => material.name, []);\r\n\r\n return <EntitySelector {...rest} getEntities={getMaterials} getName={getName} />;\r\n};\r\n"]}
|
|
@@ -3,6 +3,7 @@ import type { Scene } from "@babylonjs/core/scene.js";
|
|
|
3
3
|
import type { Nullable } from "@babylonjs/core/types.js";
|
|
4
4
|
import type { Node } from "@babylonjs/core/node.js";
|
|
5
5
|
import type { PrimitiveProps } from "./primitive.js";
|
|
6
|
+
import type { EntitySelectorProps } from "./entitySelector.js";
|
|
6
7
|
export type NodeSelectorProps = PrimitiveProps<Nullable<Node>> & {
|
|
7
8
|
/**
|
|
8
9
|
* The scene to get nodes from
|
|
@@ -12,7 +13,7 @@ export type NodeSelectorProps = PrimitiveProps<Nullable<Node>> & {
|
|
|
12
13
|
* Optional filter function to filter which nodes are shown
|
|
13
14
|
*/
|
|
14
15
|
filter?: (node: Node) => boolean;
|
|
15
|
-
}
|
|
16
|
+
} & Omit<EntitySelectorProps<Node>, "getEntities" | "getName">;
|
|
16
17
|
/**
|
|
17
18
|
* A primitive component with a ComboBox for selecting from existing scene nodes.
|
|
18
19
|
* @param props NodeSelectorProps
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeSelector.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/nodeSelector.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"nodeSelector.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/nodeSelector.tsx"],"names":[],"mappings":";AAOA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAalD;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAyC,CAAC,KAAK,EAAE,EAAE;IACxE,YAAY,CAAC,WAAW,GAAG,cAAc,CAAC;IAC1C,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IAEjC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,IAAU,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAE3D,OAAO,KAAC,cAAc,OAAK,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAI,CAAC;AACjF,CAAC,CAAC","sourcesContent":["import type { FunctionComponent } from \"react\";\r\nimport type { Scene } from \"core/scene\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { Node } from \"core/node\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport type { EntitySelectorProps } from \"./entitySelector\";\r\n\r\nimport { useCallback } from \"react\";\r\nimport { EntitySelector } from \"./entitySelector\";\r\n\r\nexport type NodeSelectorProps = PrimitiveProps<Nullable<Node>> & {\r\n /**\r\n * The scene to get nodes from\r\n */\r\n scene: Scene;\r\n /**\r\n * Optional filter function to filter which nodes are shown\r\n */\r\n filter?: (node: Node) => boolean;\r\n} & Omit<EntitySelectorProps<Node>, \"getEntities\" | \"getName\">;\r\n\r\n/**\r\n * A primitive component with a ComboBox for selecting from existing scene nodes.\r\n * @param props NodeSelectorProps\r\n * @returns NodeSelector component\r\n */\r\nexport const NodeSelector: FunctionComponent<NodeSelectorProps> = (props) => {\r\n NodeSelector.displayName = \"NodeSelector\";\r\n const { scene, ...rest } = props;\r\n\r\n const getNodes = useCallback(() => scene.getNodes(), [scene]);\r\n const getName = useCallback((node: Node) => node.name, []);\r\n\r\n return <EntitySelector {...rest} getEntities={getNodes} getName={getName} />;\r\n};\r\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { FunctionComponent } from "react";
|
|
2
|
+
import type { Scene } from "@babylonjs/core/scene.js";
|
|
3
|
+
import type { Nullable } from "@babylonjs/core/types.js";
|
|
4
|
+
import type { Skeleton } from "@babylonjs/core/Bones/skeleton.js";
|
|
5
|
+
import type { PrimitiveProps } from "./primitive.js";
|
|
6
|
+
import type { EntitySelectorProps } from "./entitySelector.js";
|
|
7
|
+
export type SkeletonSelectorProps = PrimitiveProps<Nullable<Skeleton>> & {
|
|
8
|
+
/**
|
|
9
|
+
* The scene to get skeletons from
|
|
10
|
+
*/
|
|
11
|
+
scene: Scene;
|
|
12
|
+
/**
|
|
13
|
+
* Optional filter function to filter which skeletons are shown
|
|
14
|
+
*/
|
|
15
|
+
filter?: (skeleton: Skeleton) => boolean;
|
|
16
|
+
} & Omit<EntitySelectorProps<Skeleton>, "getEntities" | "getName">;
|
|
17
|
+
/**
|
|
18
|
+
* A primitive component with a ComboBox for selecting from existing scene skeletons.
|
|
19
|
+
* @param props SkeletonSelectorProps
|
|
20
|
+
* @returns SkeletonSelector component
|
|
21
|
+
*/
|
|
22
|
+
export declare const SkeletonSelector: FunctionComponent<SkeletonSelectorProps>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback } from "react";
|
|
3
|
+
import { EntitySelector } from "./entitySelector.js";
|
|
4
|
+
/**
|
|
5
|
+
* A primitive component with a ComboBox for selecting from existing scene skeletons.
|
|
6
|
+
* @param props SkeletonSelectorProps
|
|
7
|
+
* @returns SkeletonSelector component
|
|
8
|
+
*/
|
|
9
|
+
export const SkeletonSelector = (props) => {
|
|
10
|
+
SkeletonSelector.displayName = "SkeletonSelector";
|
|
11
|
+
const { scene, ...rest } = props;
|
|
12
|
+
const getSkeletons = useCallback(() => scene.skeletons, [scene.skeletons]);
|
|
13
|
+
const getName = useCallback((skeleton) => skeleton.name, []);
|
|
14
|
+
return _jsx(EntitySelector, { ...rest, getEntities: getSkeletons, getName: getName });
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=skeletonSelector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skeletonSelector.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/skeletonSelector.tsx"],"names":[],"mappings":";AAOA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAalD;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAA6C,CAAC,KAAK,EAAE,EAAE;IAChF,gBAAgB,CAAC,WAAW,GAAG,kBAAkB,CAAC;IAClD,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IAEjC,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3E,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,QAAkB,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAEvE,OAAO,KAAC,cAAc,OAAK,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAI,CAAC;AACrF,CAAC,CAAC","sourcesContent":["import type { FunctionComponent } from \"react\";\r\nimport type { Scene } from \"core/scene\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { Skeleton } from \"core/Bones/skeleton\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport type { EntitySelectorProps } from \"./entitySelector\";\r\n\r\nimport { useCallback } from \"react\";\r\nimport { EntitySelector } from \"./entitySelector\";\r\n\r\nexport type SkeletonSelectorProps = PrimitiveProps<Nullable<Skeleton>> & {\r\n /**\r\n * The scene to get skeletons from\r\n */\r\n scene: Scene;\r\n /**\r\n * Optional filter function to filter which skeletons are shown\r\n */\r\n filter?: (skeleton: Skeleton) => boolean;\r\n} & Omit<EntitySelectorProps<Skeleton>, \"getEntities\" | \"getName\">;\r\n\r\n/**\r\n * A primitive component with a ComboBox for selecting from existing scene skeletons.\r\n * @param props SkeletonSelectorProps\r\n * @returns SkeletonSelector component\r\n */\r\nexport const SkeletonSelector: FunctionComponent<SkeletonSelectorProps> = (props) => {\r\n SkeletonSelector.displayName = \"SkeletonSelector\";\r\n const { scene, ...rest } = props;\r\n\r\n const getSkeletons = useCallback(() => scene.skeletons, [scene.skeletons]);\r\n const getName = useCallback((skeleton: Skeleton) => skeleton.name, []);\r\n\r\n return <EntitySelector {...rest} getEntities={getSkeletons} getName={getName} />;\r\n};\r\n"]}
|
|
@@ -3,6 +3,7 @@ import type { Scene } from "@babylonjs/core/scene.js";
|
|
|
3
3
|
import type { Nullable } from "@babylonjs/core/types.js";
|
|
4
4
|
import type { FunctionComponent } from "react";
|
|
5
5
|
import type { PrimitiveProps } from "./primitive.js";
|
|
6
|
+
import type { EntitySelectorProps } from "./entitySelector.js";
|
|
6
7
|
export type TextureSelectorProps = PrimitiveProps<Nullable<BaseTexture>> & {
|
|
7
8
|
/**
|
|
8
9
|
* The scene to get textures from
|
|
@@ -16,7 +17,7 @@ export type TextureSelectorProps = PrimitiveProps<Nullable<BaseTexture>> & {
|
|
|
16
17
|
* Whether to only allow cube textures
|
|
17
18
|
*/
|
|
18
19
|
cubeOnly?: boolean;
|
|
19
|
-
}
|
|
20
|
+
} & Omit<EntitySelectorProps<BaseTexture>, "getEntities" | "getName">;
|
|
20
21
|
/**
|
|
21
22
|
* A primitive component with a ComboBox for selecting from existing scene textures
|
|
22
23
|
* and a button for uploading new texture files.
|
|
@@ -19,11 +19,11 @@ const useStyles = makeStyles({
|
|
|
19
19
|
*/
|
|
20
20
|
export const TextureSelector = (props) => {
|
|
21
21
|
TextureSelector.displayName = "TextureSelector";
|
|
22
|
-
const { scene, cubeOnly, value, onChange } = props;
|
|
22
|
+
const { scene, cubeOnly, value, onChange, onLink, defaultValue } = props;
|
|
23
23
|
const classes = useStyles();
|
|
24
24
|
const getTextures = useCallback(() => scene.textures, [scene.textures]);
|
|
25
|
-
const getName = useCallback((texture) => texture.displayName || texture.name
|
|
25
|
+
const getName = useCallback((texture) => texture.displayName || texture.name || `${texture.getClassName() || "Unnamed Texture"} (${texture.uniqueId})`, []);
|
|
26
26
|
const filter = useCallback((texture) => !cubeOnly || texture.isCube, [cubeOnly]);
|
|
27
|
-
return (_jsxs("div", { className: classes.container, children: [_jsx(EntitySelector, { value: value, onChange: onChange, getEntities: getTextures, getName: getName, filter: filter }), _jsx(TextureUpload, { scene: scene, onChange: onChange, cubeOnly: cubeOnly })] }));
|
|
27
|
+
return (_jsxs("div", { className: classes.container, children: [_jsx(EntitySelector, { value: value, onChange: onChange, onLink: onLink, defaultValue: defaultValue, getEntities: getTextures, getName: getName, filter: filter }), !value && _jsx(TextureUpload, { scene: scene, onChange: onChange, cubeOnly: cubeOnly })] }));
|
|
28
28
|
};
|
|
29
29
|
//# sourceMappingURL=textureSelector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textureSelector.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/textureSelector.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"textureSelector.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/fluent/primitives/textureSelector.tsx"],"names":[],"mappings":";AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,SAAS,GAAG,UAAU,CAAC;IACzB,SAAS,EAAE;QACP,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE,QAAQ;QACpB,GAAG,EAAE,MAAM,CAAC,kBAAkB;KACjC;CACJ,CAAC,CAAC;AAiBH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAA4C,CAAC,KAAK,EAAE,EAAE;IAC9E,eAAe,CAAC,WAAW,GAAG,iBAAiB,CAAC;IAChD,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;IACzE,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAE5B,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,OAAoB,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,YAAY,EAAE,IAAI,iBAAiB,KAAK,OAAO,CAAC,QAAQ,GAAG,EAAE,EAAE,CAAC,CAAC;IACzK,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,OAAoB,EAAE,EAAE,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE9F,OAAO,CACH,eAAK,SAAS,EAAE,OAAO,CAAC,SAAS,aAC7B,KAAC,cAAc,IAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAI,EAC3J,CAAC,KAAK,IAAI,KAAC,aAAa,IAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,GAAI,IAChF,CACT,CAAC;AACN,CAAC,CAAC","sourcesContent":["import type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { Scene } from \"core/scene\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { FunctionComponent } from \"react\";\r\nimport type { PrimitiveProps } from \"./primitive\";\r\nimport type { EntitySelectorProps } from \"./entitySelector\";\r\n\r\nimport { makeStyles, tokens } from \"@fluentui/react-components\";\r\nimport { useCallback } from \"react\";\r\nimport { TextureUpload } from \"../hoc/textureUpload\";\r\nimport { EntitySelector } from \"./entitySelector\";\r\n\r\nconst useStyles = makeStyles({\r\n container: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n alignItems: \"center\",\r\n gap: tokens.spacingHorizontalS,\r\n },\r\n});\r\n\r\nexport type TextureSelectorProps = PrimitiveProps<Nullable<BaseTexture>> & {\r\n /**\r\n * The scene to get textures from\r\n */\r\n scene: Scene;\r\n /**\r\n * File types to accept for upload\r\n */\r\n accept?: string;\r\n /**\r\n * Whether to only allow cube textures\r\n */\r\n cubeOnly?: boolean;\r\n} & Omit<EntitySelectorProps<BaseTexture>, \"getEntities\" | \"getName\">;\r\n\r\n/**\r\n * A primitive component with a ComboBox for selecting from existing scene textures\r\n * and a button for uploading new texture files.\r\n * @param props TextureSelectorProps\r\n * @returns TextureSelector component\r\n */\r\nexport const TextureSelector: FunctionComponent<TextureSelectorProps> = (props) => {\r\n TextureSelector.displayName = \"TextureSelector\";\r\n const { scene, cubeOnly, value, onChange, onLink, defaultValue } = props;\r\n const classes = useStyles();\r\n\r\n const getTextures = useCallback(() => scene.textures, [scene.textures]);\r\n const getName = useCallback((texture: BaseTexture) => texture.displayName || texture.name || `${texture.getClassName() || \"Unnamed Texture\"} (${texture.uniqueId})`, []);\r\n const filter = useCallback((texture: BaseTexture) => !cubeOnly || texture.isCube, [cubeOnly]);\r\n\r\n return (\r\n <div className={classes.container}>\r\n <EntitySelector value={value} onChange={onChange} onLink={onLink} defaultValue={defaultValue} getEntities={getTextures} getName={getName} filter={filter} />\r\n {!value && <TextureUpload scene={scene} onChange={onChange} cubeOnly={cubeOnly} />}\r\n </div>\r\n );\r\n};\r\n"]}
|