Skip to content

Commit 2c7e3f0

Browse files
georginahalpernGeorgina
andauthored
[Fluent] Add boundproperty, add dropdownpropertyline (#16788)
Co-authored-by: Georgina <[email protected]>
1 parent ba2190d commit 2c7e3f0

File tree

5 files changed

+50
-10
lines changed

5 files changed

+50
-10
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { useInterceptObservable } from "../../hooks/instrumentationHooks";
2+
import { useObservableState } from "../../hooks/observableHooks";
3+
import type { ComponentType } from "react";
4+
import type { BaseComponentProps } from "shared-ui-components/fluent/hoc/propertyLine";
5+
6+
export type BoundPropertyProps<T, P extends object> = Omit<P, "value" | "onChange"> & {
7+
component: ComponentType<P & BaseComponentProps<T>>;
8+
target: any;
9+
propertyKey: PropertyKey;
10+
};
11+
12+
export function BoundPropertyLine<T, P extends object>(props: BoundPropertyProps<T, P>) {
13+
// eslint-disable-next-line @typescript-eslint/naming-convention
14+
const { target, propertyKey, component: Component, ...rest } = props;
15+
const value = useObservableState(() => target[propertyKey], useInterceptObservable("property", target, propertyKey));
16+
17+
return <Component {...(rest as P)} value={value} onChange={(val: T) => (target[propertyKey] = val)} />;
18+
}

packages/dev/inspector-v2/src/components/properties/meshOutlineOverlayProperties.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { Color3PropertyLine } from "shared-ui-components/fluent/hoc/colorPropert
99
import { SwitchPropertyLine } from "shared-ui-components/fluent/hoc/switchPropertyLine";
1010
import { useInterceptObservable } from "../../hooks/instrumentationHooks";
1111
import { useObservableState } from "../../hooks/observableHooks";
12+
import { BoundPropertyLine } from "./boundPropertyLine";
1213

1314
type Color3Keys<T> = { [P in keyof T]: T[P] extends Color3 ? P : never }[keyof T];
1415

@@ -25,16 +26,15 @@ export const MeshOutlineOverlayProperties: FunctionComponent<{ mesh: Mesh }> = (
2526
const { mesh } = props;
2627

2728
// There is no observable for colors, so we use an interceptor to listen for changes.
28-
const renderOverlay = useObservableState(() => mesh.renderOverlay, useInterceptObservable("property", mesh, "renderOverlay"));
2929
const overlayColor = useColor3Property(mesh, "overlayColor");
3030

3131
const renderOutline = useObservableState(() => mesh.renderOutline, useInterceptObservable("property", mesh, "renderOutline"));
3232
const outlineColor = useColor3Property(mesh, "outlineColor");
3333

3434
return (
3535
<>
36-
<SwitchPropertyLine key="RenderOverlay" label="Render Overlay" value={renderOverlay} onChange={(checked) => (mesh.renderOverlay = checked)} />
37-
<Collapse visible={renderOverlay}>
36+
<BoundPropertyLine component={SwitchPropertyLine} key="RenderOverlay" label="Render Overlay" target={mesh} propertyKey="renderOverlay" />
37+
<Collapse visible={mesh.renderOverlay}>
3838
<Color3PropertyLine
3939
key="OverlayColor"
4040
label="Overlay Color"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Dropdown } from "../primitives/dropdown";
2+
import type { DropdownProps } from "../primitives/dropdown";
3+
import { PropertyLine } from "./propertyLine";
4+
import type { PropertyLineProps } from "./propertyLine";
5+
import type { FunctionComponent } from "react";
6+
7+
/**
8+
* Wraps a dropdown in a property line
9+
* @param props - PropertyLineProps and DropdownProps
10+
* @returns property-line wrapped dropdown
11+
*/
12+
export const DropdownPropertyLine: FunctionComponent<PropertyLineProps & DropdownProps> = (props) => {
13+
return (
14+
<PropertyLine {...props}>
15+
<Dropdown {...props} />
16+
</PropertyLine>
17+
);
18+
};

packages/dev/sharedUiComponents/src/fluent/primitives/dropdown.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Dropdown as FluentDropdown, makeStyles, Option } from "@fluentui/react-components";
22
import type { FunctionComponent } from "react";
3+
import type { BaseComponentProps } from "../hoc/propertyLine";
34

45
const useDropdownStyles = makeStyles({
56
dropdownOption: {
@@ -20,7 +21,9 @@ export type DropdownOption = {
2021
value: string | number;
2122
};
2223

23-
type DropdownProps = { options: readonly DropdownOption[]; onSelect: (o: string) => void; defaultValue?: DropdownOption };
24+
export type DropdownProps = BaseComponentProps<DropdownOption> & {
25+
options: readonly DropdownOption[];
26+
};
2427

2528
/**
2629
* Renders a fluent UI dropdown with a calback for selection and a required default value
@@ -33,10 +36,10 @@ export const Dropdown: FunctionComponent<DropdownProps> = (props) => {
3336
<FluentDropdown
3437
className={classes.dropdownOption}
3538
onOptionSelect={(evt, data) => {
36-
data.optionValue != undefined && props.onSelect(data.optionValue);
39+
data.optionValue != undefined && props.onChange(props.options.find((o) => o.value.toString() === data.optionValue) as DropdownOption);
3740
}}
38-
defaultValue={props.defaultValue?.label}
39-
defaultSelectedOptions={props.defaultValue && [props.defaultValue.value.toString()]}
41+
defaultValue={props.value.label}
42+
defaultSelectedOptions={[props.value.value.toString()]}
4043
>
4144
{props.options.map((option: DropdownOption) => (
4245
<Option className={classes.optionsLine} key={option.label} value={option.value.toString()} disabled={false}>

packages/dev/sharedUiComponents/src/lines/optionsLineComponent.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { IInspectableOptions } from "core/Misc/iInspectable";
66
import copyIcon from "../imgs/copy.svg";
77
import { PropertyLine } from "../fluent/hoc/propertyLine";
88
import { Dropdown } from "../fluent/primitives/dropdown";
9+
import type { DropdownOption } from "../fluent/primitives/dropdown";
910
import { ToolContext } from "../fluent/hoc/fluentToolWrapper";
1011

1112
// eslint-disable-next-line @typescript-eslint/naming-convention
@@ -124,10 +125,10 @@ export class OptionsLine extends React.Component<IOptionsLineProps, { value: num
124125
<PropertyLine label={this.props.label} onCopy={() => this.onCopyClickStr()}>
125126
<Dropdown
126127
options={this.props.options}
127-
onSelect={(val: string) => {
128-
val !== undefined && this.updateValue(val);
128+
onChange={(val: DropdownOption) => {
129+
val.value !== undefined && this.updateValue(val.value.toString());
129130
}}
130-
defaultValue={this.props.options.find((o) => o.value === this.state.value || o.selected)}
131+
value={this.props.options.find((o) => o.value === this.state.value || o.selected) || this.props.options[0]}
131132
/>
132133
</PropertyLine>
133134
);

0 commit comments

Comments
 (0)