Skip to main content

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.

View Documentation

<SpotlightNumber
value={1247.5}
unit="m²"
label="Floor Area"
format=".1f"
trend={+12.5}
status="good"
/>

ComparePluginSettingsForm​

Configure comparison views and analysis settings.

View Documentation

<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​

Development Resources​

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