A comprehensive Svelte wrapper library for Microsoft FluentUI web components (v2.6.x), providing a seamless way to use FluentUI components in Svelte applications.
- 🎨 Complete FluentUI Component Set - Wraps all major FluentUI web components
- 🔧 TypeScript Support - Full type definitions for all components
- 📱 Responsive Design - Built-in responsive layout components
- 🎯 Svelte 5 Compatible - Works with the latest Svelte features
- 🎨 SCSS & Tailwind CSS - Flexible styling options
- 📦 Tree-shakeable - Import only what you need
- ✨ FluentUI Blazor Inspired - Advanced components like DatePicker, TimePicker, InputFile, and Autocomplete
- 💾 Navigation Persistence - Sidebar menu state persists across page reloads with localStorage
- 🎯 Active Route Highlighting - Current page automatically highlighted in navigation
- 🔔 Toast Notifications - Programmatic toast service with multiple positions and auto-dismiss
- Navigation Persistence - Sidebar menu state automatically saved to localStorage and restored on page reload
- Active Route Highlighting - Current page is automatically highlighted in the navigation menu
- Toast Service - Programmatic notifications with
toast.success(),toast.error(), etc. - 6 positions, progress bars, auto-dismiss - DatePicker & TimePicker - Full-featured date and time selection with calendar popup and time picker
- InputFile - Drag-and-drop file upload with validation and progress tracking
- Autocomplete - Multiple selection with tag/chip display and async search support
- QuickGrid - Advanced data grid with sorting, filtering, and pagination
- Three-State Checkbox - Checkbox with indeterminate state support
- Responsive Layout - Complete layout system with Grid, Stack, and responsive components
npm install svelte-fluentui<script>
import { Button, TextField, Card } from 'svelte-fluentui'
</script>
<Card>
<TextField placeholder="Enter your name" />
<Button appearance="accent">Submit</Button>
</Card>Button- Various button styles and appearancesTextField- Text input with validationNumberField- Numeric input controlTextarea- Multi-line text inputCheckbox- Checkbox input with three-state supportRadio/RadioGroup- Radio button controlsSwitch- Toggle switchSelect- Dropdown selectionCombobox- Searchable dropdownAutocomplete- Multiple selection with tags/chips (inspired by FluentUI Blazor)Slider- Range slider controlSearch- Search input fieldDatePicker- Date selection with calendar popup (inspired by FluentUI Blazor)TimePicker- Time selection with hour/minute/second picker (inspired by FluentUI Blazor)InputFile- File upload with drag-drop and progress tracking (inspired by FluentUI Blazor)
DataGrid/DataGridRow/DataGridCell- Data table componentsQuickGrid- Advanced data grid with sorting, filtering, and paginationCard- Content containerBadge- Status indicatorsProgressBar- Progress indicationTooltip- Contextual informationCalendar- Date picker and calendarPaginator- Pagination control
Tabs/Tab/TabPanel- Tab navigationBreadcrumb/BreadcrumbItem- Breadcrumb navigationMenu/MenuItem- Context menusAppBar/AppBarItem- Application barNavMenu/NavItem/NavLink- Navigation componentsAnchor- Link component
Stack- Flexible layout containerLayout- Page layout wrapperHeader/Footer/BodyContent- Layout sectionsSpacer- Spacing utilityDivider- Visual separator
Dialog- Modal dialogsToast- Declarative notification messagesToastContainer+toast- Programmatic toast service (success, error, warning, info)Accordion/AccordionItem- Collapsible content
Listbox/Option- List selectionTree/TreeItem- Hierarchical dataToolbar- Action toolbars
<script>
import { TextField, Button, Stack } from 'svelte-fluentui'
let email = ''
let password = ''
</script>
<Stack orientation="vertical" gap="16">
<TextField
bind:value={email}
type="email"
placeholder="Enter email"
required
/>
<TextField
bind:value={password}
type="password"
placeholder="Enter password"
required
/>
<Button appearance="accent">Sign In</Button>
</Stack><script>
import { DataGrid, DataGridRow, DataGridCell } from 'svelte-fluentui'
const users = [
{ name: 'Alice', email: 'alice@example.com', role: 'Admin' },
{ name: 'Bob', email: 'bob@example.com', role: 'User' }
]
</script>
<DataGrid>
{#each users as user}
<DataGridRow>
<DataGridCell>{user.name}</DataGridCell>
<DataGridCell>{user.email}</DataGridCell>
<DataGridCell>{user.role}</DataGridCell>
</DataGridRow>
{/each}
</DataGrid><script lang="ts">
import { QuickGrid } from 'svelte-fluentui'
type User = {
id: number
name: string
email: string
role: string
}
const users: User[] = [
{ id: 1, name: 'Alice', email: 'alice@example.com', role: 'Admin' },
{ id: 2, name: 'Bob', email: 'bob@example.com', role: 'User' },
{ id: 3, name: 'Carol', email: 'carol@example.com', role: 'User' }
]
const columns = [
{ field: 'id', title: 'ID', width: '80px', sortable: true },
{ field: 'name', title: 'Name', sortable: true, filterable: true },
{ field: 'email', title: 'Email', filterable: true },
{ field: 'role', title: 'Role', sortable: true }
]
</script>
<QuickGrid
items={users}
{columns}
sortable
filterable
pageable
pageSize={10}
/><script>
import { Layout, Header, NavMenu, NavGroup, NavLinkItem, BodyContent } from 'svelte-fluentui'
import { page } from '$app/stores'
// Check if a link is active based on current route
function isActive(href: string): boolean {
if (!href) return false
if (href === "/" && $page.url.pathname === "/") return true
if (href !== "/" && $page.url.pathname.startsWith(href)) return true
return false
}
</script>
<Layout>
<Header slot="header">
<h1>My App</h1>
</Header>
<NavMenu slot="navigation">
<NavGroup title="Main Menu">
{#snippet linkText()}
Main Menu
{/snippet}
<NavLinkItem href="/" class={isActive("/") ? "active" : ""}>
Home
</NavLinkItem>
<NavLinkItem href="/about" class={isActive("/about") ? "active" : ""}>
About
</NavLinkItem>
<NavLinkItem href="/contact" class={isActive("/contact") ? "active" : ""}>
Contact
</NavLinkItem>
</NavGroup>
</NavMenu>
<BodyContent>
<!-- Main content here -->
</BodyContent>
</Layout><script>
import { DatePicker, TimePicker } from 'svelte-fluentui'
let selectedDate = $state<Date | null>(new Date())
let selectedTime = $state<string | null>("14:30")
</script>
<DatePicker
bind:value={selectedDate}
label="Select date"
placeholder="Choose a date"
/>
<TimePicker
bind:value={selectedTime}
label="Select time"
use24Hours={true}
showSeconds={false}
/><script lang="ts">
import { Autocomplete } from 'svelte-fluentui'
const options = [
{ value: "1", text: "Option 1" },
{ value: "2", text: "Option 2" },
{ value: "3", text: "Option 3" }
]
let selected = $state<string[]>([])
</script>
<Autocomplete
bind:selectedOptions={selected}
options={options}
label="Select multiple"
placeholder="Type to search..."
maxSelectedOptions={5}
/><script lang="ts">
import { InputFile } from 'svelte-fluentui'
import type { FileUploadHandler } from 'svelte-fluentui'
const uploadFile: FileUploadHandler = async (file, onProgress) => {
const formData = new FormData()
formData.append('file', file)
// Your upload logic here
// Call onProgress(percent) to update progress bar
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
})
if (!response.ok) throw new Error('Upload failed')
}
</script>
<InputFile
multiple={true}
accept="image/*"
maxFileSize={5 * 1024 * 1024}
uploadFileCallback={uploadFile}
onFileUploaded={(file) => console.log('Uploaded:', file.name)}
/><script>
import { ToastContainer, toast } from 'svelte-fluentui'
function showSuccess() {
toast.success('Operation completed successfully!')
}
function showError() {
const id = toast.error('Something went wrong', {
persistent: true,
position: 'top-center'
})
// Later: toast.dismiss(id)
}
function showWithProgress() {
toast.info('Processing your request...', {
showProgress: true,
duration: 8000
})
}
</script>
<!-- Add once in your layout -->
<ToastContainer />
<button onclick={showSuccess}>Show Success</button>
<button onclick={showError}>Show Error</button>
<button onclick={showWithProgress}>Show With Progress</button>Clone the repository and install dependencies:
git clone https://github.com/KeenMate/svelte-fluentui.git
cd svelte-fluentui
npm installThe library source code is in src/lib/. To package the library:
npm run packageThe documentation site is in the docs/ folder as a separate SvelteKit project:
cd docs
npm install
npm run devOr use the Makefile:
make dev # Runs docs dev serverVisit http://localhost:5173 to see the component showcase and examples.
Build the library for publishing:
npm run buildBuild documentation Docker image:
# With local source
make docker-build-docs
# With specific npm version
make docker-build-docs VERSION=1.0.0-rc03Contributions are welcome! Please feel free to submit a Pull Request.
MIT © KeenMate
Built on top of Microsoft FluentUI Web Components v2.6.x.