Browse Source

improve icon error message (#4796)

Khaleel Al-Adhami 3 months ago
parent
commit
90be664981
2 changed files with 41 additions and 3 deletions
  1. 11 3
      reflex/components/lucide/icon.py
  2. 30 0
      reflex/utils/format.py

+ 11 - 3
reflex/components/lucide/icon.py

@@ -54,7 +54,7 @@ class Icon(LucideIconComponent):
         if "tag" not in props:
             raise AttributeError("Missing 'tag' keyword-argument for Icon")
 
-        tag: str | Var | LiteralVar = props.pop("tag")
+        tag: str | Var | LiteralVar = Var.create(props.pop("tag"))
         if isinstance(tag, LiteralVar):
             if isinstance(tag, LiteralStringVar):
                 tag = tag._var_value
@@ -70,9 +70,17 @@ class Icon(LucideIconComponent):
             not isinstance(tag, str)
             or format.to_snake_case(tag) not in LUCIDE_ICON_LIST
         ):
+            if isinstance(tag, str):
+                icons_sorted = sorted(
+                    LUCIDE_ICON_LIST,
+                    key=lambda s: format.length_of_largest_common_substring(tag, s),
+                    reverse=True,
+                )
+            else:
+                icons_sorted = LUCIDE_ICON_LIST
             raise ValueError(
-                f"Invalid icon tag: {tag}. Please use one of the following: {', '.join(LUCIDE_ICON_LIST[0:25])}, ..."
-                "\nSee full list at https://lucide.dev/icons."
+                f"Invalid icon tag: {tag}. Please use one of the following: {', '.join(icons_sorted[0:25])}, ..."
+                "\nSee full list at https://reflex.dev/docs/library/data-display/icon/#icons-list."
             )
 
         if tag in LUCIDE_ICON_MAPPING_OVERRIDE:

+ 30 - 0
reflex/utils/format.py

@@ -27,6 +27,36 @@ WRAP_MAP = {
 }
 
 
+def length_of_largest_common_substring(str1: str, str2: str) -> int:
+    """Find the length of the largest common substring between two strings.
+
+    Args:
+        str1: The first string.
+        str2: The second string.
+
+    Returns:
+        The length of the largest common substring.
+    """
+    if not str1 or not str2:
+        return 0
+
+    # Create a matrix of size (len(str1) + 1) x (len(str2) + 1)
+    dp = [[0] * (len(str2) + 1) for _ in range(len(str1) + 1)]
+
+    # Variables to keep track of maximum length and ending position
+    max_length = 0
+
+    # Fill the dp matrix
+    for i in range(1, len(str1) + 1):
+        for j in range(1, len(str2) + 1):
+            if str1[i - 1] == str2[j - 1]:
+                dp[i][j] = dp[i - 1][j - 1] + 1
+                if dp[i][j] > max_length:
+                    max_length = dp[i][j]
+
+    return max_length
+
+
 def get_close_char(open: str, close: str | None = None) -> str:
     """Check if the given character is a valid brace.