Skip to content

Commit 4a5d2e9

Browse files
Use optionize for constructor options across view components.
Replace hand-merged option spreads with the typed optionize/EmptySelfOptions/combineOptions pattern so defaults and parent options stay type-safe. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent b5a0a34 commit 4a5d2e9

4 files changed

Lines changed: 42 additions & 27 deletions

File tree

src/common/CelestialBodyNode.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { TReadOnlyProperty } from "scenerystack/axon";
22
import { Multilink } from "scenerystack/axon";
33
import type { Vector2 } from "scenerystack/dot";
4-
import { optionize } from "scenerystack/phet-core";
4+
import { combineOptions, optionize } from "scenerystack/phet-core";
55
import type { ModelViewTransform2 } from "scenerystack/phetcommon";
66
import type { NodeOptions, TPaint } from "scenerystack/scenery";
77
import { Circle, Node } from "scenerystack/scenery";
@@ -33,7 +33,7 @@ export class CelestialBodyNode extends Node {
3333

3434
const body = new Circle(radius, { fill });
3535

36-
super({ ...nodeOptions, children: [body] });
36+
super(combineOptions<NodeOptions>(nodeOptions, { children: [body] }));
3737

3838
Multilink.multilink([positionProperty, mvtProperty], (pos, mvt) => {
3939
this.translation = mvt.modelToViewPosition(pos);

src/common/SolarSystemModelsPanel.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,26 @@
2525
* const panel = new SolarSystemModelsPanel(content, { fill: "transparent" });
2626
*/
2727

28+
import { type EmptySelfOptions, optionize } from "scenerystack/phet-core";
2829
import type { Node } from "scenerystack/scenery";
29-
import type { PanelOptions } from "scenerystack/sun";
30-
import { Panel } from "scenerystack/sun";
30+
import { Panel, type PanelOptions } from "scenerystack/sun";
3131
import SolarSystemModelsColors from "../SolarSystemModelsColors.js";
3232
import { PANEL_CORNER_RADIUS, PANEL_X_MARGIN, PANEL_Y_MARGIN } from "../SolarSystemModelsConstants.js";
3333

34+
export type SolarSystemModelsPanelOptions = PanelOptions;
35+
3436
export class SolarSystemModelsPanel extends Panel {
35-
public constructor(content: Node, providedOptions?: PanelOptions) {
36-
super(content, {
37-
fill: SolarSystemModelsColors.panelBackgroundColorProperty,
38-
stroke: SolarSystemModelsColors.panelBorderColorProperty,
39-
cornerRadius: PANEL_CORNER_RADIUS,
40-
xMargin: PANEL_X_MARGIN,
41-
yMargin: PANEL_Y_MARGIN,
42-
...providedOptions,
43-
});
37+
public constructor(content: Node, providedOptions?: SolarSystemModelsPanelOptions) {
38+
const options = optionize<SolarSystemModelsPanelOptions, EmptySelfOptions, PanelOptions>()(
39+
{
40+
fill: SolarSystemModelsColors.panelBackgroundColorProperty,
41+
stroke: SolarSystemModelsColors.panelBorderColorProperty,
42+
cornerRadius: PANEL_CORNER_RADIUS,
43+
xMargin: PANEL_X_MARGIN,
44+
yMargin: PANEL_Y_MARGIN,
45+
},
46+
providedOptions,
47+
);
48+
super(content, options);
4449
}
4550
}

src/configurations/view/ConfigurationsScreenView.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { DerivedProperty, Multilink, type TReadOnlyProperty } from "scenerystack/axon";
22
import { Vector2 } from "scenerystack/dot";
33
import { Shape } from "scenerystack/kite";
4+
import { type EmptySelfOptions, optionize } from "scenerystack/phet-core";
45
import { ModelViewTransform2 } from "scenerystack/phetcommon";
56
import { Circle, DragListener, KeyboardDragListener, Node, Path, Rectangle, Text } from "scenerystack/scenery";
67
import { PhetFont, ResetAllButton } from "scenerystack/scenery-phet";
7-
import type { ScreenViewOptions } from "scenerystack/sim";
8-
import { ScreenView } from "scenerystack/sim";
8+
import { ScreenView, type ScreenViewOptions } from "scenerystack/sim";
99
import { RectangularPushButton } from "scenerystack/sun";
1010
import { Tandem } from "scenerystack/tandem";
1111
import { CelestialBodyNode } from "../../common/CelestialBodyNode.js";
@@ -46,16 +46,21 @@ function buildMvt(a1: number, a2: number): ModelViewTransform2 {
4646
);
4747
}
4848

49+
export type ConfigurationsScreenViewOptions = ScreenViewOptions;
50+
4951
export class ConfigurationsScreenView extends ScreenView {
5052
private readonly model: ConfigurationsModel;
5153
// Rebuilt whenever the orbital radii change, so its scale always fits both orbits.
5254
private readonly mvtProperty: TReadOnlyProperty<ModelViewTransform2>;
5355

54-
public constructor(model: ConfigurationsModel, options?: ScreenViewOptions) {
55-
super({
56-
screenSummaryContent: new ConfigurationsScreenSummaryContent(model),
57-
...options,
58-
});
56+
public constructor(model: ConfigurationsModel, providedOptions?: ConfigurationsScreenViewOptions) {
57+
const options = optionize<ConfigurationsScreenViewOptions, EmptySelfOptions, ScreenViewOptions>()(
58+
{
59+
screenSummaryContent: new ConfigurationsScreenSummaryContent(model),
60+
},
61+
providedOptions,
62+
);
63+
super(options);
5964

6065
this.model = model;
6166
this.mvtProperty = new DerivedProperty(

src/ptolemaic/view/PtolemaicScreenView.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { Multilink, Property, type TReadOnlyProperty } from "scenerystack/axon";
22
import { Vector2 } from "scenerystack/dot";
33
import { Shape } from "scenerystack/kite";
4+
import { type EmptySelfOptions, optionize } from "scenerystack/phet-core";
45
import { ModelViewTransform2 } from "scenerystack/phetcommon";
56
import { Circle, DragListener, Node, Path, Rectangle, Text } from "scenerystack/scenery";
67
import { ArrowNode, PhetFont, ResetAllButton } from "scenerystack/scenery-phet";
7-
import type { ScreenViewOptions } from "scenerystack/sim";
8-
import { ScreenView } from "scenerystack/sim";
8+
import { ScreenView, type ScreenViewOptions } from "scenerystack/sim";
99
import { Tandem } from "scenerystack/tandem";
1010
import { CelestialBodyNode } from "../../common/CelestialBodyNode.js";
1111
import { FLAT_RESET_ALL_BUTTON_OPTIONS } from "../../common/SolarSystemModelsButtonOptions.js";
@@ -35,16 +35,21 @@ import { PtolemaicZodiacStrip } from "./PtolemaicZodiacStrip.js";
3535
// Zodiac glyphs (Unicode), Aries→Pisces — matches the Flash symbol-font ring.
3636
const ZODIAC_SIGNS = ["♈", "♉", "♊", "♋", "♌", "♍", "♎", "♏", "♐", "♑", "♒", "♓"];
3737

38+
export type PtolemaicScreenViewOptions = ScreenViewOptions;
39+
3840
export class PtolemaicScreenView extends ScreenView {
3941
private readonly pathTrail: PtolemaicPathTrail;
4042
private readonly model: PtolemaicModel;
4143
private readonly mvtProperty: TReadOnlyProperty<ModelViewTransform2>;
4244

43-
public constructor(model: PtolemaicModel, options?: ScreenViewOptions) {
44-
super({
45-
screenSummaryContent: new PtolemaicScreenSummaryContent(model),
46-
...options,
47-
});
45+
public constructor(model: PtolemaicModel, providedOptions?: PtolemaicScreenViewOptions) {
46+
const options = optionize<PtolemaicScreenViewOptions, EmptySelfOptions, ScreenViewOptions>()(
47+
{
48+
screenSummaryContent: new PtolemaicScreenSummaryContent(model),
49+
},
50+
providedOptions,
51+
);
52+
super(options);
4853

4954
this.model = model;
5055

0 commit comments

Comments
 (0)