Add inspector panel with preset grid and intensity slider

This commit is contained in:
Keith Solomon
2026-08-05 16:37:53 -05:00
parent 2c73f8472f
commit c2a0ae2d8c
7 changed files with 2411 additions and 83 deletions
+64
View File
@@ -0,0 +1,64 @@
/**
* @jest-environment jsdom
*/
import { render, screen, within } from '@testing-library/react';
import { FilterPanel } from '../../src/inspector';
jest.mock( '@wordpress/i18n', () => ( {
__: ( str ) => str,
} ) );
const baseProps = {
attributes: { filter: 'normal', intensity: 100 },
setAttributes: jest.fn(),
};
// React tracks input values on controlled components via an internal
// getter/setter pair so it can detect genuine value changes. Assigning
// `slider.value = '40'` directly bypasses that tracker and React rejects
// the subsequent input event as a no-op. Using the native value setter
// keeps React's tracker in sync so the onChange handler actually fires.
const setNativeValue = ( element, value ) => {
const proto = Object.getPrototypeOf( element );
const descriptor = Object.getOwnPropertyDescriptor( proto, 'value' );
descriptor.set.call( element, value );
element.dispatchEvent( new Event( 'input', { bubbles: true } ) );
};
describe( 'FilterPanel', () => {
test( 'renders a button for each preset', () => {
render( <FilterPanel { ...baseProps } /> );
const group = screen.getByRole( 'group', { name: /Filter presets/ } );
const buttons = within( group ).getAllByRole( 'button' );
// 8 preset buttons.
expect( buttons.length ).toBe( 8 );
} );
test( 'marks the active preset with aria-pressed', () => {
render( <FilterPanel { ...{ ...baseProps, attributes: { filter: 'dramatic', intensity: 100 } } } /> );
const dramatic = screen.getByRole( 'button', { name: /Dramatic/ } );
expect( dramatic ).toHaveAttribute( 'aria-pressed', 'true' );
} );
test( 'toggles a preset via setAttributes when clicked', () => {
const setAttributes = jest.fn();
render( <FilterPanel { ...{ ...baseProps, setAttributes } } /> );
const vivid = screen.getByRole( 'button', { name: /Vivid/ } );
vivid.click();
expect( setAttributes ).toHaveBeenCalledWith( { filter: 'vivid' } );
} );
test( 'renders the intensity slider with the current value', () => {
render( <FilterPanel { ...{ ...baseProps, attributes: { filter: 'normal', intensity: 60 } } } /> );
const slider = screen.getByRole( 'slider' );
expect( slider.value ).toBe( '60' );
} );
test( 'updates intensity via setAttributes', () => {
const setAttributes = jest.fn();
render( <FilterPanel { ...{ ...baseProps, setAttributes } } /> );
const slider = screen.getByRole( 'slider' );
setNativeValue( slider, '40' );
expect( setAttributes ).toHaveBeenCalledWith( { intensity: 40 } );
} );
} );
+2
View File
@@ -0,0 +1,2 @@
// Register @testing-library/jest-dom custom matchers (toHaveAttribute, etc.).
import '@testing-library/jest-dom';
+1 -1
View File
@@ -1,2 +1,2 @@
// Minimal setup. Test files import from '@wordpress/blocks' etc. and
// get the standard Jest config from wp-scripts.
// get the standard Jest config from wp-scripts.