flowind-design-system
v1.0.8
Published
A comprehensive design system built with Svelte and Tailwind CSS
Maintainers
Readme
flowind-design-system
A comprehensive design system built with Svelte 5 and Tailwind CSS 4. This package provides reusable UI components and design tokens for building consistent web applications.
🚀 Features
- 10 Core Components: Button, Card, Input, Badge, Form, Tabs, Accordion, Modal, Table, and Text
- Custom Design Tokens: Comprehensive color palette, typography, spacing, and shadow system
- TypeScript Support: Full type safety for all components and props
- Accessibility: WCAG 2.1 AA compliant components
- Responsive Design: Mobile-first approach with flexible layouts
- Dark Mode: Built-in dark mode support with automatic theme switching
- Svelte 5: Uses modern Svelte 5 syntax with snippets and runes
🛠️ Tech Stack
- Svelte 5: Modern reactive framework with snippets and runes
- Tailwind CSS 4: Latest utility-first CSS framework
- TypeScript: Type safety and better developer experience
- Tailwind Variants: Type-safe component styling
📦 Installation
npm install flowind-design-system🎨 Setup
Required CSS Configuration
You must add this to your main CSS file (e.g., app.css or global.css):
@import 'tailwindcss';
@import 'flowind-design-system/theme.css';
@custom-variant dark (&:where(.dark, .dark *));
@source "../../node_modules/flowind-design-system/dist";This setup:
- Imports Tailwind CSS 4
- Imports our custom theme with design tokens
- Configures dark mode support
- Sources our component styles from the package
Tailwind Configuration
Make sure your tailwind.config.js includes the design system:
/** @type {import('tailwindcss').Config} */
export default {
content: [
'./src/**/*.{html,js,svelte,ts}',
'./node_modules/flowind-design-system/dist/**/*.{js,ts}'
],
darkMode: 'class', // or 'media'
theme: {
extend: {
// Your custom theme extensions
}
},
plugins: []
};🎯 Components
Button
<script>
import { Button } from 'flowind-design-system';
</script>
<Button variant="primary" size="md" loading={false} disabled={false}>Click me</Button>Props:
variant:'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'error' | 'outline' | 'ghost'- Button style variantsize:'xs' | 'sm' | 'md' | 'lg' | 'xl'- Button sizeloading:boolean- Shows loading spinner when truedisabled:boolean- Disables the buttonfullWidth:boolean- Makes button full widthchildren:Snippet- Button content (should be a snippet)onclick:(event: MouseEvent) => void- Click handleronkeydown:(event: KeyboardEvent) => void- Keyboard handleraria-label:string- Accessibility label
Card
<script>
import { Card } from 'flowind-design-system';
</script>
<Card variant="elevated" padding="lg">
<h3>Title</h3>
<p>Content</p>
</Card>Props:
variant:'default' | 'elevated' | 'outlined' | 'flat'- Card style variantpadding:'none' | 'sm' | 'md' | 'lg' | 'xl'- Card paddinghover:boolean- Add hover effectsinteractive:boolean- Make card interactivechildren:Snippet- Card content (should be a snippet)
Input
<script>
import { Input } from 'flowind-design-system';
</script>
<Input
label="Email"
placeholder="Enter email..."
helperText="We'll never share your email"
variant="default"
size="md"
type="email"
/>Props:
label:string- Input labelplaceholder:string- Placeholder texthelperText:string- Helper text below inputvariant:'default' | 'success' | 'error'- Input style variantsize:'xs' | 'sm' | 'md' | 'lg' | 'xl'- Input sizetype:string- Input type (text, email, password, etc.)error:boolean- Shows error statesuccess:boolean- Shows success state
Badge
<script>
import { Badge } from 'flowind-design-system';
</script>
<Badge variant="primary" size="md" removable>New</Badge>Props:
variant:'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'error' | 'info'- Badge style variantremovable:boolean- Shows remove buttononRemove:() => void- Remove button click handlerchildren:Snippet- Badge content (should be a snippet)
Text
<script>
import { Text } from 'flowind-design-system';
</script>
<Text variant="h4" as="h4" color="primary">Heading Text</Text>Props:
variant:'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'body' | 'bodySmall' | 'meta'- Text style variantas:keyof HTMLElementTagNameMap- HTML element to rendercolor:'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'error'- Text coloralign:'left' | 'center' | 'right' | 'justify'- Text alignmentweight:'normal' | 'medium' | 'semibold' | 'bold'- Font weighttruncate:boolean- Truncate text with ellipsisitalic:boolean- Italic textunderline:boolean- Underlined textlineThrough:boolean- Strikethrough textnoWrap:boolean- Prevent text wrappingchildren:Snippet- Text content (should be a snippet)
Form
<script>
import { Form, Input, Button } from 'flowind-design-system';
function handleSubmit(formData) {
console.log('Form submitted:', formData);
}
</script>
<Form layout="vertical" spacing="lg" onSubmit={handleSubmit}>
<Input label="Name" placeholder="Enter your name" />
<Input label="Email" type="email" placeholder="Enter your email" />
<Button variant="primary">Submit</Button>
</Form>Props:
layout:'vertical' | 'horizontal' | 'inline'- Form layout directionspacing:'sm' | 'md' | 'lg' | 'xl'- Spacing between form elementsonSubmit:(formData: FormData) => void- Form submission handlerchildren:Snippet- Form content (should be a snippet)
Tabs
<script>
import { Tabs } from 'flowind-design-system';
</script>
{#snippet tabOneContent()}
<div>
<h3>First Tab Content</h3>
<p>This is the content for the first tab.</p>
</div>
{/snippet}
{#snippet tabTwoContent()}
<div>
<h3>Second Tab Content</h3>
<p>This is the content for the second tab.</p>
</div>
{/snippet}
<Tabs
items={[
{ id: 'one', label: 'First Tab', content: tabOneContent },
{ id: 'two', label: 'Second Tab', content: tabTwoContent }
]}
activeId="one"
position="top"
/>Props:
items:{ id: string; label: string; content: Snippet }[]- Array of tab itemsactiveId:string- Currently active tab IDposition:'top' | 'bottom' | 'left' | 'right'- Tab position
Accordion
<script>
import { Accordion } from 'flowind-design-system';
</script>
{#snippet faqOneContent()}
<div>
<p>Flowind is a comprehensive design system built with Svelte 5 and Tailwind CSS 4.</p>
</div>
{/snippet}
{#snippet faqTwoContent()}
<div>
<p>Components can be customized through CSS custom properties and Tailwind classes.</p>
</div>
{/snippet}
<Accordion
items={[
{
id: 'faq-1',
title: 'What is Flowind Design System?',
content: faqOneContent
},
{
id: 'faq-2',
title: 'How do I customize components?',
content: faqTwoContent
}
]}
multiple={false}
flush={false}
arrowPosition="right"
/>Props:
items:{ id: string; title: string; content: Snippet; open?: boolean }[]- Array of accordion itemsvariant:'default' | 'elevated' | 'outlined' | 'flat'- Accordion style variantmultiple:boolean- Allow multiple items to be open simultaneouslyflush:boolean- Remove borders and spacingarrowPosition:'left' | 'right'- Position of the expand/collapse arrowonItemToggle:(event: { itemId: string; isOpen: boolean }) => void- Item toggle callback
Modal
<script>
import { Modal, Button, Text } from 'flowind-design-system';
let isOpen = false;
</script>
{#snippet modalBody()}
<div>
<p>This is the modal body content. You can include any components or content here.</p>
</div>
{/snippet}
{#snippet modalFooter()}
<div class="flex justify-end gap-2">
<Button variant="outline" onclick={() => (isOpen = false)}>Cancel</Button>
<Button variant="primary" onclick={() => (isOpen = false)}>Confirm</Button>
</div>
{/snippet}
<Modal
bind:open={isOpen}
title="Confirm Action"
size="md"
position="center"
body={modalBody}
footer={modalFooter}
/>Props:
open:boolean- Controls modal visibilitytitle:string- Modal titlesize:'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl'- Modal sizeposition:'center' | 'top' | 'bottom' | 'left' | 'right'- Modal positionclosable:boolean- Show close buttononClose:() => void- Close button click handlerbody:Snippet- Modal body content (should be a snippet)footer:Snippet- Modal footer content (should be a snippet)header:Snippet- Custom header content (should be a snippet)
Table
<script>
import { Table, Text } from 'flowind-design-system';
import type { TableRow } from 'flowind-design-system';
const columns = [
{ key: 'name', label: 'Name', sortable: true, width: '40%' },
{ key: 'type', label: 'Type', sortable: true, width: '25%' },
{ key: 'size', label: 'Size', sortable: true, width: '15%' },
{ key: 'modified', label: 'Modified', sortable: true, width: '20%' }
];
const rows: TableRow[] = [
{
id: '1',
type: 'folder',
data: { name: 'Documents', type: 'Folder', size: '—', modified: '2024-01-16' },
expanded: false,
children: [
{
id: '1-1',
type: 'folder',
data: { name: 'Projects', type: 'Folder', size: '—', modified: '2024-01-15' },
expanded: false,
children: [
{
id: '1-1-1',
type: 'file',
data: {
name: 'project-docs.pdf',
type: 'PDF Document',
size: '2.3 MB',
modified: '2024-01-15'
},
expandedContent: fileDetailsContent
}
]
},
{
id: '1-2',
type: 'file',
data: { name: 'notes.txt', type: 'Text File', size: '1.2 KB', modified: '2024-01-14' },
expandedContent: fileDetailsContent
}
]
},
{
id: '2',
type: 'file',
data: { name: 'report.xlsx', type: 'Excel File', size: '3.1 MB', modified: '2024-01-13' },
expandedContent: fileDetailsContent
}
];
</script>
{#snippet fileDetailsContent()}
<div class="space-y-3 rounded-lg bg-gray-50 p-4 dark:bg-gray-700">
<Text variant="h6" color="primary">File Details</Text>
<div class="grid grid-cols-2 gap-4 text-sm">
<div>
<Text variant="bodySmall" color="secondary">Created: 2024-01-15</Text>
<Text variant="bodySmall" color="secondary">Modified: 2024-01-16</Text>
</div>
<div>
<Text variant="bodySmall" color="secondary">Owner: Current User</Text>
<Text variant="bodySmall" color="secondary">Permissions: Read/Write</Text>
</div>
</div>
</div>
{/snippet}
<Table
{columns}
{rows}
sortable={true}
expandable={true}
striped={true}
hoverable={true}
variant="default"
/>Props:
columns:TableColumn[]- Array of column definitions withkey,label,sortable,width,alignrows:TableRow[]- Array of row data withid,data,type,expanded,children,expandedContentsortable:boolean- Enable column sortingexpandable:boolean- Enable row expansionstriped:boolean- Add striped stylinghoverable:boolean- Add hover effectsvariant:'default' | 'elevated' | 'outlined' | 'flat'- Table style variant
🎨 Design Tokens
Color Palette
Our design system includes a comprehensive color palette:
- Primary: Blue shades (50-950) for main actions and brand elements
- Secondary: Gray shades (50-950) for text and neutral elements
- Accent: Purple shades (50-950) for highlights and accents
- Semantic: Success (green), Warning (orange), Error (red)
Typography
- Fonts: Inter (UI), Poppins (Display), Merriweather (Serif), JetBrains Mono (Code)
- Scale: xs (12px) to 5xl (48px) with consistent line heights
Spacing
- Base Unit: 4px (0.25rem)
- Scale: 0px to 96px using Tailwind's spacing system
📚 API Reference
Style Functions
All components include helper functions for building custom classes:
import {
buildButtonClasses,
buildCardClasses,
buildInputClasses,
buildBadgeClasses,
buildTextClasses,
buildFormClasses,
buildTabsClasses,
buildAccordionClasses,
buildModalClasses,
buildTableClasses
} from 'flowind-design-system';
const buttonClasses = buildButtonClasses({
variant: 'primary',
size: 'lg',
disabled: false
});Style Objects
Access raw style objects for custom implementations:
import {
buttonStyles,
cardStyles,
inputStyles,
badgeStyles,
textStyles,
formStyles,
tabsStyles,
accordionStyles,
modalStyles,
tableStyles
} from 'flowind-design-system';🤝 Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
📄 License
MIT License - see LICENSE file for details.
🆘 Support
For support and questions:
- Create an issue on GitHub
- Check the documentation
- Review the Storybook examples
