diff --git a/packages/studio/src/components/editor/propertyPanelFlatPrimitives.test.tsx b/packages/studio/src/components/editor/propertyPanelFlatPrimitives.test.tsx index 954ea8052..32c7f4b9f 100644 --- a/packages/studio/src/components/editor/propertyPanelFlatPrimitives.test.tsx +++ b/packages/studio/src/components/editor/propertyPanelFlatPrimitives.test.tsx @@ -229,6 +229,96 @@ describe("FlatSlider", () => { }); }); +describe("FlatSlider — Grade extensions", () => { + it("renders a center tick when centerTick is true, and omits it by default", () => { + const { host: withTick, root: rootA } = renderInto( + , + ); + expect(withTick.querySelector('[data-flat-slider-center-tick="true"]')).not.toBeNull(); + act(() => rootA.unmount()); + + const { host: withoutTick, root: rootB } = renderInto( + , + ); + expect(withoutTick.querySelector('[data-flat-slider-center-tick="true"]')).toBeNull(); + act(() => rootB.unmount()); + }); + + it("always reserves a 14px reset slot, showing the icon only when set and onReset is provided", () => { + const onReset = vi.fn(); + const { host, root } = renderInto( + , + ); + const slot = host.querySelector('[data-flat-slider-reset-slot="true"]'); + expect(slot).not.toBeNull(); + const resetButton = host.querySelector('[data-flat-slider-reset="true"]'); + expect(resetButton).not.toBeNull(); + act(() => resetButton?.dispatchEvent(new MouseEvent("click", { bubbles: true }))); + expect(onReset).toHaveBeenCalledTimes(1); + act(() => root.unmount()); + + const { host: unsetHost, root: rootB } = renderInto( + , + ); + expect(unsetHost.querySelector('[data-flat-slider-reset-slot="true"]')).not.toBeNull(); + expect(unsetHost.querySelector('[data-flat-slider-reset="true"]')).toBeNull(); + act(() => rootB.unmount()); + }); + + it("renders no reset slot at all when centerTick is omitted, matching existing Style/Media callers", () => { + const { host, root } = renderInto( + , + ); + expect(host.querySelector('[data-flat-slider-reset-slot="true"]')).toBeNull(); + expect(host.querySelector('[data-flat-slider-reset="true"]')).toBeNull(); + act(() => root.unmount()); + }); +}); + describe("FlatSelectRow", () => { it("renders the default tier with no reset button", () => { const { host, root } = renderInto( diff --git a/packages/studio/src/components/editor/propertyPanelFlatPrimitives.tsx b/packages/studio/src/components/editor/propertyPanelFlatPrimitives.tsx index e6dc9f1f7..0ea2174c7 100644 --- a/packages/studio/src/components/editor/propertyPanelFlatPrimitives.tsx +++ b/packages/studio/src/components/editor/propertyPanelFlatPrimitives.tsx @@ -247,6 +247,8 @@ export function FlatSlider({ tier, displayValue, disabled, + centerTick, + onReset, onCommit, }: { label: string; @@ -257,6 +259,8 @@ export function FlatSlider({ tier: "default" | "explicitCustom"; displayValue: string; disabled?: boolean; + centerTick?: boolean; + onReset?: () => void; onCommit: (nextValue: number) => void; }) { const clampedPct = Math.max(0, Math.min(100, ((value - min) / Math.max(max - min, 1e-6)) * 100)); @@ -285,6 +289,12 @@ export function FlatSlider({ commitFromClientX(e.clientX, e.currentTarget.getBoundingClientRect()); }} > + {centerTick && ( +
+ )} {tier === "explicitCustom" && (
{displayValue} + {centerTick && ( + + {tier === "explicitCustom" && onReset && ( + + )} + + )}
); }