Skip to main content

Advanced Features Guide

This guide covers advanced Adaptly features for power users, including custom loaders, component validation, command bar customization, and advanced hooks usage.

Custom Loaders

Default Loading Overlay

Adaptly includes a built-in loading overlay that appears during AI processing:

<AdaptlyProvider
// ... other props
// Loading overlay is enabled by default
/>

Custom Loader Component

Create your own loading overlay with the customLoader prop:

// Custom loader component
function MyCustomLoader({ isVisible, message, subMessage }) {
if (!isVisible) return null;

return (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
<div className="bg-white dark:bg-gray-800 p-8 rounded-lg shadow-lg max-w-md">
<div className="flex items-center space-x-4">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
<div>
<h3 className="text-lg font-semibold">{message}</h3>
<p className="text-gray-600 dark:text-gray-400">{subMessage}</p>
</div>
</div>
</div>
</div>
);
}

// Use custom loader
<AdaptlyProvider
customLoader={MyCustomLoader}
// ... other props
/>

Loader Configuration

Customize the loading overlay behavior:

<AdaptlyProvider
// ... other props
// These props are passed to your custom loader
loadingOverlay={{
enabled: true,
message: "AI is generating your layout...",
subMessage: "Creating components and arranging them for you"
}}
/>

Component Validation

Automatic Validation

Adaptly automatically validates components against your adaptly.json schema:

{
"components": {
"MetricCard": {
"description": "Display key performance indicators",
"props": {
"title": { "type": "string", "required": true },
"value": { "type": "string", "required": true },
"change": { "type": "string", "required": false }
},
"useCases": ["revenue tracking", "user metrics"],
"space": { "min": [2, 1], "max": [3, 2], "preferred": [2, 1] }
}
}
}

Validation Rules

Required Props:

// ✅ Valid - has required props
<MetricCard title="Revenue" value="$45,231" />

// ❌ Invalid - missing required props
<MetricCard value="$45,231" /> // Missing title

Type Validation:

// ✅ Valid - correct types
<MetricCard title="Revenue" value="$45,231" progress={75} />

// ❌ Invalid - wrong types
<MetricCard title="Revenue" value="$45,231" progress="75%" /> // progress should be number

Allowed Values:

// ✅ Valid - allowed value
<MetricCard changeType="positive" />

// ❌ Invalid - not in allowed list
<MetricCard changeType="good" /> // Should be "positive", "negative", or "neutral"

Validation Errors

Adaptly will log validation errors and filter out invalid components:

// Check console for validation warnings
console.log("Component validation failed:", component);

Command Bar Customization

Custom AI Suggestions

Override the default AI suggestions with your own:

const customSuggestions = [
{
value: "Create a sales dashboard",
label: "📊 Create a sales dashboard",
description: "Generate a dashboard with sales metrics and charts"
},
{
value: "Show user analytics",
label: "👥 Show user analytics",
description: "Display user engagement and activity metrics"
},
{
value: "Add revenue metrics",
label: "💰 Add revenue metrics",
description: "Include revenue tracking and financial data"
}
];

<AdaptlyProvider
aiSuggestions={customSuggestions}
// ... other props
/>

Command Bar Options

Customize the command bar behavior:

<AdaptlyProvider
showAISuggestions={true} // Show AI suggestions
showUtilityCommands={true} // Show utility commands (reset, etc.)
// ... other props
/>

Custom Commands

Add your own utility commands:

const { parseUserInput } = useAdaptiveUI();

// Custom command handler
const handleCustomCommand = (command: string) => {
switch (command) {
case "export data":
// Export current layout
break;
case "import data":
// Import layout from file
break;
case "share layout":
// Share layout with team
break;
}
};

// Use in your component
<button onClick={() => handleCustomCommand("export data")}>
Export Layout
</button>

Layout Customization

Default Layout

Set a default layout for your application:

const defaultLayout = {
components: [
{
id: "welcome-card",
type: "EmptyCard",
props: {
title: "Welcome to Adaptly!",
description: "Press ⌘K to describe how you want your dashboard to look."
},
position: { x: 0, y: 0, w: 6, h: 2 },
visible: true
}
],
layout: "grid" as const,
spacing: 6,
columns: 6
};

<AdaptlyProvider
defaultLayout={defaultLayout}
// ... other props
/>

Grid Configuration

Customize the grid layout:

const gridConfig = {
components: [],
layout: "grid" as const,
spacing: 8, // Gap between components
columns: 12 // Number of columns
};

<AdaptlyProvider
defaultLayout={gridConfig}
// ... other props
/>

Layout Types

Support different layout types:

// Grid layout (default)
const gridLayout = {
layout: "grid" as const,
columns: 6,
spacing: 6
};

// Flex layout
const flexLayout = {
layout: "flex" as const,
spacing: 6
};

// Absolute layout
const absoluteLayout = {
layout: "absolute" as const,
spacing: 6
};

Advanced Hooks Usage

useAdaptiveUI Hook

Access all Adaptly functionality through the useAdaptiveUI hook:

import { useAdaptiveUI } from "adaptly";

function MyComponent() {
const {
adaptation,
updateAdaptation,
addComponent,
removeComponent,
updateComponent,
parseUserInput,
parseUserInputWithLLM,
resetToDefault,
isLLMProcessing,
lastLLMResponse,
saveToStorage,
loadFromStorage,
clearStorage,
hasStoredData,
currentLLMProvider
} = useAdaptiveUI();

// Use any of these methods
return (
<div>
<p>Current provider: {currentLLMProvider}</p>
<p>Processing: {isLLMProcessing ? "Yes" : "No"}</p>
{lastLLMResponse && <p>Last response: {lastLLMResponse}</p>}
</div>
);
}

Component Management

Add Components:

const { addComponent } = useAdaptiveUI();

const newComponent = {
id: "metric-1",
type: "MetricCard",
props: {
title: "Revenue",
value: "$45,231",
change: "+20.1%"
},
position: { x: 0, y: 0, w: 2, h: 1 },
visible: true
};

addComponent(newComponent);

Update Components:

const { updateComponent } = useAdaptiveUI();

// Update component props
updateComponent("metric-1", {
props: {
title: "Updated Revenue",
value: "$50,000"
}
});

// Update component position
updateComponent("metric-1", {
position: { x: 2, y: 0, w: 2, h: 1 }
});

Remove Components:

const { removeComponent } = useAdaptiveUI();

removeComponent("metric-1");

Layout Management

Update Layout:

const { updateAdaptation } = useAdaptiveUI();

// Change layout type
updateAdaptation({
layout: "flex",
spacing: 8
});

// Update grid columns
updateAdaptation({
columns: 12,
spacing: 4
});

AI Processing

Basic Input Parsing:

const { parseUserInput } = useAdaptiveUI();

// Simple commands without AI
parseUserInput("reset to default");
parseUserInput("switch to grid layout");

LLM-Powered Parsing:

const { parseUserInputWithLLM } = useAdaptiveUI();

// AI-powered commands
await parseUserInputWithLLM("Create a sales dashboard with revenue metrics");
await parseUserInputWithLLM("Add charts and filter by this week");

Processing Status:

const { isLLMProcessing, lastLLMResponse } = useAdaptiveUI();

if (isLLMProcessing) {
return <div>AI is thinking...</div>;
}

if (lastLLMResponse) {
return <div>AI response: {lastLLMResponse}</div>;
}

Storage Management

Manual Storage Control:

const { saveToStorage, loadFromStorage, clearStorage, hasStoredData } = useAdaptiveUI();

// Save current state
const saved = saveToStorage();

// Load saved state
const savedState = loadFromStorage();

// Clear all data
const cleared = clearStorage();

// Check if data exists
if (hasStoredData()) {
console.log("Found saved data");
}

Real-World Patterns

Provider Switching

Implement runtime provider switching:

const [selectedProvider, setSelectedProvider] = useState("google");
const [selectedModel, setSelectedModel] = useState("gemini-2.0-flash-exp");

const getApiKey = () => {
switch (selectedProvider) {
case "google":
return process.env.NEXT_PUBLIC_GOOGLE_GENERATIVE_AI_API_KEY!;
case "openai":
return process.env.NEXT_PUBLIC_OPENAI_API_KEY!;
case "anthropic":
return process.env.NEXT_PUBLIC_ANTHROPIC_API_KEY!;
default:
return "";
}
};

<AdaptlyProvider
apiKey={getApiKey()}
provider={selectedProvider}
model={selectedModel}
// ... other props
/>

Theme Integration

Integrate with theme systems:

const { adaptation } = useAdaptiveUI();

// Apply theme to components
const themedComponents = adaptation.components.map(component => ({
...component,
props: {
...component.props,
theme: currentTheme,
darkMode: isDarkMode
}
}));

Notification Handling

Handle AI responses and errors:

const { lastLLMResponse, isLLMProcessing } = useAdaptiveUI();

useEffect(() => {
if (lastLLMResponse) {
if (lastLLMResponse.includes("Error:")) {
showErrorNotification(lastLLMResponse);
} else {
showSuccessNotification("Layout updated successfully");
}
}
}, [lastLLMResponse]);

Performance Optimization

Component Memoization

Memoize expensive components:

const MemoizedMetricCard = React.memo(MetricCard);

<AdaptlyProvider
components={{ MetricCard: MemoizedMetricCard }}
// ... other props
/>

Lazy Loading

Load components lazily:

const LazyChart = React.lazy(() => import("./components/Chart"));

<AdaptlyProvider
components={{
MetricCard,
Chart: LazyChart
}}
// ... other props
/>

Storage Optimization

Optimize storage usage:

// Use smaller storage keys
<AdaptlyProvider
storageKey="ui" // Instead of "my-application-ui"
storageVersion="1.0.0"
// ... other props
/>

Next Steps

Example Implementations


Ready for the API reference? Check out the Core Components API for complete documentation of all Adaptly components and their props!