UI 컴포넌트 라이브러리
MudBlazor 등 오픈소스 UI 라이브러리를 설치하고 기성 컴포넌트를 활용합니다.
📌 학습 목표
- Blazor에서 UI 컴포넌트 라이브러리가 필요한 이유를 설명할 수 있다.
- MudBlazor를 Blazor 프로젝트에 올바르게 설치·등록할 수 있다.
- MudButton, MudTextField, MudDataGrid 등 핵심 컴포넌트를 실제로 사용할 수 있다.
- 테마 커스터마이징으로 색상·폰트를 프로젝트에 맞게 조정할 수 있다.
- 여러 UI 라이브러리 옵션을 비교하고 프로젝트 성격에 맞는 것을 선택할 수 있다.
📝 개념 설명
1. UI 컴포넌트 라이브러리란?
UI 컴포넌트 라이브러리는 버튼·입력창·테이블·모달 등 반복적으로 쓰이는 UI 요소들을 미리 만들어둔 패키지입니다. 처음부터 CSS와 JavaScript로 모든 것을 직접 만드는 대신, 검증된 컴포넌트를 가져다 쓰면 개발 시간을 크게 줄이고 디자인 일관성도 확보할 수 있습니다.
Blazor 생태계에는 여러 UI 라이브러리가 존재합니다. 그 중 MudBlazor는 Material Design 기반으로, 무료 오픈소스이며 Blazor 전용으로 설계되어 가장 널리 사용됩니다.
| 항목 | MudBlazor | Radzen Blazor | Blazorise |
|---|---|---|---|
| 라이선스 | MIT (무료) | MIT (무료) | MIT (무료) |
| 디자인 기반 | Material Design | 자체 + Bootstrap 지원 | Bootstrap / Tailwind |
| 컴포넌트 수 | 100+ (풍부) | 70+ | 80+ |
| 데이터그리드 | MudDataGrid (강력) | DataGrid (강력) | DataGrid (기본) |
| CSS 의존성 | 자체 포함 | 자체 포함 | Bootstrap 필요 |
| 추천 상황 | 범용 Material 스타일 | 엔터프라이즈·대시보드 | Bootstrap 기반 프로젝트 |
2. MudBlazor 설치 및 초기 설정
MudBlazor 설치는 크게 패키지 설치 → 서비스 등록 → CSS/JS 참조 추가 세 단계로 이루어집니다.
2-1. NuGet 패키지 설치
# .NET CLI 사용 시
dotnet add package MudBlazor
# 또는 Visual Studio의 NuGet 패키지 관리자에서 'MudBlazor' 검색 후 설치
2-2. 서비스 등록 (Program.cs)
using MudBlazor.Services;
var builder = WebApplication.CreateBuilder(args);
// Blazor Server 또는 WebAssembly 서비스 등록 다음에 추가
builder.Services.AddMudServices();
var app = builder.Build();
// ... (이하 생략)
2-3. CSS · JS 참조 추가
Blazor Server의 경우 App.razor 또는 _Layout.cshtml의 <head> 안에 다음을 추가합니다.
<!-- MudBlazor CSS -->
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
<link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />
<!-- MudBlazor JS (body 닫기 태그 바로 위) -->
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
2-4. 필수 Provider 추가 (App.razor 또는 MainLayout.razor)
MudBlazor의 Snackbar(알림), Dialog(모달) 등이 제대로 작동하려면 최상위 레이아웃에 Provider 컴포넌트를 배치해야 합니다.
<!-- MainLayout.razor 또는 App.razor 최상위에 배치 -->
<MudThemeProvider />
<MudDialogProvider />
<MudSnackbarProvider />
@Body
2-5. _Imports.razor에 using 추가
@using MudBlazor
3. 핵심 컴포넌트 사용법
3-1. MudButton
<MudButton Variant='Variant.Filled' Color='Color.Primary' OnClick='HandleClick'>
저장
</MudButton>
<MudButton Variant='Variant.Outlined' Color='Color.Secondary' StartIcon='@Icons.Material.Filled.Delete'>
삭제
</MudButton>
@code {
void HandleClick()
{
Console.WriteLine("버튼 클릭!");
}
}
- Variant: Filled(채움), Outlined(테두리), Text(텍스트 전용) 중 선택
- Color: Primary, Secondary, Success, Warning, Error, Info 등 테마 색상 사용
- StartIcon / EndIcon: Material Icons를 버튼 앞뒤에 배치
3-2. MudTextField — 입력 폼
@page "/contact"
<MudTextField @bind-Value='name' Label='이름' Variant='Variant.Outlined' />
<MudTextField @bind-Value='email' Label='이메일' InputType='InputType.Email' />
<MudTextField @bind-Value='message' Label='메시지' Lines='4' />
<MudButton OnClick='Submit' Color='Color.Primary' Variant='Variant.Filled'>제출</MudButton>
@code {
string name = "";
string email = "";
string message = "";
void Submit()
{
Console.WriteLine($"이름: {name}, 이메일: {email}");
}
}
3-3. MudSelect — 드롭다운 선택
<MudSelect T='string' @bind-Value='selectedCity' Label='도시 선택'>
<MudSelectItem Value='"Seoul"'>서울</MudSelectItem>
<MudSelectItem Value='"Busan"'>부산</MudSelectItem>
<MudSelectItem Value='"Incheon"'>인천</MudSelectItem>
</MudSelect>
@code {
string selectedCity = "Seoul";
}
3-4. MudDataGrid — 데이터 테이블
@using MudBlazor
<MudDataGrid T='Employee' Items='employees' Filterable='true' SortMode='SortMode.Multiple'>
<Columns>
<PropertyColumn Property='e => e.Name' Title='이름' />
<PropertyColumn Property='e => e.Department' Title='부서' />
<PropertyColumn Property='e => e.Salary' Title='급여' Format='N0' />
</Columns>
</MudDataGrid>
@code {
List<Employee> employees = new()
{
new() { Name = "김민준", Department = "개발", Salary = 5000000 },
new() { Name = "이서연", Department = "기획", Salary = 4500000 },
new() { Name = "박도현", Department = "디자인", Salary = 4200000 },
};
record Employee(string Name = "", string Department = "", int Salary = 0);
}
Filterable='true' 한 줄로 각 열에 필터 입력창이 자동 생성됩니다. SortMode='SortMode.Multiple'로 다중 열 정렬도 기본 지원합니다.3-5. MudDialog — 모달 대화상자
@* 모달을 여는 페이지 *@
@inject IDialogService DialogService
<MudButton OnClick='OpenDialog'>대화상자 열기</MudButton>
@code {
async Task OpenDialog()
{
var options = new DialogOptions { CloseOnEscapeKey = true };
DialogService.Show<ConfirmDialog>("확인", options);
}
}
@* ConfirmDialog.razor *@
<MudDialog>
<TitleContent><MudText Typo='Typo.h6'>정말 삭제하시겠습니까?</MudText></TitleContent>
<DialogContent><MudText>이 작업은 되돌릴 수 없습니다.</MudText></DialogContent>
<DialogActions>
<MudButton OnClick='Cancel'>취소</MudButton>
<MudButton Color='Color.Error' OnClick='Confirm'>삭제</MudButton>
</DialogActions>
</MudDialog>
@code {
[CascadingParameter] MudDialogInstance MudDialog { get; set; } = null!;
void Cancel() => MudDialog.Cancel();
void Confirm() => MudDialog.Close(DialogResult.Ok(true));
}
3-6. MudSnackbar — 알림 메시지
@inject ISnackbar Snackbar
<MudButton OnClick='ShowNotification'>알림 보내기</MudButton>
@code {
void ShowNotification()
{
Snackbar.Add("저장이 완료되었습니다!", Severity.Success);
// Severity: Success, Warning, Error, Info, Normal
}
}
4. 테마 커스터마이징
MudBlazor는 MudTheme 객체를 통해 전체 앱의 색상·폰트·모서리 둥글기 등을 일괄 설정할 수 있습니다.
@* App.razor 또는 MainLayout.razor *@
<MudThemeProvider Theme='myTheme' />
@code {
MudTheme myTheme = new MudTheme()
{
Palette = new PaletteLight()
{
Primary = "#1976D2", // 주색상 (파란색 계열)
Secondary = "#FF4081", // 보조색상
AppbarBackground = "#1565C0",
Background = "#F5F5F5",
},
Typography = new Typography()
{
Default = new Default()
{
FontFamily = new[] { "Noto Sans KR", "Roboto", "sans-serif" },
}
},
LayoutProperties = new LayoutProperties()
{
DefaultBorderRadius = "8px"
}
};
}
5. MudLayout으로 앱 레이아웃 구성
MudBlazor는 AppBar(상단바) · Drawer(사이드바) · MainContent를 포함한 완성된 레이아웃 컴포넌트도 제공합니다.
@* MainLayout.razor *@
<MudLayout>
<MudAppBar Color='Color.Primary' Fixed='true'>
<MudIconButton Icon='@Icons.Material.Filled.Menu' Color='Color.Inherit' Edge='Edge.Start'
OnClick='ToggleDrawer' />
<MudText Typo='Typo.h6'>내 Blazor 앱</MudText>
<MudSpacer />
<MudIconButton Icon='@Icons.Material.Filled.AccountCircle' Color='Color.Inherit' />
</MudAppBar>
<MudDrawer @bind-Open='drawerOpen' Variant='DrawerVariant.Responsive'>
<MudNavMenu>
<MudNavLink Href='/' Icon='@Icons.Material.Filled.Home'>홈</MudNavLink>
<MudNavLink Href='/products' Icon='@Icons.Material.Filled.Inventory'>상품 목록</MudNavLink>
<MudNavLink Href='/settings' Icon='@Icons.Material.Filled.Settings'>설정</MudNavLink>
</MudNavMenu>
</MudDrawer>
<MudMainContent>
<MudContainer MaxWidth='MaxWidth.ExtraLarge' Class='pa-4'>
@Body
</MudContainer>
</MudMainContent>
</MudLayout>
@code {
bool drawerOpen = true;
void ToggleDrawer() => drawerOpen = !drawerOpen;
}
💡 예제 & 실습 — 직원 관리 미니 앱
지금까지 배운 MudBlazor 컴포넌트를 조합해 간단한 직원 관리 페이지를 만들어 봅니다.
@page "/employees"
@inject ISnackbar Snackbar
@inject IDialogService DialogService
<MudText Typo='Typo.h4' Class='mb-4'>직원 관리</MudText>
<MudPaper Class='pa-4 mb-4'>
<MudGrid>
<MudItem xs='12' md='4'>
<MudTextField @bind-Value='newName' Label='이름' Variant='Variant.Outlined' FullWidth='true' />
</MudItem>
<MudItem xs='12' md='4'>
<MudSelect T='string' @bind-Value='newDept' Label='부서' Variant='Variant.Outlined'>
<MudSelectItem Value='"개발"'>개발</MudSelectItem>
<MudSelectItem Value='"기획"'>기획</MudSelectItem>
<MudSelectItem Value='"디자인"'>디자인</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs='12' md='4' Class='d-flex align-center'>
<MudButton Variant='Variant.Filled' Color='Color.Primary'
StartIcon='@Icons.Material.Filled.PersonAdd'
OnClick='AddEmployee' FullWidth='true'>
직원 추가
</MudButton>
</MudItem>
</MudGrid>
</MudPaper>
<MudDataGrid T='Employee' Items='employees' Filterable='true' Hover='true' Striped='true'>
<Columns>
<PropertyColumn Property='e => e.Id' Title='ID' />
<PropertyColumn Property='e => e.Name' Title='이름' />
<PropertyColumn Property='e => e.Department' Title='부서' />
<TemplateColumn Title='작업'>
<CellTemplate>
<MudIconButton Icon='@Icons.Material.Filled.Delete'
Color='Color.Error' Size='Size.Small'
OnClick='() => DeleteEmployee(context.Item)' />
</CellTemplate>
</TemplateColumn>
</Columns>
</MudDataGrid>
@code {
record Employee(int Id, string Name, string Department);
List<Employee> employees = new()
{
new(1, "김민준", "개발"),
new(2, "이서연", "기획"),
};
string newName = "";
string newDept = "개발";
int nextId = 3;
void AddEmployee()
{
if (string.IsNullOrWhiteSpace(newName))
{
Snackbar.Add("이름을 입력하세요.", Severity.Warning);
return;
}
employees.Add(new(nextId++, newName, newDept));
newName = "";
Snackbar.Add("직원이 추가되었습니다!", Severity.Success);
}
void DeleteEmployee(Employee emp)
{
employees.Remove(emp);
Snackbar.Add($"{emp.Name} 직원이 삭제되었습니다.", Severity.Info);
}
}
위 코드는 MudGrid(반응형 레이아웃), MudTextField, MudSelect, MudButton, MudDataGrid, MudSnackbar를 모두 조합한 완성된 CRUD 예제입니다. 별도 CSS 작성 없이도 깔끔한 Material Design UI가 완성됩니다.
dotnet add package MudBlazor
Program.cs
AddMudServices()
App.razor
<head> 안에 추가
MainLayout.razor
Dialog·Snackbar Provider
_Imports.razor
@using MudBlazor
⚠️ 자주 틀리는 것 / 주의사항
<MudThemeProvider />, <MudDialogProvider />, <MudSnackbarProvider /> 세 가지를 MainLayout.razor 최상위에 반드시 배치하세요. 하나라도 누락되면 해당 기능이 렌더링 되지 않습니다.MudBlazor.min.css는 <head> 안에, MudBlazor.min.js는 </body> 직전에 배치해야 합니다. 반대로 하거나 body 안 다른 위치에 두면 아이콘·애니메이션이 작동하지 않습니다.<MudDataGrid T='Employee' Items='employees'>처럼 T='...'를 생략하면 컴파일 에러가 발생합니다. Blazor 컴포넌트가 어떤 타입의 데이터를 처리하는지 컴파일러가 추론하지 못하기 때문입니다.AddMudServices()를 호출하면 이 두 서비스가 의존성 주입(DI) 컨테이너에 자동 등록됩니다. 사용하는 컴포넌트 파일 상단에 @inject ISnackbar Snackbar처럼 반드시 선언해야 합니다.Primary = Color.Blue가 아니라 Primary = "#1976D2"처럼 HEX 문자열로 지정해야 합니다. Color 열거형은 컴포넌트 속성에서만 사용하며 테마 팔레트에서는 문자열을 씁니다.Blazor 프로젝트 기본 템플릿은 Bootstrap CSS를 포함합니다. MudBlazor를 도입하면 Bootstrap의 버튼·폼 스타일이 MudBlazor 스타일과 충돌할 수 있으므로, Bootstrap CSS 참조를 제거하거나 MudBlazor 전용 레이아웃으로 완전히 전환하는 것이 좋습니다.
🎯 마무리
MudBlazor는 Blazor 개발에서 가장 검증된 오픈소스 UI 라이브러리입니다. NuGet 설치 → 서비스 등록 → CSS·JS 참조 → Provider 배치 → _Imports.razor 설정의 다섯 단계만 완료하면 100개 이상의 고품질 컴포넌트를 즉시 사용할 수 있습니다.
버튼·입력창·선택박스·데이터그리드·모달·알림 등 웹 앱의 핵심 UI 요소가 모두 기성 컴포넌트로 제공되므로, 직접 CSS를 작성하는 시간 대신 비즈니스 로직 구현에 집중할 수 있다는 것이 가장 큰 장점입니다. MudTheme를 통한 전역 테마 설정으로 브랜드 색상을 일괄 적용하는 것도 잊지 마세요.
- MudBlazor는 Material Design 기반의 Blazor 전용 오픈소스 UI 라이브러리로, 100개 이상의 컴포넌트를 무료 제공한다.
- 설치는 NuGet →
AddMudServices()→ CSS·JS 참조 → Provider 3종 배치 →@using MudBlazor순서로 진행한다. MudDialogProvider와MudSnackbarProvider를 MainLayout에 배치하지 않으면 모달·알림 기능이 작동하지 않는다.- MudDataGrid는
Filterable='true'만으로 자동 필터 UI를 제공하며, 제네릭 타입T='...'지정이 필수다. - MudTheme 객체로 Primary·Secondary 색상, 폰트, 모서리 둥글기를 전역 일괄 설정할 수 있다.
- MudBlazor와 Bootstrap CSS를 함께 사용하면 스타일 충돌이 발생할 수 있으므로 Bootstrap 참조를 제거하는 것이 권장된다.