@@ -258,6 +258,91 @@ def get_currency(self, item: M) -> str:
258
258
return getattr (item , "currency" , "usd" )
259
259
260
260
261
+ class DescriptionListSocialsItem [M ](DescriptionListItem [M ]):
262
+ """A description list item that displays social links with platform icons.
263
+
264
+ This item displays social links from the model, including both the socials
265
+ list and twitter_username field, with appropriate formatting and icons.
266
+
267
+ Args:
268
+ M: Type parameter for the model type.
269
+ """
270
+
271
+ def render (self , request : Request , item : M ) -> Generator [None ] | None :
272
+ """Render social links with platform icons and external links.
273
+
274
+ Args:
275
+ request: The FastAPI request object.
276
+ item: The data object to render social links from.
277
+ """
278
+ socials = getattr (item , "socials" , [])
279
+ twitter_username = getattr (item , "twitter_username" , None )
280
+
281
+ with tag .div (classes = "flex flex-col gap-2" ):
282
+ # Display Twitter/X username if available
283
+ if twitter_username :
284
+ with tag .div (classes = "flex items-center gap-2" ):
285
+ with tag .span (classes = "text-sm font-medium" ):
286
+ text ("𝕏 (Twitter):" )
287
+ with tag .a (
288
+ href = f"https://twitter.com/{ twitter_username } " ,
289
+ classes = "link flex items-center gap-1" ,
290
+ target = "_blank" ,
291
+ rel = "noopener noreferrer" ,
292
+ ):
293
+ text (f"@{ twitter_username } " )
294
+ with tag .div (classes = "icon-external-link" ):
295
+ pass
296
+
297
+ # Display social links from socials field
298
+ if socials :
299
+ for social in socials :
300
+ platform = social .get ("platform" , "" )
301
+ url = social .get ("url" , "" )
302
+ if platform and url :
303
+ with tag .div (classes = "flex items-center gap-2" ):
304
+ with tag .span (classes = "text-sm font-medium" ):
305
+ # Add platform-specific icons/emojis
306
+ if platform .lower () in ["twitter" , "x" ]:
307
+ text ("𝕏:" )
308
+ elif platform .lower () == "github" :
309
+ text ("GitHub:" )
310
+ elif platform .lower () == "linkedin" :
311
+ text ("LinkedIn:" )
312
+ elif platform .lower () == "youtube" :
313
+ text ("YouTube:" )
314
+ elif platform .lower () == "instagram" :
315
+ text ("Instagram:" )
316
+ elif platform .lower () == "facebook" :
317
+ text ("Facebook:" )
318
+ elif platform .lower () == "discord" :
319
+ text ("Discord:" )
320
+ else :
321
+ text (f"{ platform .title ()} :" )
322
+ with tag .a (
323
+ href = url ,
324
+ classes = "link flex items-center gap-1" ,
325
+ target = "_blank" ,
326
+ rel = "noopener noreferrer" ,
327
+ ):
328
+ # Display the URL or just the platform name
329
+ display_text = url
330
+ if url .startswith ("https://" ):
331
+ display_text = url [8 :] # Remove https://
332
+ elif url .startswith ("http://" ):
333
+ display_text = url [7 :] # Remove http://
334
+ text (display_text )
335
+ with tag .div (classes = "icon-external-link" ):
336
+ pass
337
+
338
+ # Show message if no social links
339
+ if not socials and not twitter_username :
340
+ with tag .span (classes = "text-gray-500 italic" ):
341
+ text ("No social links available" )
342
+
343
+ return None
344
+
345
+
261
346
class DescriptionList [M ]:
262
347
"""A complete description list component for displaying structured data.
263
348
0 commit comments