diff --git a/routes/elements/element_add.py b/routes/elements/element_add.py
index 40786900..615ddf1f 100644
--- a/routes/elements/element_add.py
+++ b/routes/elements/element_add.py
@@ -17,4 +17,11 @@ def element_add(slug, screen_id):
et = types.get(int(element_type_id))
widget = et["default_widget"] if et else "conteneur"
new_id = screens.add_element(slug, screen_id, widget, element_type_id)
+ icon_class = request.form.get("icon_class")
+ if widget == "icone" and icon_class:
+ # Posé depuis la galerie d'icônes (voir le panneau de propriétés,
+ # section "Icônes") : la classe Font Awesome choisie remplace celle
+ # posée par défaut à la création plutôt que de repartir d'une icône
+ # neutre que l'utilisateur devrait ensuite retaper à la main.
+ screens.save_element_controls(slug, new_id, {"ctrl_icon_class": icon_class})
return redirect(url_for("screen_edit", slug=slug, screen_id=screen_id, selected=new_id))
diff --git a/routes/screens/screen_edit.py b/routes/screens/screen_edit.py
index 468a179b..ed2ea7a9 100644
--- a/routes/screens/screen_edit.py
+++ b/routes/screens/screen_edit.py
@@ -73,4 +73,5 @@ def screen_edit(slug, screen_id):
animation_clips=animation_clips, animation_clips_json=json.dumps(animation_clips),
animate_css_catalog=screens.ANIMATE_CSS_CATALOG,
animate_css_labels_json=json.dumps(screens.ANIMATE_CSS_LABELS),
+ fontawesome_icons=screens.FONTAWESOME_ICONS,
)
diff --git a/screens/__init__.py b/screens/__init__.py
index e40b97f5..7427a388 100644
--- a/screens/__init__.py
+++ b/screens/__init__.py
@@ -41,6 +41,7 @@ from .widgets.registry import WIDGETS
from .widgets.container_widgets import CONTAINER_WIDGETS
from .widgets.layout_capable_widgets import LAYOUT_CAPABLE_WIDGETS
from .widgets.font_options import GOOGLE_FONTS_LINK
+from .widgets.fontawesome_icons import FONTAWESOME_ICONS
from .widgets.widget_meta import widget_meta
from .widgets.controls_with_values import controls_with_values
from .widgets.data_definition_options import data_definition_options
diff --git a/screens/widgets/fontawesome_icons.py b/screens/widgets/fontawesome_icons.py
new file mode 100644
index 00000000..75d12431
--- /dev/null
+++ b/screens/widgets/fontawesome_icons.py
@@ -0,0 +1,46 @@
+# Sélection large mais CURATÉE d'icônes Font Awesome 5 Free (style "solid")
+# pour la galerie du widget Icône (voir bulma_controls.py/registry.py et la
+# section "Icônes" du panneau de propriétés dans screen_edit.html) —
+# volontairement PAS le catalogue Font Awesome 5 Free complet (~1500 icônes) :
+# une liste embarquée doit être garantie exacte (une classe qui n'existe pas
+# affiche une case vide dans la police), donc on limite ici aux icônes dont
+# le nom est sûr plutôt que de deviner l'exhaustif. N'importe quelle autre
+# icône Font Awesome 5 reste utilisable en tapant directement sa classe dans
+# le réglage "Icône" du panneau de propriétés.
+FONTAWESOME_ICONS = [
+ "star", "heart", "check", "times", "plus", "minus", "search", "cog", "cogs", "wrench",
+ "hammer", "tools", "trash", "trash-alt", "edit", "pen", "pencil-alt", "save", "download",
+ "upload", "share", "share-alt", "link", "unlink", "lock", "lock-open", "key", "eye",
+ "eye-slash", "bell", "bell-slash", "bookmark", "flag", "flag-checkered", "thumbtack",
+ "filter", "sort", "sort-up", "sort-down", "list", "list-ul", "list-ol", "th", "th-list",
+ "th-large", "bars", "ellipsis-h", "ellipsis-v", "expand", "compress", "sync", "sync-alt",
+ "redo", "undo", "home", "user", "users", "user-circle", "user-plus", "user-minus",
+ "user-friends", "sign-in-alt", "sign-out-alt", "question-circle", "info-circle",
+ "exclamation-circle", "exclamation-triangle", "times-circle", "check-circle", "ban",
+ "shield-alt", "gem", "coins", "money-bill", "wallet", "credit-card", "gift", "trophy",
+ "medal", "award", "crown", "dice", "dice-d6", "dice-d20", "chess", "chess-king",
+ "chess-queen", "chess-knight", "chess-bishop", "chess-rook", "chess-pawn", "puzzle-piece",
+ "gamepad", "rocket", "bomb", "fire", "bolt", "snowflake", "sun", "moon", "cloud",
+ "cloud-rain", "wind", "umbrella", "tree", "leaf", "seedling", "paw", "spider", "skull",
+ "skull-crossbones", "map", "map-marker-alt", "map-marked-alt", "compass", "mountain",
+ "water", "globe", "globe-americas", "flask", "vial", "syringe", "pills", "heartbeat",
+ "dumbbell", "running", "walking", "swimmer", "futbol", "basketball-ball", "volleyball-ball",
+ "football-ball", "baseball-ball", "table-tennis", "bowling-ball", "horse", "dove", "cat",
+ "dog", "fish", "frog", "hippo", "otter", "kiwi-bird", "book", "book-open", "graduation-cap",
+ "school", "chalkboard", "chalkboard-teacher", "pencil-ruler", "ruler", "ruler-combined",
+ "calculator", "laptop", "desktop", "mobile-alt", "tablet-alt", "keyboard", "mouse",
+ "headphones", "microphone", "video", "camera", "image", "images", "film", "music", "play",
+ "pause", "stop", "step-forward", "step-backward", "volume-up", "volume-down", "volume-mute",
+ "volume-off", "envelope", "envelope-open", "comment", "comments", "comment-dots", "phone",
+ "phone-alt", "calendar", "calendar-alt", "calendar-check", "clock", "hourglass",
+ "hourglass-half", "stopwatch", "car", "car-side", "truck", "plane", "plane-departure",
+ "ship", "anchor", "subway", "train", "bus", "bicycle", "taxi", "road", "traffic-light",
+ "gas-pump", "screwdriver", "toolbox", "hard-hat", "building", "city", "industry",
+ "warehouse", "store", "shopping-cart", "shopping-bag", "box", "boxes", "dolly", "pallet",
+ "archive", "folder", "folder-open", "file", "file-alt", "file-pdf", "file-word",
+ "file-excel", "file-image", "file-video", "file-audio", "database", "server",
+ "network-wired", "wifi", "signal", "satellite", "satellite-dish", "robot", "microchip",
+ "memory", "hdd", "print", "cut", "paste", "copy", "clipboard", "clipboard-list",
+ "clipboard-check", "sticky-note", "paperclip", "paint-brush", "palette", "magic",
+ "fire-extinguisher", "first-aid", "briefcase", "suitcase",
+]
diff --git a/screens/widgets/registry.py b/screens/widgets/registry.py
index 354cbf6d..606adcc4 100644
--- a/screens/widgets/registry.py
+++ b/screens/widgets/registry.py
@@ -315,4 +315,20 @@ WIDGETS = {
"w": 60, "h": 40, "default_content": "",
"controls": BULMA_TABS_CONTROLS,
},
+ "icone": {
+ # La classe Font Awesome ("fa-solid fa-xxx") EST le contenu visuel de
+ # ce widget — posée soit en cliquant/glissant une icône depuis la
+ # galerie du panneau de propriétés (voir routes/elements/element_add.py,
+ # qui pré-remplit ce réglage), soit tapée à la main ici pour n'importe
+ # quelle icône Font Awesome 5 hors de la sélection curatée de la
+ # galerie (voir fontawesome_icons.py).
+ "label": "Icône", "icon": "🔤", "tag": "i", "has_content": False,
+ "w": 15, "h": 15, "default_content": "",
+ "controls": [
+ c_text("icon_class", "Icône (classe Font Awesome 5)", "attr:class",
+ default="fa-solid fa-star", placeholder="fa-solid fa-heart", group="Contenu"),
+ c_slider("font-size", "Taille", "style:font-size", min=10, max=160, default=32, group="Texte"),
+ c_color("color", "Couleur", "style:color", "#e8eaf0", group="Texte"),
+ ],
+ },
}
diff --git a/static/style.css b/static/style.css
index 2a5ec86b..c486ee65 100644
--- a/static/style.css
+++ b/static/style.css
@@ -183,6 +183,18 @@ body.builderBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden; d
#propsPanelReopenBtn{ right:24px; }
.widgetGrid{ display:grid; grid-template-columns:1fr 1fr; gap:8px; }
+
+/* Galerie d'icônes Font Awesome (panneau de propriétés) — voir
+ fontawesome_icons.py et addIconElement()/filterIconGallery() plus bas. */
+.iconGallery{ display:grid; grid-template-columns:repeat(6, 1fr); gap:6px; max-height:220px; overflow-y:auto; margin-top:8px; }
+.iconGalleryTile{
+ aspect-ratio:1; display:flex; align-items:center; justify-content:center;
+ background:var(--panel2); border:1px solid var(--border); border-radius:6px;
+ color:var(--text); cursor:grab; font-size:15px; padding:0;
+}
+.iconGalleryTile:hover{ border-color:var(--accent); color:var(--accent); }
+.iconGalleryTile.dragging{ opacity:0.4; }
+.iconGalleryTile.iconHidden{ display:none; }
.widgetBtnForm{ margin:0; }
.widgetBtn{
width:100%; display:flex; flex-direction:column; align-items:center; gap:4px;
diff --git a/templates/play.html b/templates/play.html
index 940b0497..4e0ffbf9 100644
--- a/templates/play.html
+++ b/templates/play.html
@@ -8,6 +8,7 @@
+