diff --git a/packages/toolpad-app/src/toolpad/AppEditor/CodeComponentEditor/index.tsx b/packages/toolpad-app/src/toolpad/AppEditor/CodeComponentEditor/index.tsx index a19f764857c..8397d71575d 100644 --- a/packages/toolpad-app/src/toolpad/AppEditor/CodeComponentEditor/index.tsx +++ b/packages/toolpad-app/src/toolpad/AppEditor/CodeComponentEditor/index.tsx @@ -5,8 +5,16 @@ import createCache from '@emotion/cache'; import { CacheProvider } from '@emotion/react'; import * as ReactDOM from 'react-dom'; import { ErrorBoundary } from 'react-error-boundary'; -import { NodeId, createComponent, ToolpadComponent, TOOLPAD_COMPONENT } from '@mui/toolpad-core'; +import { + NodeId, + createComponent, + ToolpadComponent, + TOOLPAD_COMPONENT, + ArgTypeDefinitions, + ArgTypeDefinition, +} from '@mui/toolpad-core'; import { useQuery } from '@tanstack/react-query'; +import invariant from 'invariant'; import * as appDom from '../../../appDom'; import { useDom, useDomApi } from '../../DomLoader'; import { tryFormat } from '../../../utils/prettier'; @@ -17,17 +25,57 @@ import usePageTitle from '../../../utils/usePageTitle'; import useLatest from '../../../utils/useLatest'; import AppThemeProvider from '../../../runtime/AppThemeProvider'; import useCodeComponent from './useCodeComponent'; -import { mapValues } from '../../../utils/collections'; +import { filterValues, mapValues } from '../../../utils/collections'; import ErrorAlert from '../PageEditor/ErrorAlert'; import lazyComponent from '../../../utils/lazyComponent'; import CenteredSpinner from '../../../components/CenteredSpinner'; import SplitPane from '../../../components/SplitPane'; +import { getDefaultControl } from '../../propertyControls'; +import { WithControlledProp } from '../../../utils/types'; const TypescriptEditor = lazyComponent(() => import('../../../components/TypescriptEditor'), { noSsr: true, fallback: , }); +interface PropertyEditorProps extends WithControlledProp { + name: string; + argType: ArgTypeDefinition; +} + +function PropertyEditor({ argType, name, value, onChange }: PropertyEditorProps) { + const Control = getDefaultControl(argType); + if (!Control) { + return null; + } + return ; +} + +interface PropertiesEditorProps extends WithControlledProp> { + argTypes: ArgTypeDefinitions; +} + +function PropertiesEditor({ argTypes, value, onChange }: PropertiesEditorProps) { + return ( + + Properties: + {Object.entries(argTypes).map(([name, argType]) => { + invariant(argType, 'argType not defined'); + return ( + {name}} resetKeys={[argType]}> + onChange({ ...value, [name]: newPropValue })} + /> + + ); + })} + + ); +} + const Noop = createComponent(() => null); const CanvasFrame = styled('iframe')({ @@ -148,6 +196,8 @@ function CodeComponentEditorContent({ codeComponentNode }: CodeComponentEditorCo [argTypes], ); + const [props, setProps] = React.useState({}); + return ( @@ -162,7 +212,10 @@ function CodeComponentEditorContent({ codeComponentNode }: CodeComponentEditorCo extraLibs={extraLibs} /> - + + + + } > - + typeof propValue !== 'undefined')} + /> {compileError ? : null} diff --git a/packages/toolpad-app/src/toolpad/propertyControls/select.tsx b/packages/toolpad-app/src/toolpad/propertyControls/select.tsx index ef50e0ff61c..1cabe20ed44 100644 --- a/packages/toolpad-app/src/toolpad/propertyControls/select.tsx +++ b/packages/toolpad-app/src/toolpad/propertyControls/select.tsx @@ -6,7 +6,7 @@ function SelectPropEditor({ label, propType, value, onChange, disabled }: Editor const items = propType.type === 'string' ? propType.enum ?? [] : []; const handleChange = React.useCallback( (event: React.ChangeEvent) => { - onChange(event.target.value); + onChange(event.target.value || undefined); }, [onChange], ); diff --git a/packages/toolpad-app/src/toolpad/propertyControls/string.tsx b/packages/toolpad-app/src/toolpad/propertyControls/string.tsx index f150006e2c7..0d8d86351cf 100644 --- a/packages/toolpad-app/src/toolpad/propertyControls/string.tsx +++ b/packages/toolpad-app/src/toolpad/propertyControls/string.tsx @@ -5,7 +5,7 @@ import type { EditorProps } from '../../types'; function StringPropEditor({ label, value, onChange, disabled }: EditorProps) { const handleChange = React.useCallback( (event: React.ChangeEvent) => { - onChange(event.target.value); + onChange(event.target.value || undefined); }, [onChange], ); diff --git a/packages/toolpad-app/src/types.ts b/packages/toolpad-app/src/types.ts index 162828517bb..480ef11b777 100644 --- a/packages/toolpad-app/src/types.ts +++ b/packages/toolpad-app/src/types.ts @@ -23,7 +23,7 @@ export interface EditorProps { propType: PropValueType; disabled?: boolean; value: T | undefined; - onChange: (newValue: T) => void; + onChange: (newValue: T | undefined) => void; } export type FlowDirection = 'row' | 'column' | 'row-reverse' | 'column-reverse';