Components Overview
InForm's component library provides a comprehensive set of React components for building parametric design exploration interfaces. These components handle everything from parameter input to 3D visualization and data analysis.
Component Categories​
Input Components​
Parameter Control Components for user interaction:
- SliderParameter: Continuous numeric input with range validation
- IntegerParameter: Discrete numeric input with step control
- DropdownParameter: Selection from predefined options
- BooleanParameter: Toggle switches and checkboxes
- TextParameter: Text input with validation
- ListParameter: Multi-select and tagging interfaces
Visualization Components​
3D and Data Visualization Components:
- UnityViewer: WebGL-based 3D model display and interaction
- ParameterSpaceViewer: Multi-dimensional parameter space visualization
- ComparisonViewer: Side-by-side variant comparison
- PerformanceCharts: Various chart types for data visualization
- HeatMapViewer: Performance heat maps and contour plots
Layout Components​
Interface Organization Components:
- ParameterPanel: Organized parameter input interface
- ResultsPanel: Performance metrics and analysis results
- NavigationBar: Project navigation and user controls
- SidePanel: Collapsible side panels for tools and information
- TabContainer: Tabbed interface for different views
Data Components​
Data Handling and Display Components:
- DataTable: Sortable, filterable data tables
- MetricCard: Individual performance metric display
- ProgressIndicator: Loading and calculation progress
- ErrorBoundary: Error handling and user feedback
- NotificationCenter: User notifications and alerts
Core Components​
SpotlightNumber​
Display key performance metrics with formatting and context.
<SpotlightNumber
value={1247.5}
unit="m²"
label="Floor Area"
format=".1f"
trend={+12.5}
status="good"
/>
ComparePluginSettingsForm​
Configure comparison views and analysis settings.
<ComparePluginSettingsForm
settings={comparisonSettings}
onSettingsChange={handleSettingsUpdate}
availableMetrics={performanceMetrics}
projects={projectList}
/>
UnityViewer​
3D model visualization and interaction.
<UnityViewer
modelData={geometryData}
parameters={currentParameters}
onParameterChange={handleParameterUpdate}
viewConfiguration={viewConfig}
interactionMode="explore"
/>
Component Design Principles​
Consistency​
All components follow consistent design patterns:
- Material-UI Based: Built on MUI component library
- Theme Support: Responsive to light/dark themes
- Responsive Design: Works across desktop, tablet, and mobile
- Accessibility: WCAG 2.1 AA compliance
Composability​
Components are designed to work together:
- Prop Interfaces: Standardized prop patterns
- Event Handling: Consistent event naming and structure
- State Management: Compatible with React state and Redux
- TypeScript Support: Full TypeScript definitions
Performance​
Optimized for complex parametric applications:
- Lazy Loading: Components load on demand
- Memoization: Prevent unnecessary re-renders
- Virtual Scrolling: Handle large datasets efficiently
- Debounced Updates: Smooth parameter adjustment
Usage Patterns​
Basic Parameter Interface​
import { ParameterPanel, SliderParameter, DropdownParameter } from '@inform/components';
function ParametricInterface({ parameters, onParameterChange }) {
return (
<ParameterPanel title="Design Parameters">
<SliderParameter
name="building_height"
label="Building Height"
value={parameters.building_height}
min={10}
max={200}
step={1}
unit="m"
onChange={(value) => onParameterChange('building_height', value)}
/>
<DropdownParameter
name="structural_system"
label="Structural System"
value={parameters.structural_system}
options={['Steel Frame', 'Concrete', 'Timber', 'Composite']}
onChange={(value) => onParameterChange('structural_system', value)}
/>
</ParameterPanel>
);
}
3D Visualization Setup​
import { UnityViewer, ViewControls } from '@inform/components';
function ModelViewer({ modelData, parameters }) {
const [viewMode, setViewMode] = useState('perspective');
const [showWireframe, setShowWireframe] = useState(false);
return (
<div className="model-viewer">
<ViewControls
viewMode={viewMode}
onViewModeChange={setViewMode}
showWireframe={showWireframe}
onWireframeToggle={setShowWireframe}
/>
<UnityViewer
modelData={modelData}
parameters={parameters}
viewMode={viewMode}
showWireframe={showWireframe}
onSelectionChange={handleSelection}
/>
</div>
);
}
Data Visualization​
import { PerformanceCharts, MetricCard, DataTable } from '@inform/components';
function AnalysisResults({ results, variants }) {
return (
<div className="analysis-results">
<div className="metrics-summary">
<MetricCard
title="Floor Area"
value={results.floor_area}
unit="m²"
trend={results.area_trend}
/>
<MetricCard
title="Construction Cost"
value={results.cost}
unit="USD"
format="currency"
/>
</div>
<PerformanceCharts
data={results.performance_data}
chartType="scatter"
xAxis="floor_area"
yAxis="cost"
colorBy="structural_system"
/>
<DataTable
data={variants}
columns={['name', 'floor_area', 'cost', 'performance_score']}
sortable
filterable
/>
</div>
);
}
Styling and Theming​
Theme Configuration​
import { ThemeProvider, createInformTheme } from '@inform/components';
const theme = createInformTheme({
palette: {
primary: {
main: '#1976d2',
},
secondary: {
main: '#dc004e',
},
},
inform: {
parameter: {
borderRadius: 8,
spacing: 16,
},
visualization: {
colorScheme: 'viridis',
gridColor: '#e0e0e0',
},
},
});
function App() {
return (
<ThemeProvider theme={theme}>
<InformApplication />
</ThemeProvider>
);
}
Custom Styling​
import { styled } from '@mui/material/styles';
import { ParameterPanel } from '@inform/components';
const CustomParameterPanel = styled(ParameterPanel)(({ theme }) => ({
backgroundColor: theme.palette.background.paper,
borderRadius: theme.shape.borderRadius,
padding: theme.spacing(2),
boxShadow: theme.shadows[1],
'& .parameter-group': {
marginBottom: theme.spacing(3),
},
'& .parameter-label': {
fontWeight: theme.typography.fontWeightMedium,
color: theme.palette.text.primary,
},
}));
State Management​
Component State Patterns​
import { useParameterState, useModelEvaluation } from '@inform/hooks';
function ParametricExplorer({ projectId }) {
// Manage parameter state
const {
parameters,
updateParameter,
resetParameters,
saveVariant,
} = useParameterState(projectId);
// Handle model evaluation
const {
results,
isCalculating,
error,
evaluate,
} = useModelEvaluation(projectId);
// Automatic evaluation when parameters change
useEffect(() => {
const debounced = debounce(() => evaluate(parameters), 500);
debounced();
return debounced.cancel;
}, [parameters, evaluate]);
if (error) {
return <ErrorMessage error={error} onRetry={() => evaluate(parameters)} />;
}
return (
<div className="parametric-explorer">
<ParameterPanel
parameters={parameters}
onParameterChange={updateParameter}
disabled={isCalculating}
/>
<ModelViewer
results={results}
isLoading={isCalculating}
/>
<ResultsPanel
results={results}
onSaveVariant={saveVariant}
/>
</div>
);
}
Redux Integration​
import { useSelector, useDispatch } from 'react-redux';
import { updateParameter, evaluateModel } from '../store/parametricSlice';
function ConnectedParameterPanel() {
const dispatch = useDispatch();
const { parameters, isEvaluating } = useSelector(state => state.parametric);
const handleParameterChange = (name, value) => {
dispatch(updateParameter({ name, value }));
dispatch(evaluateModel());
};
return (
<ParameterPanel
parameters={parameters}
onParameterChange={handleParameterChange}
disabled={isEvaluating}
/>
);
}
Advanced Features​
Custom Component Development​
import { forwardRef } from 'react';
import { useInformTheme, BaseParameter } from '@inform/components';
const CustomSliderParameter = forwardRef(({
name,
label,
value,
min,
max,
onChange,
...props
}, ref) => {
const theme = useInformTheme();
return (
<BaseParameter
ref={ref}
name={name}
label={label}
{...props}
>
<CustomSlider
value={value}
min={min}
max={max}
onChange={onChange}
theme={theme}
/>
</BaseParameter>
);
});
Plugin Architecture​
import { PluginProvider, usePlugin } from '@inform/components';
// Define a custom analysis plugin
const performanceAnalysisPlugin = {
name: 'performance-analysis',
component: PerformanceAnalysisPanel,
settings: PerformanceSettings,
evaluate: performanceAnalysisFunction,
};
// Register and use plugins
function AnalysisWorkspace() {
const plugin = usePlugin('performance-analysis');
return (
<PluginProvider plugins={[performanceAnalysisPlugin]}>
<AnalysisInterface />
</PluginProvider>
);
}
Testing Components​
Unit Testing​
import { render, screen, fireEvent } from '@testing-library/react';
import { SliderParameter } from '@inform/components';
describe('SliderParameter', () => {
it('calls onChange when value changes', () => {
const handleChange = jest.fn();
render(
<SliderParameter
name="test-slider"
label="Test Slider"
value={50}
min={0}
max={100}
onChange={handleChange}
/>
);
const slider = screen.getByRole('slider');
fireEvent.change(slider, { target: { value: 75 } });
expect(handleChange).toHaveBeenCalledWith(75);
});
});
Integration Testing​
import { render, screen, waitFor } from '@testing-library/react';
import { ParametricExplorer } from '../components/ParametricExplorer';
import { mockEvaluationAPI } from '../__mocks__/api';
describe('ParametricExplorer Integration', () => {
it('evaluates model when parameters change', async () => {
mockEvaluationAPI.mockResolvedValue({ floor_area: 1000, cost: 500000 });
render(<ParametricExplorer projectId="test-project" />);
const heightSlider = screen.getByLabelText('Building Height');
fireEvent.change(heightSlider, { target: { value: 60 } });
await waitFor(() => {
expect(screen.getByText('1000 m²')).toBeInTheDocument();
});
});
});
Performance Optimization​
Component Optimization​
import { memo, useMemo, useCallback } from 'react';
const OptimizedParameterPanel = memo(({ parameters, onParameterChange }) => {
// Memoize expensive calculations
const parameterGroups = useMemo(() => {
return groupParametersByCategory(parameters);
}, [parameters]);
// Memoize event handlers
const handleParameterChange = useCallback((name, value) => {
onParameterChange(name, value);
}, [onParameterChange]);
return (
<ParameterPanel
parameterGroups={parameterGroups}
onParameterChange={handleParameterChange}
/>
);
});
Virtual Scrolling for Large Datasets​
import { VirtualizedDataTable } from '@inform/components';
function LargeDataTable({ data }) {
return (
<VirtualizedDataTable
data={data}
rowHeight={50}
overscan={10}
columns={columns}
onRowClick={handleRowClick}
/>
);
}
Accessibility​
ARIA Support​
function AccessibleSliderParameter({ name, label, value, onChange, ...props }) {
return (
<div className="parameter-container">
<label htmlFor={name} className="parameter-label">
{label}
</label>
<input
id={name}
type="range"
value={value}
onChange={(e) => onChange(Number(e.target.value))}
aria-describedby={`${name}-description`}
{...props}
/>
<div id={`${name}-description`} className="parameter-description">
Current value: {value}
</div>
</div>
);
}
Keyboard Navigation​
function KeyboardNavigableInterface() {
const handleKeyDown = (event) => {
switch (event.key) {
case 'Tab':
// Handle tab navigation
break;
case 'Enter':
// Handle activation
break;
case 'Escape':
// Handle cancellation
break;
}
};
return (
<div
className="interface"
onKeyDown={handleKeyDown}
tabIndex={0}
role="application"
aria-label="Parametric Design Interface"
>
{/* Interface content */}
</div>
);
}
Next Steps​
Component Documentation​
- SpotlightNumber: Performance metric display component
- ComparePluginSettingsForm: Comparison configuration component
Development Resources​
- API Reference: Backend integration
- Developer Guides: Implementation tutorials
- Architecture: Platform architecture
Community and Support​
- Component Library GitHub: Source code and issue tracking
- Storybook Documentation: Interactive component examples
- Design System: Visual design guidelines and assets
- Community Forum: Developer discussions and support