8000 GitHub - nemanjavlahovic/FloeKit: Elegant, modular UI building blocks for SwiftUI β€” design system, components, and utilities with built-in theming and accessibility
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Elegant, modular UI building blocks for SwiftUI β€” design system, components, and utilities with built-in theming and accessibility

Notifications You must be signed in to change notification settings

nemanjavlahovic/FloeKit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

37 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

FloeKit

7a368114-cc08-48e8-99fa-a7b060ece85c

Elegant, modular UI building blocks for SwiftUI

Inspired by floating ice sheets, FloeKit provides calm, elegant, and modular UI components designed for composability, design clarity, and reuse. It positions itself as a thoughtful layer on top of SwiftUI, offering a consistent design system with built-in theming, spacing, and typography.

Swift Platform SPM

πŸ“‹ Table of Contents

✨ Features

  • 🎨 Consistent Design System - Unified colors, typography, spacing, and shadows
  • πŸ“± Cross-Platform - Works seamlessly on iOS and macOS
  • πŸŒ— Perfect Dark Mode - βœ… Complete - All components tested and beautiful in both light and dark modes
  • β™Ώ Accessibility First - Built-in VoiceOver, Dynamic Type, and comprehensive accessibility support
  • πŸ—οΈ Advanced Architecture - Result builders, preference keys, haptic feedback, and sophisticated animations
  • πŸ”§ Highly Customizable - Override any aspect while maintaining design consistency
  • ⚑ Performance Optimized - Efficient SwiftUI implementation with smooth 60fps animations
  • πŸ“¦ Zero Dependencies - Pure SwiftUI implementation with no external dependencies
  • 🎯 Production Ready - Battle-tested components with proper error handling and edge cases

πŸš€ Installation

Swift Package Manager

Add FloeKit to your project through Xcode:

  1. File β†’ Add Package Dependencies
  2. Enter package URL: https://github.com/nemanjavlahovic/FloeKit
  3. Select version and add to target

Or add to your Package.swift:

dependencies: [
    .package(url: "https://github.com/nemanjavlahovic/FloeKit", from: "0.3.0")
]

🧱 Components

FloeButton

Soft, elevated buttons with multiple sizes, loading states, and icon support.

FloeButton Examples

import FloeKit

// Basic button
FloeButton("Get Started") {
    // Action
}

// Button with icon and custom styling
// Note: Parameters can be specified in any order using named parameters
FloeButton("Save", 
          size: .large,
          backgroundColor: .blue,
          textColor: .white,
          icon: Image(systemName: "checkmark")) {
    // Save action
}

// Loading state
FloeButton("Processing...", isLoading: true) {
    // Action
}

Sizes: .small, .medium, .large
Features: Loading states, icons, custom colors, accessibility support


FloeTextField

Elegant text input with focus states, icons, validation, and character limits.

FloeTextField Examples

@State private var email = ""
@State private var password = ""
@State private var bio = ""

// Basic text field
FloeTextField(text: $email, placeholder: "Email address")

// With icons and validation
FloeTextField(
    text: $email,
    placeholder: "Enter email",
    leadingIcon: Image(systemName: "envelope"),
    errorMessage: "Invalid email format"
)

// Secure field
FloeTextField(
    text: $password,
    placeholder: "Password",
    leadingIcon: Image(systemName: "lock"),
    isSecure: true
)

// With character limit
FloeTextField(
    text: $bio,
    placeholder: "Bio",
    characterLimit: 150
)

Features: Icons, secure input, validation, character limits, focus states


FloeCard

Clean, elevated containers with consistent shadows and padding.

FloeCard Examples

FloeCard {
    VStack {
        Text("Card Title")
            .floeFont(.headline)
        Text("Card content goes here")
            .floeFont(.body)
    }
}

// Custom styling
FloeCard(backgroundColor: .blue.opacity(0.1),
         shadowStyle: .elevated,
         padding: .spacious) {
    // Content
}

Features: Customizable shadows, padding presets, border support


FloeAvatar

Elegant, customizable avatar components with status indicators and grouping support.

FloeAvatar Examples

// Basic avatars
FloeAvatar.initials("JD")
FloeAvatar.icon("person.fill")
FloeAvatar.placeholder()

// With image
FloeAvatar(image: Image("user-photo"))

// Different sizes
FloeAvatar.initials("SM", size: .small)
FloeAvatar.initials("LG", size: .large)
FloeAvatar.initials("XL", size: .extraLarge)

// With status indicators
FloeAvatar.online(initials: "ON")
FloeAvatar(initials: "AW", statusIndicator: .away)
FloeAvatar(initials: "BY", statusIndicator: .busy)
FloeAvatar(initials: "CT", statusIndicator: .custom(.purple))

// Custom styling
FloeAvatar(
    initials: "VIP",
    backgroundColor: .black,
    foregroundColor: .yellow,
    borderColor: .yellow,
    borderWidth: 2,
    shadowStyle: .elevated
)

// Interactive avatars
FloeAvatar.initials("TAP") {
    print("Avatar tapped!")
}

Grouped Avatars:

// Stacked avatars with overlap
FloeAvatarGroup(
    avatars: [avatar1, avatar2, avatar3],
    style: .stacked,
    maxVisible: 3
)

// Grid layout
FloeAvatarGroup(
    avatars: avatarArray,
    style: .grid(columns: 2)
)

Sizes: .small, .medium, .large, .extraLarge
Status: Online, offline, away, busy, custom colors
Features: Images, initials, SF Symbols, borders, shadows, tap actions, grouping


FloeToast (New)

Lightweight, animated toast notifications with swipe-to-dismiss and customizable styles.

@StateObject private var toastManager = FloeToastManager()

// Basic usage with convenience methods
.floeToast(FloeToast.success("Success!", message: "Operation completed"))
.floeToast(FloeToast.error("Error!", message: "Something went wrong"))
.floeToast(FloeToast.warning("Warning!", message: "Please check your input"))
.floeToast(FloeToast.info("Info", message: "New update available"))

// Custom toast with action
FloeToast("Custom Toast",
          message: "With action button",
          style: .custom(backgroundColor: .purple, 
                        foregroundColor: .white, 
                        icon: Image(systemName: "star.fill")),
          actionTitle: "Action") {
    // Action handler
}

// Using Toast Manager
toastManager.show(FloeToast.success("Saved successfully!"))

// Advanced configuration
FloeToast("Upload Complete",
          message: "Your file has been uploaded",
          style: .success,
          position: .bottom,
          duration: 5.0,
          actionTitle: "View") {
    // View file action
} onDismiss: {
    print("Toast dismissed")
}

Styles: Success, warning, error, info, custom
Positions: Top, bottom
Features: Auto-dismiss, swipe gestures, action buttons, custom styling, animations


FloeTabBar (New)

Modern floating tab bar with smooth animations and flexible configuration.

FloeTabBar Result Builder FloeTabBar Enhanced Badges

// Define tabs
let tabs = [
    FloeTabBar.Tab.systemIcon(id: "home", title: "Home", 
                             systemName: "house", selectedSystemName: "house.fill"),
    FloeTabBar.Tab.systemIcon(id: "search", title: "Search", 
                             systemName: "magnifyingglass", badge: "3"),
    FloeTabBar.Tab.systemIcon(id: "favorites", title: "Favorites", 
                             systemName: "heart", selectedSystemName: "heart.fill"),
    FloeTabBar.Tab.systemIcon(id: "profile", title: "Profile", 
                             systemName: "person", selectedSystemName: "person.fill")
]

// Basic tab bar
@State private var selectedTab = "home"

FloeTabBar(
    tabs: tabs,
    selectedTabId: selectedTab,
    onTabSelected: { selectedTab = $0 }
)

// Floating style with central action
FloeTabBar(
    tabs: tabs,
    selectedTabId: selectedTab,
    onTabSelected: { selectedTab = $0 },
    style: .floating,
    indicatorStyle: .pill,
    centralAction: { print("Add new item") },
    centralActionIcon: Image(systemName: "plus.circle.fill")
)

// Scrollable for many tabs
FloeTabBar(
    tabs: manyTabs,
    selectedTabId: selectedTab,
    onTabSelected: { selectedTab = $0 },
    isScrollable: true
)

// Complete tab bar controller
FloeTabBarController(
    tabs: tabs,
    initialSelection: "home",
    style: .floating
) { selectedTab in
    // Content for each tab
    switch selectedTab {
    case "home": HomeView()
    case "search": SearchView()
    case "favorites": FavoritesView()
    case "profile": ProfileView()
    default: EmptyView()
    }
}

Styles: Floating, attached, minimal
Indicators: Pill, underline, background, none
Features: Badges, central action button, scrollable tabs, animations, custom icons

Result Builder Syntax:

// Declarative tab creation with @TabBuilder
FloeTabBar(
    selectedTabId: selectedTab,
    onTabSelected: { selectedTab = $0 },
    style: .floating,
    indicatorStyle: .pill
) {
    FloeTabBar.Tab.systemIcon(id: "home", title: "Home", systemName: "house")
    FloeTabBar.Tab.systemIcon(id: "search", title: "Search", systemName: "magnifyingglass")
    FloeTabBar.Tab.systemIcon(id: "favorites", title: "Favorites", systemName: "heart")
    FloeTabBar.Tab.systemIcon(id: "profile", title: "Profile", systemName: "person")
}

FloeSlider (New)

Customizable slider with haptic feedback, value labels, and both horizontal/vertical orientations.

@State private var volume: Double = 50
@State private var brightness: Double = 0.7

// Basic slider
FloeSlider(value: $volume, in: 0...100, showLabels: .value)

// Percentage slider with convenience method
FloeSlider.percentage(value: $volume, showLabels: true)

// Volume-style slider (0-1)
FloeSlider.volume(value: $brightness)

// Custom range with steps
FloeSlider(
    value: $rating,
    in: 0...5,
    step: 0.5,
    showLabels: .value,
    showMinMax: true
)

// Vertical slider
FloeSlider(
    value: $volume,
    in: 0...100,
    orientation: .vertical,
    showLabels: .percentage
)
.frame(height: 200)

// Custom styling
FloeSlider(
    value: $temperature,
    in: 16...30,
    showLabels: .custom({ "\(Int($0))Β°C" }),
    fillColor: .orange,
    thumbColor: .red,
    enableHaptics: true
)

Orientations: Horizontal, vertical
Label Styles: None, value, percentage, custom formatter
Features: Haptic feedback, range indicators, step values, custom styling, accessibility


FloeTextView (New)

Rich text display and editing component with expansion controls and character limits.

FloeTextView Examples

@State private var editableText = ""
@State private var limitedText = ""

// Basic editable text view
FloeTextView(
    text: $editableText,
    placeholder: "Enter your thoughts...",
    size: .medium
)

// Read-only with expansion
FloeTextView.readOnly(
    text: "Long text content that can be expanded...",
    expansionStyle: .readMore(previewLines: 2)
)

// With character limit
FloeTextView.withCharacterLimit(
    text: $limitedText,
    placeholder: "Bio (max 100 characters)",
    characterLimit: 100,
    size: .small
)

// Attributed text with rich formatting
FloeTextView.attributedText(
    attributedString,
    size: .medium,
    expansionStyle: .readMore(previewLines: 3)
)

Sizes: .small, .medium, .large
Expansion Styles: Read more/less, character limits, custom
Features: Rich text support, smooth animations, character counting, accessibility


FloeProgressIndicator (New)

Versatile progress indicators with linear and circular styles, supporting both determinate and indeterminate states.

FloeProgressIndicator Demo

@State private var progress: Double = 0.65

// Linear progress indicators
FloeProgressIndicator(
    progress: progress,
    style: .linear,
    size: .medium,
    showPercentage: true
)

// Circular progress indicators
FloeProgressIndicator(
    progress: 0.75,
    style: .circular,
    size: .large,
    showPercentage: true
)

// Indeterminate loading
FloeProgressIndicator.indeterminate(
    style: .circular,
    size: .medium,
    color: .blue
)

// State-based indicators
FloeProgressIndicator.loading(style: .circular, size: .medium)
FloeProgressIndicator.success(style: .circular, size: .medium)
FloeProgressIndicator.error(style: .circular, size: .medium)

// Custom styling
FloeProgressIndicator(
    progress: progress,
    style: .linear,
    size: .large,
    color: .purple,
    backgroundColor: .gray.opacity(0.2),
    showPercentage: true
)

Styles: Linear, circular
States: Determinate, indeterminate, loading, success, error
Sizes: .small, .medium, .large
Features: Smooth animations, custom colors, percentage display, accessibility


πŸ—οΈ Comprehensive Example

Here's how FloeKit components work together in a real application:

import SwiftUI
import FloeKit

struct ProfileView: View {
    @State private var name = ""
    @State private var bio = ""
    @State private var selectedTab = "profile"
    @State private var showSuccessToast = false
    
    var body: some View {
        FloeTabBarController(
            initialSelection: "profile",
            style: .floating
        ) {
            FloeTabBar.Tab.systemIcon(id: "profile", title: "Profile", systemName: "person")
            FloeTabBar.Tab.systemIcon(id: "settings", title: "Settings", systemName: "gear")
        } content: { selectedTab in
            ScrollView {
                VStack(spacing: FloeSpacing.Size.lg.value) {
                    // Avatar Section
                    FloeCard {
                        VStack(spacing: FloeSpacing.Size.md.value) {
                            FloeAvatar.initials("JD", size: .extraLarge)
                            Text("John Doe")
                                .floeFont(.headline)
                        }
                        .frame(maxWidth: .infinity)
                    }
                    
                    // Form Section
                    FloeCard(padding: .comfortable) {
                        VStack(spacing: FloeSpacing.Size.md.value) {
                            FloeTextField(
                                text: $name,
                                placeholder: "Full Name",
                                leadingIcon: Image(systemName: "person.fill")
                            )
                            
                            FloeTextView.withCharacterLimit(
                                text: $bio,
                                placeholder: "Tell us about yourself...",
                                characterLimit: 150,
                                size: .medium
                            )
                            
                            FloeButton("Save Profile",
                                      size: .large,
                                      backgroundColor: FloeColors.primary,
                                      textColor: .white) {
                                showSuccessToast = true
                            }
                        }
                    }
                    
                    // Progress Section
                    FloeCard {
                        VStack(alignment: .leading, spacing: FloeSpacing.Size.sm.value) {
                            Text("Profile Completion")
                                .floeFont(.headline)
                            
                            FloeProgressIndicator(
                                progress: 0.75,
                                style: .linear,
                                size: .medium,
                                showPercentage: true
                            )
                        }
                    }
                }
                .floePadding(.comfortable)
            }
            .floeToast(showSuccessToast ? 
                FloeToast.success("Profile Updated!", 
                                 message: "Your changes have been saved") {
                    showSuccessToast = false
                } : nil
            )
        }
    }
}

This example demonstrates:

  • FloeTabBarController with multiple screens
  • FloeCard for clean content organization
  • FloeAvatar for user representation
  • FloeTextField with icons for form input
  • FloeTextView with character limits for longer text
  • FloeButton for primary actions
  • FloeProgressIndicator for status display
  • FloeToast for user feedback
  • FloeSpacing and FloeFont for consistent styling

πŸ› οΈ Utilities

FloeColors

Adaptive color palette with seamless light/dark mode support.

// Primary semantic colors
.foregroundColor(FloeColors.primary)     // Main brand color
.backgroundColor(FloeColors.secondary)   // Secondary brand color
.foregroundColor(FloeColors.accent)      // Accent highlights
.foregroundColor(FloeColors.error)       // Error states

// Surface colors
.backgroundColor(FloeColors.background)  // Main background
.backgroundColor(FloeColors.surface)     // Card/component backgrounds

// Neutral scale for subtle elements
.foregroundColor(FloeColors.neutral0)    // Pure contrast
.foregroundColor(FloeColors.neutral10)   // High contrast text
.foregroundColor(FloeColors.neutral20)   // Medium contrast borders
.foregroundColor(FloeColors.neutral30)   // Low contrast dividers
.foregroundColor(FloeColors.neutral40)   // Subtle text
.foregroundColor(FloeColors.neutral90)   // Very subtle backgrounds

// State colors
.foregroundColor(FloeColors.success)     // Success feedback
.foregroundColor(FloeColors.warning)     // Warning states

βœ… All colors automatically adapt to light/dark mode
βœ… Consistent contrast ratios for accessibility
βœ… Can be overridden via color assets for custom theming


FloeFont

Typography system with semantic font styles.

Text("Headline")
    .floeFont(.headline)

Text("Body text")
    .floeFont(.body)

// Or with custom size and weight
Text("Custom")
    .floeFont(size: .xl, weight: .bold)

// Available styles: .body, .caption, .button, .title, .headline, .subheadline
// Available sizes: .xs, .sm, .base, .lg, .xl, .xl2, .xl3, .xl4

FloeSpacing

Consistent spacing and padding system.

// Use spacing tokens
VStack(spacing: FloeSpacing.Size.lg.value) {
    // Content
}

// Apply semantic padding
SomeView()
    .floePadding(.card)        // Standard card padding
    .floePadding(.section)     // Section container padding
    .floePadding(.comfortable) // Comfortable all-around padding
    .floePadding(.spacious)    // Spacious padding
    .floePadding(.generous)    // Generous padding

// Custom spacing
SomeView()
    .floePadding(.vertical, .lg)
    .floePadding(.horizontal, .xl)

FloeShadow

Consistent shadow system with automatic dark mode adaptation.

// Apply semantic shadows
RoundedRectangle(cornerRadius: 12)
    .floeShadow(.soft)      // Subtle shadow
    .floeShadow(.medium)    // Standard shadow
    .floeShadow(.elevated)  // Strong shadow

// Available styles: .none, .subtle, .soft, .medium, .elevated

πŸ—ΊοΈ Roadmap

πŸŽ›οΈ FloeStepper (Next Phase)

Custom stepper component with enhanced visual feedback.

  • Smooth animations and haptic feedback
  • Custom styling and button designs
  • Long press for rapid changes
  • Custom step values and ranges

πŸ“… FloeDatePicker & FloeTimePicker (Next Phase)

Modern date and time selection components.

  • Inline and compact picker styles
  • Custom styling with FloeKit design language
  • Range selection support
  • Localization and timezone support

πŸ” FloeSearchBar (Next Phase)

Enhanced search bar with modern styling and functionality.

  • Animated search icon and clear button
  • Search suggestions and recent searches
  • Voice input support
  • Custom filtering and debouncing

πŸ“‹ FloeList & FloeGrid (Planned)

Enhanced list and grid components with built-in styling.

  • Pull-to-refresh and infinite scrolling
  • Swipe actions and reordering
  • Section headers with sticky behavior
  • Loading states and empty state views

🎨 FloeColorPicker (Planned)

Modern color selection component.

  • Multiple picker styles (wheel, palette, sliders)
  • Custom color palettes and recent colors
  • Hex, RGB, HSL input support
  • Eyedropper functionality

πŸ“Š FloeChart (Planned)

Simple charting components for basic data visualization.

  • Line, bar, and pie chart support
  • Animated data updates
  • Interactive tooltips and legends
  • Customizable colors and styling

🎨 Theming

FloeKit supports comprehensive theming through color asset overrides:

  1. Add a Colors.xcassets to your app
  2. Create color sets with FloeKit's color names:
    • FloePrimary, FloeSecondary, FloeAccent
    • FloeBackground, FloeSurface
    • FloeNeutral0, FloeNeutral10, FloeNeutral20, FloeNeutral30, FloeNeutral40, FloeNeutral90
  3. FloeKit will automatically use your custom colors

πŸ“„ License

FloeKit is available under the MIT license. See LICENSE for details.


πŸ™ Acknowledgments

Inspired by modern design systems and the SwiftUI community's best practices.


About

Elegant, modular UI building blocks for SwiftUI β€” design system, components, and utilities with built-in theming and accessibility

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

0