diff --git a/ComponentSelectorAdditions/ComponentResult.cs b/ComponentSelectorAdditions/ComponentResult.cs
index 33af9a2..1497059 100644
--- a/ComponentSelectorAdditions/ComponentResult.cs
+++ b/ComponentSelectorAdditions/ComponentResult.cs
@@ -10,22 +10,52 @@
 
 namespace ComponentSelectorAdditions
 {
+    /// <summary>
+    /// Represents a component or node returned by the <see cref="Events.EnumerateComponentsEvent"/>.
+    /// </summary>
     public sealed class ComponentResult
     {
+        /// <summary>
+        /// Gets the category that should be shown as the <see cref="Type">Type's</see> parent.
+        /// </summary>
         public CategoryNode<Type> Category { get; }
-        public string FullName => Type.FullName;
+
+        /// <summary>
+        /// Gets the <see cref="Type">Type's</see> group identifier, if present.
+        /// </summary>
         public string? Group { get; }
 
+        /// <summary>
+        /// Gets the <see cref="Type">Type's</see> group name, if present.
+        /// </summary>
         public string? GroupName { get; }
 
+        /// <summary>
+        /// Gets whether the <see cref="Type">Type</see> is part of a group.
+        /// </summary>
         [MemberNotNullWhen(true, nameof(Group), nameof(GroupName))]
         public bool HasGroup => Group is not null;
 
+        /// <summary>
+        /// Gets whether this <see cref="Type">Type</see> is a generic type definition.
+        /// </summary>
         public bool IsGeneric => Type.IsGenericTypeDefinition;
 
+        /// <summary>
+        /// Gets the <see cref="Type">Type's</see> nice name.
+        /// </summary>
         public string NiceName => Type.GetNiceName();
+
+        /// <summary>
+        /// Gets the component / node <see cref="System.Type"/> result.
+        /// </summary>
         public Type Type { get; }
 
+        /// <summary>
+        /// Creates a new component / node <see cref="System.Type"/> result with the given category.
+        /// </summary>
+        /// <param name="category">The category that should be shown as the <see cref="Type">Type's</see> parent.</param>
+        /// <param name="type">The component / node <see cref="System.Type"/>.</param>
         public ComponentResult(CategoryNode<Type> category, Type type)
         {
             Type = type;
diff --git a/ComponentSelectorAdditions/ComponentSelectorAdditions.csproj b/ComponentSelectorAdditions/ComponentSelectorAdditions.csproj
index 378edc3..a496715 100644
--- a/ComponentSelectorAdditions/ComponentSelectorAdditions.csproj
+++ b/ComponentSelectorAdditions/ComponentSelectorAdditions.csproj
@@ -11,7 +11,7 @@
     <PackageId>ComponentSelectorAdditions</PackageId>
     <Title>Component Selector Additions</Title>
     <Authors>Banane9</Authors>
-    <Version>0.2.0-beta</Version>
+    <Version>0.3.0-beta</Version>
     <Description>This MonkeyLoader mod for Resonite overhauls the Component Selector / Protoflux Node Selector to have a search, as well as favorites and recents categories.</Description>
     <PackageReadmeFile>README.md</PackageReadmeFile>
     <PackageLicenseExpression>LGPL-3.0-or-later</PackageLicenseExpression>
@@ -30,17 +30,13 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="MonkeyLoader" Version="0.18.0-beta" />
-    <PackageReference Include="MonkeyLoader.GamePacks.Resonite" Version="0.16.5-beta" />
+    <PackageReference Include="MonkeyLoader" Version="0.19.1-beta" />
+    <PackageReference Include="MonkeyLoader.GamePacks.Resonite" Version="0.17.0-beta" />
     <PackageReference Include="PolySharp" Version="1.14.1">
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>
-    <PackageReference Include="Resonite.Elements.Core" Version="1.0.2" />
-    <PackageReference Include="Resonite.FrooxEngine" Version="2024.6.11.74" />
-    <PackageReference Include="System.Text.Json" Version="8.0.2">
-      <PrivateAssets>all</PrivateAssets>
-      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
-    </PackageReference>
+    <PackageReference Include="Resonite.Elements.Core" Version="1.1.0" />
+    <PackageReference Include="Resonite.FrooxEngine" Version="2024.7.11.1293" />
   </ItemGroup>
 </Project>
diff --git a/ComponentSelectorAdditions/Events/BuildCustomGenericBuilder.cs b/ComponentSelectorAdditions/Events/BuildCustomGenericBuilder.cs
index 20d2b2d..f4077bd 100644
--- a/ComponentSelectorAdditions/Events/BuildCustomGenericBuilder.cs
+++ b/ComponentSelectorAdditions/Events/BuildCustomGenericBuilder.cs
@@ -38,7 +38,7 @@ public sealed class BuildCustomGenericBuilder : BuildUIEvent
         public IEnumerable<Button> OtherAddedButtons => OtherAddedButtonsSet.AsSafeEnumerable();
         public ComponentSelector Selector { get; }
 
-        public BuildCustomGenericBuilder(ComponentSelector selector, UIBuilder ui, Type component) : base(ui)
+        internal BuildCustomGenericBuilder(ComponentSelector selector, UIBuilder ui, Type component) : base(ui)
         {
             Selector = selector;
             Component = component;
diff --git a/ComponentSelectorAdditions/Events/BuildSelectorFooterEvent.cs b/ComponentSelectorAdditions/Events/BuildSelectorFooterEvent.cs
index 7d8d75b..f2b4a93 100644
--- a/ComponentSelectorAdditions/Events/BuildSelectorFooterEvent.cs
+++ b/ComponentSelectorAdditions/Events/BuildSelectorFooterEvent.cs
@@ -12,7 +12,7 @@ public sealed class BuildSelectorFooterEvent : BuildSelectorEvent
 
         public bool HasCancelButton { get; }
 
-        public BuildSelectorFooterEvent(ComponentSelector selector, UIBuilder ui, SelectorSearchBar? searchBar, bool hasBackButton, bool hasCancelButton)
+        internal BuildSelectorFooterEvent(ComponentSelector selector, UIBuilder ui, SelectorSearchBar? searchBar, bool hasBackButton, bool hasCancelButton)
             : base(selector, ui)
         {
             HasBackButton = hasBackButton;
diff --git a/ComponentSelectorAdditions/Events/BuildSelectorHeaderEvent.cs b/ComponentSelectorAdditions/Events/BuildSelectorHeaderEvent.cs
index 3637cdf..0ad8f70 100644
--- a/ComponentSelectorAdditions/Events/BuildSelectorHeaderEvent.cs
+++ b/ComponentSelectorAdditions/Events/BuildSelectorHeaderEvent.cs
@@ -6,7 +6,7 @@ namespace ComponentSelectorAdditions.Events
     public sealed class BuildSelectorHeaderEvent : BuildSelectorEvent
     {
         /// <inheritdoc/>
-        public BuildSelectorHeaderEvent(ComponentSelector selector, UIBuilder ui) : base(selector, ui)
+        internal BuildSelectorHeaderEvent(ComponentSelector selector, UIBuilder ui) : base(selector, ui)
         { }
     }
 }
\ No newline at end of file
diff --git a/ComponentSelectorAdditions/Events/EnumerateCategoriesEvent.cs b/ComponentSelectorAdditions/Events/EnumerateCategoriesEvent.cs
index 38eb0a8..0dc1188 100644
--- a/ComponentSelectorAdditions/Events/EnumerateCategoriesEvent.cs
+++ b/ComponentSelectorAdditions/Events/EnumerateCategoriesEvent.cs
@@ -19,7 +19,7 @@ public override IEnumerable<CategoryNode<Type>> Items
         public ComponentSelector Selector { get; }
 
         /// <inheritdoc/>
-        public EnumerateCategoriesEvent(ComponentSelector selector, SelectorPath path, CategoryNode<Type> rootCategory)
+        internal EnumerateCategoriesEvent(ComponentSelector selector, SelectorPath path, CategoryNode<Type> rootCategory)
         {
             Selector = selector;
             Path = path;
diff --git a/ComponentSelectorAdditions/Events/EnumerateComponentsEvent.cs b/ComponentSelectorAdditions/Events/EnumerateComponentsEvent.cs
index 5bd5422..82b08d8 100644
--- a/ComponentSelectorAdditions/Events/EnumerateComponentsEvent.cs
+++ b/ComponentSelectorAdditions/Events/EnumerateComponentsEvent.cs
@@ -14,6 +14,7 @@ public sealed class EnumerateComponentsEvent : CancelableSortedItemsEvent<Compon
         public override IEnumerable<ComponentResult> Items
             => sortableItems
                 .Where(entry => ComponentFilter(entry.Key.Type))
+                .Where(entry => Selector.World.Types.IsSupported(entry.Key.Type))
                 .OrderBy(entry => entry.Value)
                 .ThenBy(entry => entry.Key.GroupName ?? entry.Key.Type.Name)
                 .Select(entry => entry.Key);
@@ -24,7 +25,7 @@ public override IEnumerable<ComponentResult> Items
         public ComponentSelector Selector { get; }
 
         /// <inheritdoc/>
-        public EnumerateComponentsEvent(ComponentSelector selector, SelectorPath path, CategoryNode<Type> rootCategory, Predicate<Type> componentFilter)
+        internal EnumerateComponentsEvent(ComponentSelector selector, SelectorPath path, CategoryNode<Type> rootCategory, Predicate<Type> componentFilter)
         {
             Selector = selector;
             Path = path;
diff --git a/ComponentSelectorAdditions/Events/EnumerateConcreteGenericsEvent.cs b/ComponentSelectorAdditions/Events/EnumerateConcreteGenericsEvent.cs
index 2e1db44..f47686f 100644
--- a/ComponentSelectorAdditions/Events/EnumerateConcreteGenericsEvent.cs
+++ b/ComponentSelectorAdditions/Events/EnumerateConcreteGenericsEvent.cs
@@ -1,6 +1,8 @@
 using FrooxEngine;
 using MonkeyLoader.Resonite.Events;
 using System;
+using System.Collections.Generic;
+using System.Linq;
 
 namespace ComponentSelectorAdditions.Events
 {
@@ -12,9 +14,16 @@ public class EnumerateConcreteGenericsEvent : SortedItemsEvent<Type>
         /// </summary>
         public Type Component { get; }
 
+        /// <inheritdoc/>
+        public override IEnumerable<Type> Items
+            => sortableItems
+                .Where(entry => Selector.World.Types.IsSupported(entry.Key))
+                .OrderBy(entry => entry.Value)
+                .Select(entry => entry.Key);
+
         public ComponentSelector Selector { get; }
 
-        public EnumerateConcreteGenericsEvent(ComponentSelector selector, Type component)
+        internal EnumerateConcreteGenericsEvent(ComponentSelector selector, Type component)
         {
             Selector = selector;
             Component = component;
diff --git a/ComponentSelectorAdditions/FavoritesCategories.cs b/ComponentSelectorAdditions/FavoritesCategories.cs
index f7b02a1..61c0926 100644
--- a/ComponentSelectorAdditions/FavoritesCategories.cs
+++ b/ComponentSelectorAdditions/FavoritesCategories.cs
@@ -120,9 +120,10 @@ public void Handle(PostProcessButtonsEvent eventData)
 
             foreach (var addButton in eventData.AddButtons.Concat(eventData.GenericButtons))
             {
-                AddFavoriteButton(eventData.UI, addButton, true,
-                    isProtoFlux ? IsFavoriteProtoFluxNode : IsFavoriteComponent,
-                    isProtoFlux ? ToggleFavoriteProtoFluxNode : ToggleFavoriteComponent);
+                Func<TypeManager, string, bool> isFavorite = isProtoFlux ? IsFavoriteProtoFluxNode : IsFavoriteComponent;
+                Func<TypeManager, string, bool> toggleFavorite = isProtoFlux ? ToggleFavoriteProtoFluxNode : ToggleFavoriteComponent;
+
+                AddFavoriteButton(eventData.UI, addButton, true, isFavorite, toggleFavorite);
             }
         }
 
@@ -175,8 +176,10 @@ protected override bool OnShutdown(bool applicationExiting)
             return base.OnShutdown(applicationExiting);
         }
 
-        private static void AddFavoriteButton(UIBuilder builder, Button button, bool isComponent, Predicate<string> isFavorite, Func<string, bool> toggleFavorite)
+        private static void AddFavoriteButton(UIBuilder builder, Button button, bool isComponent,
+            Func<TypeManager, string, bool> isFavorite, Func<TypeManager, string, bool> toggleFavorite)
         {
+            var types = button.World.Types;
             builder.NestInto(button.Slot.Parent);
 
             var height = button.Slot.GetComponent<LayoutElement>().MinHeight;
@@ -199,14 +202,14 @@ private static void AddFavoriteButton(UIBuilder builder, Button button, bool isC
                 name = name.Substring(lastSlashIndex + 1);
             }
 
-            var favColor = isFavorite(name) ? RadiantUI_Constants.Hero.YELLOW : RadiantUI_Constants.Neutrals.DARKLIGHT;
+            var favColor = isFavorite(types, name) ? RadiantUI_Constants.Hero.YELLOW : RadiantUI_Constants.Neutrals.DARKLIGHT;
 
             var favoriteButton = builder.Button(OfficialAssets.Graphics.Icons.World_Categories.FeaturedRibbon, RadiantUI_Constants.BUTTON_COLOR, favColor);
             var icon = favoriteButton.Slot.GetComponentsInChildren<Image>().Last();
 
             favoriteButton.LocalPressed += (btn, btnEvent) =>
             {
-                icon.Tint.Value = toggleFavorite(name) ?
+                icon.Tint.Value = toggleFavorite(types, name) ?
                     RadiantUI_Constants.Hero.YELLOW : RadiantUI_Constants.Neutrals.DARKLIGHT;
 
                 Config.Save();
@@ -231,16 +234,16 @@ private void AddCategories()
             SearchConfig.Instance.AddExcludedCategory(ProtoFluxFavoritesPath);
         }
 
-        private bool IsFavoriteCategory(string name)
+        private bool IsFavoriteCategory(TypeManager types, string name)
             => ConfigSection.Categories.Contains(name);
 
-        private bool IsFavoriteComponent(string name)
-            => ConfigSection.Components.Contains(WorkerManager.ParseNiceType(name));
+        private bool IsFavoriteComponent(TypeManager types, string name)
+            => ConfigSection.Components.Contains(types.DecodeType(name));
 
-        private bool IsFavoriteProtoFluxNode(string name)
-            => ConfigSection.ProtoFluxNodes.Contains(WorkerManager.ParseNiceType(name));
+        private bool IsFavoriteProtoFluxNode(TypeManager types, string name)
+            => ConfigSection.ProtoFluxNodes.Contains(types.DecodeType(name));
 
-        private bool IsProtoFluxFavoriteCategory(string name)
+        private bool IsProtoFluxFavoriteCategory(TypeManager types, string name)
             => ConfigSection.ProtoFluxCategories.Contains(name);
 
         private void RemoveCategories()
@@ -252,16 +255,16 @@ private void RemoveCategories()
             SearchConfig.Instance.RemoveExcludedCategory(ProtoFluxFavoritesPath);
         }
 
-        private bool ToggleFavoriteCategory(string name)
+        private bool ToggleFavoriteCategory(TypeManager types, string name)
             => ToggleHashSetContains(ConfigSection.Categories, name);
 
-        private bool ToggleFavoriteComponent(string name)
-            => ToggleHashSetContains(ConfigSection.Components, WorkerManager.ParseNiceType(name));
+        private bool ToggleFavoriteComponent(TypeManager types, string name)
+            => ToggleHashSetContains(ConfigSection.Components, types.DecodeType(name));
 
-        private bool ToggleFavoriteProtoFluxNode(string name)
-            => ToggleHashSetContains(ConfigSection.ProtoFluxNodes, WorkerManager.ParseNiceType(name));
+        private bool ToggleFavoriteProtoFluxNode(TypeManager types, string name)
+            => ToggleHashSetContains(ConfigSection.ProtoFluxNodes, types.DecodeType(name));
 
-        private bool ToggleProtoFluxFavoriteCategory(string name)
+        private bool ToggleProtoFluxFavoriteCategory(TypeManager types, string name)
             => ToggleHashSetContains(ConfigSection.ProtoFluxCategories, name);
     }
 }
\ No newline at end of file
diff --git a/ComponentSelectorAdditions/FavoritesConfig.cs b/ComponentSelectorAdditions/FavoritesConfig.cs
index 45d5256..060faf8 100644
--- a/ComponentSelectorAdditions/FavoritesConfig.cs
+++ b/ComponentSelectorAdditions/FavoritesConfig.cs
@@ -17,16 +17,25 @@ internal sealed class FavoritesConfig : ConfigSection
         private static readonly DefiningConfigKey<bool> _sortFavoriteCategoriesToTop = new("SortFavoriteCategoriesToTop", "Sort favorited Categories above unfavorited ones.", () => false);
         private static readonly DefiningConfigKey<bool> _sortFavoriteComponentsToTop = new("SortFavoriteComponentsToTop", "Sort favorited Components / Nodes above unfavorited ones.", () => true);
         private static readonly DefiningConfigKey<bool> _sortFavoriteConcreteGenericsToTop = new("SortFavoriteConcreteGenericsToTop", "Sort favorited concrete generic Components / Nodes above unfavorited ones.", () => true);
+
         public HashSet<string> Categories => _categoriesKey.GetValue()!;
 
         public HashSet<Type> Components => _componentsKey.GetValue()!;
+
         public override string Description => "Contains the favorited categories and components.";
+
         public override string Id => "Favorites";
+
         public HashSet<string> ProtoFluxCategories => _protoFluxCategoriesKey.GetValue()!;
+
         public HashSet<Type> ProtoFluxNodes => _protoFluxNodesKey.GetValue()!;
+
         public bool SortFavoriteCategoriesToTop => _sortFavoriteCategoriesToTop.GetValue();
+
         public bool SortFavoriteComponentsToTop => _sortFavoriteComponentsToTop.GetValue();
+
         public bool SortFavoriteConcreteGenericsToTop => _sortFavoriteConcreteGenericsToTop.GetValue();
+
         public override Version Version { get; } = new(1, 1, 0);
     }
 }
\ No newline at end of file
diff --git a/ComponentSelectorAdditions/Injector.cs b/ComponentSelectorAdditions/Injector.cs
index 076a8c8..f7b3d67 100644
--- a/ComponentSelectorAdditions/Injector.cs
+++ b/ComponentSelectorAdditions/Injector.cs
@@ -163,7 +163,7 @@ private static void BuildGenericTypeUI(ComponentSelector selector, UIBuilder ui,
         {
             backButton = null;
 
-            var type = WorkerManager.GetType(PathUtility.GetFileName(path.PathSegments[^1]));
+            var type = Type.GetType(path.PathSegments[^1]);
             selector._genericType.Value = type;
 
             if (!doNotGenerateBack)
@@ -358,7 +358,7 @@ private static void OnBuildComponentButton(ComponentSelector selector, UIBuilder
                 var category = GetPrettyPath(component.Category, rootCategory);
                 var tint = component.IsGeneric ? RadiantUI_Constants.Sub.GREEN : RadiantUI_Constants.Sub.CYAN;
                 ButtonEventHandler<string> callback = component.IsGeneric ? selector.OpenGenericTypesPressed : selector.OnAddComponentPressed;
-                var argument = $"{(component.IsGeneric ? $"{path.Path}/" : "")}{component.FullName}{(component.IsGeneric && path.HasGroup ? $"?{path.Group}" : "")}";
+                var argument = $"{(component.IsGeneric ? $"{path.Path}/" : "")}{selector.World.Types.EncodeType(component.Type)}{(component.IsGeneric && path.HasGroup ? $"?{path.Group}" : "")}";
 
                 MakePermanentButton(ui, category, component.NiceName, tint, callback, argument);
             }
diff --git a/ComponentSelectorAdditions/RecentsCategories.cs b/ComponentSelectorAdditions/RecentsCategories.cs
index d5d3579..bdaea38 100644
--- a/ComponentSelectorAdditions/RecentsCategories.cs
+++ b/ComponentSelectorAdditions/RecentsCategories.cs
@@ -125,7 +125,7 @@ private static void OnAddComponentPressedPostfix(ComponentSelector __instance, s
             if (!Enabled)
                 return;
 
-            var type = WorkerManager.ParseNiceType(typename);
+            var type = __instance.World.Types.DecodeType(typename);
             if (type is null || type.IsGenericTypeDefinition)
                 return;
 
diff --git a/ComponentSelectorAdditions/SearchBar.cs b/ComponentSelectorAdditions/SearchBar.cs
index 4aaecbc..0da84e6 100644
--- a/ComponentSelectorAdditions/SearchBar.cs
+++ b/ComponentSelectorAdditions/SearchBar.cs
@@ -40,7 +40,7 @@ public void Handle(BuildSelectorHeaderEvent eventData)
 
             ui.Style.FlexibleWidth = 1;
             var textField = ui.TextField(null, parseRTF: false);
-            var details = new SelectorSearchBar(searchLayout, textField.Editor.Target, ConfigSection.SearchRefreshDelay);
+            var details = new SelectorSearchBar(searchLayout, textField.Editor.Target, () => ConfigSection.SearchRefreshDelay);
             eventData.SearchBar = details;
 
             details.Text.NullContent.AssignLocaleString(Mod.GetLocaleString("Search"));
diff --git a/ComponentSelectorAdditions/SearchConfig.cs b/ComponentSelectorAdditions/SearchConfig.cs
index 641025f..d3dc4c0 100644
--- a/ComponentSelectorAdditions/SearchConfig.cs
+++ b/ComponentSelectorAdditions/SearchConfig.cs
@@ -13,6 +13,11 @@
 
 namespace ComponentSelectorAdditions
 {
+    /// <summary>
+    /// Represents the configuration for the search functionality.<br/>
+    /// Use the <see cref="AddExcludedCategory(string)"/> and <see cref="RemoveExcludedCategory(string)"/>
+    /// methods to add categories which shouldn't be searched into because they're added.
+    /// </summary>
     public sealed class SearchConfig : ConfigSection
     {
         private static readonly Dictionary<string, bool> _excludedCategories = new(StringComparer.OrdinalIgnoreCase);
@@ -29,10 +34,21 @@ public sealed class SearchConfig : ConfigSection
 
         private static readonly DefiningConfigKey<string> _userExcludedCategoriesKey = new("UserExcludedCategories", "Excludes specific categories from being searched into by path (case sensitive). Separate entries by semicolon. Search will work when started inside them.", () => "/ProtoFlux");
         private static readonly char[] _userExclusionSeparator = new[] { ';' };
-        public static SearchConfig Instance { get; private set; }
+
+        /// <summary>
+        /// Gets this config's instance.
+        /// </summary>
+        public static SearchConfig Instance { get; private set; } = null!;
+
+        /// <inheritdoc/>
         public override string Description => "Contains settings for the Component Selector Search.";
+
+        /// <inheritdoc/>
         public override string Id => "Search";
+
+        /// <inheritdoc/>
         public override Version Version { get; } = new(1, 0, 0);
+
         internal int MaxResultCount => _maxResultCountKey.GetValue();
         internal int SearchRefreshDelay => (int)_searchRefreshDelayKey.GetValue();
 
@@ -41,6 +57,10 @@ static SearchConfig()
             _userExcludedCategoriesKey.Changed += UserExcludedCategoriesChanged;
         }
 
+        /// <summary>
+        /// Creates an instance of this config once.
+        /// </summary>
+        /// <exception cref="InvalidOperationException"></exception>
         public SearchConfig()
         {
             if (Instance is not null)
@@ -87,6 +107,7 @@ public bool RemoveExcludedCategory(string category)
             return true;
         }
 
+        /// <inheritdoc/>
         protected override void OnLoad(JObject source, JsonSerializer jsonSerializer)
         {
             base.OnLoad(source, jsonSerializer);
diff --git a/ComponentSelectorAdditions/SelectorPath.cs b/ComponentSelectorAdditions/SelectorPath.cs
index b2f7980..d789197 100644
--- a/ComponentSelectorAdditions/SelectorPath.cs
+++ b/ComponentSelectorAdditions/SelectorPath.cs
@@ -8,25 +8,68 @@
 
 namespace ComponentSelectorAdditions
 {
+    /// <summary>
+    /// Represents the currently opened path in a <see cref="FrooxEngine.ComponentSelector"/>.
+    /// </summary>
     public sealed class SelectorPath
     {
+        /// <summary>
+        /// The path segment after which the search string begins.
+        /// </summary>
         public const string SearchSegment = "Search";
+
         private static readonly char[] _pathSeparators = { '/', '\\' };
+
+        /// <summary>
+        /// Gets whether this path targets a generic type.
+        /// </summary>
         public bool GenericType { get; }
+
+        /// <summary>
+        /// Gets the group targeted by the path, if present.
+        /// </summary>
         public string? Group { get; }
 
+        /// <summary>
+        /// Gets whether this path targets a group.
+        /// </summary>
         [MemberNotNullWhen(true, nameof(Group))]
         public bool HasGroup => !string.IsNullOrWhiteSpace(Group);
 
+        /// <summary>
+        /// Gets whether this path has a search string.
+        /// </summary>
         [MemberNotNullWhen(true, nameof(Search))]
         public bool HasSearch => !string.IsNullOrWhiteSpace(Search);
 
+        /// <summary>
+        /// Gets whether this path targets the root category.
+        /// </summary>
         public bool IsRootCategory => PathSegments.Length == 0;
+
+        /// <summary>
+        /// Gets whether this path targets whatever the root category of its <see cref="FrooxEngine.ComponentSelector"/> is.
+        /// </summary>
         public bool IsSelectorRoot { get; }
+
+        /// <summary>
+        /// Gets the path to open the current path's target's parent.
+        /// </summary>
         public string OpenParentCategoryPath => $"/{PathSegments.Take(PathSegments.Length - (GenericType || !HasGroup ? 1 : 0)).Join(delimiter: "/")}{(GenericType && HasGroup ? $"?{Group}" : "")}";
 
+        /// <summary>
+        /// Gets this path as a string.
+        /// </summary>
         public string Path { get; }
+
+        /// <summary>
+        /// Gets this path's individual segments.
+        /// </summary>
         public string[] PathSegments { get; }
+
+        /// <summary>
+        /// Gets this path's search string, if present.
+        /// </summary>
         public string? Search { get; }
 
         internal SelectorPath(string? rawPath, string? search, bool genericType, string? group, bool isSelectorRoot)
diff --git a/ComponentSelectorAdditions/SelectorSearchBar.cs b/ComponentSelectorAdditions/SelectorSearchBar.cs
index d2f4dcd..69f2e8a 100644
--- a/ComponentSelectorAdditions/SelectorSearchBar.cs
+++ b/ComponentSelectorAdditions/SelectorSearchBar.cs
@@ -9,35 +9,70 @@
 
 namespace ComponentSelectorAdditions
 {
+    /// <summary>
+    /// Contains details about a <see cref="ComponentSelector"/>'s <see cref="SearchBar"/>.
+    /// </summary>
     public sealed class SelectorSearchBar
     {
+        private readonly Func<int> _getSearchRefreshDelay;
         private CancellationTokenSource _lastResultUpdate = new();
 
+        /// <summary>
+        /// Gets or sets whether the search bar is currently shown.
+        /// </summary>
         public bool Active
         {
             get => Root.ActiveSelf;
             set => Root.ActiveSelf = value;
         }
 
+        /// <summary>
+        /// Gets or sets the search bar's current content.
+        /// <c>null</c> when inactive.
+        /// </summary>
         public string? Content
         {
             get => Active ? Text.Content.Value : null;
             set => Text.Content.Value = value;
         }
 
+        /// <summary>
+        /// Gets the search bar's <see cref="TextEditor"/>.
+        /// </summary>
         public TextEditor Editor { get; }
+
+        /// <summary>
+        /// Gets the search bar's root <see cref="Slot"/>.
+        /// </summary>
         public Slot Root { get; }
 
-        public int SearchRefreshDelay { get; }
+        /// <summary>
+        /// Gets the search bar's delay before updating when its content changes.
+        /// </summary>
+        public int SearchRefreshDelay => _getSearchRefreshDelay();
+
+        /// <summary>
+        /// Gets the search bar's <see cref="Text"/> element.
+        /// </summary>
         public Text Text => (Text)Editor.Text.Target;
 
-        public SelectorSearchBar(Slot root, TextEditor editor, int searchRefreshDelay)
+        /// <summary>
+        /// Creates a new search bar with the given details.
+        /// </summary>
+        /// <param name="root">The search bar's root slot.</param>
+        /// <param name="editor">The search bar's text editor.</param>
+        /// <param name="getSearchRefreshDelay">The search bar's delay before updating when its content changes.</param>
+        public SelectorSearchBar(Slot root, TextEditor editor, Func<int> getSearchRefreshDelay)
         {
             Root = root;
             Editor = editor;
-            SearchRefreshDelay = searchRefreshDelay;
+            _getSearchRefreshDelay = getSearchRefreshDelay ?? (() => 0);
         }
 
+        /// <summary>
+        /// Cancels the last triggered search and creates a new cancellation token for the new one.
+        /// </summary>
+        /// <returns>The newly created <see cref="CancellationToken"/> for the new search.</returns>
         public CancellationToken UpdateSearch()
         {
             _lastResultUpdate.Cancel();