> ## Documentation Index
> Fetch the complete documentation index at: https://www.cometchat.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Customizing Your UI Kit Builder

> Customize CometChat UI Kit Builder components — modify props, styling, and behavior for Flutter.

The `BuilderSettingsHelper` handles basic feature toggles. For deeper customizations, modify the configuration JSON, theme settings, or component props directly.

***

## Understanding the Customization Architecture

The Flutter UI Kit Builder uses these main files for customization:

| File                              | Purpose                                          | When to Modify                               |
| --------------------------------- | ------------------------------------------------ | -------------------------------------------- |
| `cometchat-builder-settings.json` | Feature flags and configuration constants        | Functional changes (enable/disable features) |
| `BuilderSettingsHelper`           | Utility class for loading and accessing settings | Runtime configuration access                 |
| `pubspec.yaml`                    | Font and asset declarations                      | Adding custom fonts or assets                |

<Info>
  The `cometchat-builder-settings.json` file is the source of truth for your Builder configuration. Update it and reload to apply changes.
</Info>

***

## Using BuilderSettingsHelper

The `BuilderSettingsHelper` provides access to your Builder configuration throughout your app.

### Loading Configuration

```dart theme={null}
import 'package:chat_builder/utils/builder_settings_helper.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Load settings from assets
  await BuilderSettingsHelper.loadFromAsset();
  
  runApp(const MyApp());
}
```

### Accessing Settings

```dart theme={null}
import 'package:chat_builder/utils/builder_settings_helper.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final settings = BuilderSettingsHelper.settings;
    
    // Access chat features
    final chatFeatures = settings.chatFeatures;
    final isPhotosEnabled = chatFeatures.coreMessagingExperience.photosSharing;
    
    // Access style settings
    final style = settings.style;
    final brandColor = style.color.brandColor;
    
    // Access layout settings
    final layout = settings.layout;
    final tabs = layout.tabs;
    
    return Container(/* ... */);
  }
}
```

***

## Theme Customization

### Applying Builder Theme to UI Kit

Apply the Builder configuration colors to your Flutter theme:

```dart theme={null}
import 'package:flutter/material.dart';
import 'package:chat_builder/utils/builder_settings_helper.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final style = BuilderSettingsHelper.settings.style;
    
    return MaterialApp(
      theme: ThemeData(
        primaryColor: Color(int.parse(style.color.brandColor.replaceFirst('#', '0xFF'))),
        colorScheme: ColorScheme.light(
          primary: Color(int.parse(style.color.brandColor.replaceFirst('#', '0xFF'))),
        ),
        textTheme: TextTheme(
          bodyLarge: TextStyle(
            color: Color(int.parse(style.color.primaryTextLight.replaceFirst('#', '0xFF'))),
          ),
          bodyMedium: TextStyle(
            color: Color(int.parse(style.color.secondaryTextLight.replaceFirst('#', '0xFF'))),
          ),
        ),
        fontFamily: style.typography.font,
      ),
      darkTheme: ThemeData.dark().copyWith(
        primaryColor: Color(int.parse(style.color.brandColor.replaceFirst('#', '0xFF'))),
        colorScheme: ColorScheme.dark(
          primary: Color(int.parse(style.color.brandColor.replaceFirst('#', '0xFF'))),
        ),
        textTheme: TextTheme(
          bodyLarge: TextStyle(
            color: Color(int.parse(style.color.primaryTextDark.replaceFirst('#', '0xFF'))),
          ),
          bodyMedium: TextStyle(
            color: Color(int.parse(style.color.secondaryTextDark.replaceFirst('#', '0xFF'))),
          ),
        ),
        fontFamily: style.typography.font,
      ),
      themeMode: _getThemeMode(style.theme),
      home: HomeScreen(),
    );
  }
  
  ThemeMode _getThemeMode(String theme) {
    switch (theme) {
      case 'light':
        return ThemeMode.light;
      case 'dark':
        return ThemeMode.dark;
      default:
        return ThemeMode.system;
    }
  }
}
```

### Custom Color Utilities

Create a utility class for working with Builder colors:

```dart theme={null}
import 'package:flutter/material.dart';
import 'package:chat_builder/utils/builder_settings_helper.dart';

class BuilderColors {
  static Color get brandColor {
    final hex = BuilderSettingsHelper.settings.style.color.brandColor;
    return _hexToColor(hex);
  }
  
  static Color get primaryTextLight {
    final hex = BuilderSettingsHelper.settings.style.color.primaryTextLight;
    return _hexToColor(hex);
  }
  
  static Color get primaryTextDark {
    final hex = BuilderSettingsHelper.settings.style.color.primaryTextDark;
    return _hexToColor(hex);
  }
  
  static Color get secondaryTextLight {
    final hex = BuilderSettingsHelper.settings.style.color.secondaryTextLight;
    return _hexToColor(hex);
  }
  
  static Color get secondaryTextDark {
    final hex = BuilderSettingsHelper.settings.style.color.secondaryTextDark;
    return _hexToColor(hex);
  }
  
  static Color _hexToColor(String hex) {
    return Color(int.parse(hex.replaceFirst('#', '0xFF')));
  }
}
```

***

## Custom Font Integration

### Step 1: Add Font Files

Add your custom font files to the `assets/fonts/` directory.

### Step 2: Update pubspec.yaml

Register your custom fonts:

```yaml theme={null}
flutter:
  fonts:
    - family: YourCustomFont
      fonts:
        - asset: assets/fonts/your_font_regular.ttf
        - asset: assets/fonts/your_font_medium.ttf
          weight: 500
        - asset: assets/fonts/your_font_bold.ttf
          weight: 700
```

### Step 3: Apply Custom Font

Update the configuration JSON or apply programmatically:

```dart theme={null}
// In your theme configuration
ThemeData(
  fontFamily: 'YourCustomFont',
  // ... other theme settings
)
```

***

## Component-Level Customizations

### Conditional Rendering Based on Features

Use the configuration to conditionally render UI elements:

```dart theme={null}
import 'package:chat_builder/utils/builder_settings_helper.dart';

class MessageComposer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final chatFeatures = BuilderSettingsHelper.settings.chatFeatures;
    final core = chatFeatures.coreMessagingExperience;
    final engagement = chatFeatures.deeperUserEngagement;
    
    return Row(
      children: [
        // Always show text input
        Expanded(child: TextField()),
        
        // Conditionally show attachment options
        if (core.photosSharing)
          IconButton(
            icon: Icon(Icons.photo),
            onPressed: () => _attachPhoto(),
          ),
        
        if (core.fileSharing)
          IconButton(
            icon: Icon(Icons.attach_file),
            onPressed: () => _attachFile(),
          ),
        
        if (engagement.voiceNotes)
          IconButton(
            icon: Icon(Icons.mic),
            onPressed: () => _recordVoiceNote(),
          ),
        
        if (engagement.stickers)
          IconButton(
            icon: Icon(Icons.emoji_emotions),
            onPressed: () => _showStickers(),
          ),
      ],
    );
  }
}
```

### Customizing Message Options

Control which message options appear based on configuration:

```dart theme={null}
class MessageOptionsSheet extends StatelessWidget {
  final Message message;
  
  const MessageOptionsSheet({required this.message});
  
  @override
  Widget build(BuildContext context) {
    final chatFeatures = BuilderSettingsHelper.settings.chatFeatures;
    final core = chatFeatures.coreMessagingExperience;
    final engagement = chatFeatures.deeperUserEngagement;
    final moderator = chatFeatures.moderatorControls;
    
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        if (core.quotedReplies)
          ListTile(
            leading: Icon(Icons.reply),
            title: Text('Reply'),
            onTap: () => _handleReply(),
          ),
        
        if (core.threadConversationAndReplies)
          ListTile(
            leading: Icon(Icons.forum),
            title: Text('Reply in Thread'),
            onTap: () => _handleThreadReply(),
          ),
        
        if (engagement.reactions)
          ListTile(
            leading: Icon(Icons.add_reaction),
            title: Text('React'),
            onTap: () => _handleReaction(),
          ),
        
        if (core.editMessage && _isOwnMessage())
          ListTile(
            leading: Icon(Icons.edit),
            title: Text('Edit'),
            onTap: () => _handleEdit(),
          ),
        
        if (core.deleteMessage && _isOwnMessage())
          ListTile(
            leading: Icon(Icons.delete),
            title: Text('Delete'),
            onTap: () => _handleDelete(),
          ),
        
        if (moderator.reportMessage)
          ListTile(
            leading: Icon(Icons.flag),
            title: Text('Report'),
            onTap: () => _handleReport(),
          ),
      ],
    );
  }
}
```

***

## Layout Customization

### Dynamic Tab Configuration

```dart theme={null}
import 'package:chat_builder/utils/builder_settings_helper.dart';

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final layout = BuilderSettingsHelper.settings.layout;
    
    if (!layout.withSideBar) {
      return SingleChatView();
    }
    
    final tabs = layout.tabs;
    
    return DefaultTabController(
      length: tabs.length,
      child: Scaffold(
        appBar: AppBar(
          bottom: TabBar(
            tabs: [
              if (tabs.contains('chats'))
                Tab(icon: Icon(Icons.chat), text: 'Chats'),
              if (tabs.contains('calls'))
                Tab(icon: Icon(Icons.call), text: 'Calls'),
              if (tabs.contains('users'))
                Tab(icon: Icon(Icons.people), text: 'Users'),
              if (tabs.contains('groups'))
                Tab(icon: Icon(Icons.group), text: 'Groups'),
            ],
          ),
        ),
        body: TabBarView(
          children: [
            if (tabs.contains('chats')) ChatsScreen(),
            if (tabs.contains('calls')) CallsScreen(),
            if (tabs.contains('users')) UsersScreen(),
            if (tabs.contains('groups')) GroupsScreen(),
          ],
        ),
      ),
    );
  }
}
```

***

## Call Features Customization

### Conditional Call Buttons

```dart theme={null}
class ChatHeader extends StatelessWidget {
  final bool isGroup;
  
  const ChatHeader({required this.isGroup});
  
  @override
  Widget build(BuildContext context) {
    final callFeatures = BuilderSettingsHelper.settings.callFeatures;
    final calling = callFeatures.voiceAndVideoCalling;
    
    return AppBar(
      actions: [
        if (isGroup) ...[
          if (calling.groupVoiceConference)
            IconButton(
              icon: Icon(Icons.call),
              onPressed: () => _startGroupVoiceCall(),
            ),
          if (calling.groupVideoConference)
            IconButton(
              icon: Icon(Icons.videocam),
              onPressed: () => _startGroupVideoCall(),
            ),
        ] else ...[
          if (calling.oneOnOneVoiceCalling)
            IconButton(
              icon: Icon(Icons.call),
              onPressed: () => _startVoiceCall(),
            ),
          if (calling.oneOnOneVideoCalling)
            IconButton(
              icon: Icon(Icons.videocam),
              onPressed: () => _startVideoCall(),
            ),
        ],
      ],
    );
  }
}
```

***

## Reloading Configuration

### Refresh Settings at Runtime

```dart theme={null}
import 'package:chat_builder/utils/builder_settings_helper.dart';

class SettingsScreen extends StatelessWidget {
  Future<void> _reloadConfiguration() async {
    // Reload from assets
    await BuilderSettingsHelper.loadFromAsset();
    
    // Trigger UI rebuild
    // Use a state management solution to notify listeners
  }
  
  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: _reloadConfiguration,
      child: Text('Reload Configuration'),
    );
  }
}
```
