This guide documents breaking changes and provides migration instructions for upgrading Flowbite Blazor.
TextInput, Textarea, and Select components now inherit from InputBase<TValue> (via FlowbiteInputBase<TValue>) and require the @bind-Value directive instead of separate Value/ValueChanged parameters.
Before:
<TextInput Value="@email" ValueChanged="@OnEmailChanged" />
<Textarea Value="@message" ValueChanged="@OnMessageChanged" />
<Select Value="@country" ValueChanged="@OnCountryChanged">
<option value="US">United States</option>
</Select>
@code {
private string email = "";
private string message = "";
private string country = "";
private void OnEmailChanged(string value) => email = value;
private void OnMessageChanged(string value) => message = value;
private void OnCountryChanged(string value) => country = value;
}After:
<TextInput @bind-Value="email" />
<Textarea @bind-Value="message" />
<Select @bind-Value="country">
<option value="US">United States</option>
</Select>
@code {
private string email = "";
private string message = "";
private string country = "";
}For EditForm contexts (recommended):
<EditForm Model="@model" OnValidSubmit="@HandleSubmit">
<DataAnnotationsValidator />
<TextInput TValue="string" @bind-Value="model.Email" />
<ValidationMessage For="@(() => model.Email)" />
<Textarea @bind-Value="model.Message" />
<ValidationMessage For="@(() => model.Message)" />
<Select @bind-Value="model.Country">
<option value="">Select country</option>
<option value="US">United States</option>
</Select>
<ValidationMessage For="@(() => model.Country)" />
<Button Type="submit">Submit</Button>
</EditForm>Migration steps:
- Replace
Value="@variable"with@bind-Value="variable" - Remove
ValueChangedparameter and handler methods - For generic types (e.g.,
int), specifyTValue:<TextInput TValue="int" @bind-Value="model.Age" />
The Color parameter on TextInput, Textarea, and Select is now nullable (TextInputColor? / SelectColor?).
What changed:
- When
Colorisnull(the new default), components automatically display red/Failure color when validation errors occur - When
Coloris explicitly set, the component uses that color regardless of validation state
Before:
@* Color defaulted to Gray, no automatic validation styling *@
<TextInput @bind-Value="model.Email" />After:
@* Color is null by default - automatically shows red on validation errors *@
<TextInput @bind-Value="model.Email" />
@* To force a specific color regardless of validation state: *@
<TextInput @bind-Value="model.Email" Color="TextInputColor.Gray" />Impact: Forms inside <EditForm> now automatically show visual validation feedback without additional code. If you relied on inputs staying gray during validation errors, explicitly set Color="TextInputColor.Gray".
Form components now automatically integrate with Blazor's EditForm validation:
- Red/Failure color appears when field has validation errors
- Default color returns when validation passes
- No additional code required - just use
@bind-Valueinside anEditForm
<EditForm Model="@model" OnValidSubmit="@HandleSubmit">
<DataAnnotationsValidator />
@* Input automatically turns red when validation fails *@
<TextInput TValue="string" @bind-Value="model.Email" Type="email" />
<ValidationMessage For="@(() => model.Email)" />
<Button Type="submit">Submit</Button>
</EditForm>
@code {
private MyModel model = new();
public class MyModel
{
[Required(ErrorMessage = "Email is required")]
[EmailAddress(ErrorMessage = "Invalid email format")]
public string Email { get; set; } = "";
}
}-
Update form component bindings:
# Find patterns like: # Value="@variable" ValueChanged="@handler" # Replace with: # @bind-Value="variable"
-
Remove obsolete ValueChanged handlers - no longer needed with
@bind-Value -
Add TValue for non-string types:
<TextInput TValue="int" @bind-Value="model.Age" Type="number" /> <TextInput TValue="decimal" @bind-Value="model.Price" />
-
Test forms inside EditForm - validation colors now appear automatically
-
Explicitly set Color if needed - if you don't want automatic validation colors:
<TextInput @bind-Value="model.Email" Color="TextInputColor.Gray" />
-
Verify build passes:
dotnet build
TextInput now supports debounced input for search-as-you-type scenarios:
<TextInput
@bind-Value="SearchQuery"
Behavior="InputBehavior.OnInput"
DebounceDelay="300"
Placeholder="Search..." />
@code {
private string SearchQuery { get; set; } = "";
// ValueChanged fires 300ms after user stops typing
}New services with on-demand module loading for reduced initial bundle size:
// Automatically registered via AddFlowbite(), or add individually:
services.AddFlowbiteClipboardService(); // IClipboardService
services.AddFlowbiteElementService(); // IElementService
services.AddFlowbiteFocusManagementService(); // IFocusManagementServiceSidebarCollapse now uses smooth height-based animations with a state machine:
- Four states:
Collapsed,Expanding,Expanded,Collapsing - Supports mid-animation toggle (reverse direction on click)
- Full nested collapse support
- Respects
prefers-reduced-motionpreference
Dropdown, Tooltip, and Combobox components now use @floating-ui/dom for viewport-aware positioning:
- Flip: Automatically changes placement when constrained by viewport
- Shift: Slides along the axis to stay within bounds
- Arrow positioning: Tooltip arrows adjust to actual placement
Enhanced keyboard support for Dropdown and Tooltip:
- Dropdown: ArrowUp/Down, Home/End, Enter/Space, Escape, type-ahead search
- Tooltip: Focus/blur handlers, Escape dismissal, ARIA linkage
The Style parameter on Button was renamed to Variant to free up Style for inline CSS styles. The ButtonStyle enum was also renamed to ButtonVariant.
Before:
<Button Style="ButtonStyle.Outline">Click me</Button>
<Button Style="ButtonStyle.Outline" Color="ButtonColor.Red">Delete</Button>After:
<Button Variant="ButtonVariant.Outline">Click me</Button>
<Button Variant="ButtonVariant.Outline" Color="ButtonColor.Red">Delete</Button>Find & Replace (two-step):
Style="ButtonStyle.→Variant="ButtonStyle.ButtonStyle.→ButtonVariant.
The Style parameter on Tooltip was renamed to Theme for the same reason.
Before:
<Tooltip Content="Hello" Style="light">
<Button>Light tooltip</Button>
</Tooltip>
<Tooltip Content="Hello" Style="dark">
<Button>Dark tooltip</Button>
</Tooltip>After:
<Tooltip Content="Hello" Theme="light">
<Button>Light tooltip</Button>
</Tooltip>
<Tooltip Content="Hello" Theme="dark">
<Button>Dark tooltip</Button>
</Tooltip>Find & Replace:
Style="light"→Theme="light"(on Tooltip elements)Style="dark"→Theme="dark"(on Tooltip elements)Style="auto"→Theme="auto"(on Tooltip elements)
Flowbite Blazor now requires Tailwind CSS v4.x with CSS-first configuration.
Before (Tailwind v3):
// tailwind.config.js
module.exports = {
content: ['./**/*.razor'],
theme: {
extend: {
colors: {
primary: { /* ... */ }
}
}
},
plugins: [require('flowbite/plugin')]
}After (Tailwind v4):
/* app.css */
@import "tailwindcss";
@config "./tailwind.config.js";
@plugin "flowbite/plugin";
@source "./**/*.{razor,html,cshtml,cs}";
@theme {
--color-primary-50: #eff6ff;
--color-primary-100: #dbeafe;
--color-primary-200: #bfdbfe;
--color-primary-300: #93c5fd;
--color-primary-400: #60a5fa;
--color-primary-500: #3b82f6;
--color-primary-600: #2563eb;
--color-primary-700: #1d4ed8;
--color-primary-800: #1e40af;
--color-primary-900: #1e3a8a;
--color-primary-950: #172554;
}// tailwind.config.js (minimal - just for dark mode)
module.exports = {
darkMode: 'class'
}What changed: TailwindMerge.NET now resolves conflicting Tailwind classes.
Before: Class="p-4" + component's p-2 rendered both p-2 p-4
After: Class="p-4" + component's p-2 renders p-4 only
Impact: User classes now properly override component defaults. Review any custom classes that relied on both appearing in the output.
If you need both classes (rare): Use arbitrary values: p-[8px] instead of p-2.
What changed: Dropdowns, tooltips, and popovers now use @floating-ui/dom for positioning.
Before (CSS-only): No repositioning; elements could overflow viewport After (@floating-ui): Smart positioning with automatic flip and shift
Impact: Elements auto-flip when near viewport edges and shift to stay visible. Test floating elements; behavior may differ near screen edges.
All components now inherit Style and AdditionalAttributes from FlowbiteComponentBase:
@* Inline styles *@
<Button Style="margin-top: 1rem; min-width: 200px">
Styled Button
</Button>
@* Data attributes *@
<Button data-testid="submit-btn" data-action="save">
Submit
</Button>
@* ARIA attributes *@
<Button aria-label="Close dialog" aria-pressed="false">
X
</Button>For component authors: Remove any duplicate AdditionalAttributes parameters from component subclasses - they're now inherited.
-
Update Button.Style to Button.Variant and ButtonStyle to ButtonVariant
# Step 1 - Fix property name: # Find: Style="ButtonStyle. # Replace: Variant="ButtonStyle. # Step 2 - Fix enum name: # Find: ButtonStyle. # Replace: ButtonVariant.
-
Update Tooltip.Style to Tooltip.Theme
# Find Tooltip elements with Style parameter and update: # Style="light" → Theme="light" # Style="dark" → Theme="dark" # Style="auto" → Theme="auto"
-
Migrate Tailwind CSS to v4
- Replace
tailwind.config.jscontent paths with@sourcein CSS - Move theme colors to
@themeblock in CSS - Keep minimal
tailwind.config.jsfordarkMode: 'class'
- Replace
-
Add Floating UI Script
<script src="https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.6.3/dist/floating-ui.dom.umd.min.js"></script>
-
Remove duplicate AdditionalAttributes (component authors only)
- If you created custom components inheriting from
FlowbiteComponentBase - Remove any
[Parameter(CaptureUnmatchedValues = true)] AdditionalAttributesdeclarations
- If you created custom components inheriting from
-
Verify build passes
dotnet build
-
Test your application to ensure components render correctly
Q: My dropdown appears in a different position than before. A: @floating-ui now auto-flips to stay in viewport. This is expected behavior and improves UX on smaller screens.
Q: Can I customize secondary/success/danger colors?
A: No, these are part of the Flowbite design system. Customize your primary brand color via @theme, and use the built-in semantic colors for consistency.
Q: The collapse animation is instant, not smooth.
A: Check if you or your users have "Reduce motion" enabled in OS settings. The library respects this accessibility preference via prefers-reduced-motion.
Q: TailwindMerge removed a class I needed.
A: TailwindMerge resolves conflicts by keeping the last class. If you need both (rare), use arbitrary values: p-[8px] instead of p-2.
Q: How do I migrate my custom Tailwind config? A: See the Tailwind v4 migration guide at https://tailwindcss.com/docs/upgrade-guide. Key changes:
tailwind.config.jstheme is replaced by CSS@themedirectiverequire()plugins replaced by@plugin- Content paths replaced by
@sourcedirective
Q: Will my existing component classes break?
A: Standard Tailwind classes work the same. Only conflicting classes (like p-2 p-4) are now resolved instead of both being applied.
Q: Do I need to add Floating UI for all components? A: Only if you use Dropdown, Tooltip, or Combobox components. If not, the script can be omitted.
No breaking changes.
Initial development releases. API stability not guaranteed.