|
19 | 19 | from plotly.offline import get_plotlyjs |
20 | 20 |
|
21 | 21 | # Simple HTML template for rendering a card with a title, subtitle, and body with |
22 | | -# scrollable overflow. |
| 22 | +# scrollable overflow. Subtitles are rendered in a <div> with max-height overflow |
| 23 | +# so that any HTML content (tables, lists, etc.) is valid and clipped correctly |
| 24 | +# in the collapsed state. A "See more"/"See less" toggle appears when content |
| 25 | +# overflows (matching the web UI pattern). |
23 | 26 | html_card_template = """ |
24 | 27 | <style> |
25 | 28 | .card {{ |
|
30 | 33 | border-radius: 0.5em; |
31 | 34 | padding: 10px; |
32 | 35 | }} |
33 | | -.card-header:hover {{ |
34 | | - cursor: pointer; |
35 | | -}} |
36 | | -.card-header details summary {{ |
37 | | - list-style: none; |
38 | | - display: inline-flex; |
39 | | - align-items: center; |
40 | | - gap: 0.5em; |
| 36 | +.card-subtitle {{ |
| 37 | + color: gray; |
| 38 | + font-size: 0.9em; |
| 39 | + margin: 4px 0 0 0; |
| 40 | + line-height: 1.4em; |
| 41 | + max-height: 1.4em; |
| 42 | + overflow: hidden; |
| 43 | + white-space: nowrap; |
| 44 | + text-overflow: ellipsis; |
41 | 45 | }} |
42 | | -.card-header details summary::-webkit-details-marker {{ |
| 46 | +.card-subtitle-toggle {{ |
| 47 | + color: #1877F2; |
| 48 | + cursor: pointer; |
| 49 | + font-size: 0.85em; |
| 50 | + background: none; |
| 51 | + border: none; |
| 52 | + padding: 0; |
| 53 | + margin-top: 2px; |
43 | 54 | display: none; |
44 | 55 | }} |
45 | | -.card-header details summary::after {{ |
46 | | - content: "ℹ️"; |
47 | | - font-size: 0.9em; |
48 | | -}} |
49 | 56 | </style> |
50 | 57 | <div class="card"> |
51 | 58 | <div class="card-header"> |
52 | | - <details> |
53 | | - <summary><b>{title_str}</b></summary> |
54 | | - <p>{subtitle_str}</p> |
55 | | - </details> |
| 59 | + <b>{title_str}</b> |
| 60 | + <div class="card-subtitle">{subtitle_str}</div> |
| 61 | + <button class="card-subtitle-toggle">See more</button> |
56 | 62 | </div> |
57 | 63 | <div class="card-body"> |
58 | 64 | {body_html} |
59 | 65 | </div> |
60 | 66 | </div> |
| 67 | +<script> |
| 68 | +(function() {{ |
| 69 | + var card = document.currentScript.previousElementSibling; |
| 70 | + var subtitle = card.querySelector('.card-subtitle'); |
| 71 | + var toggle = card.querySelector('.card-subtitle-toggle'); |
| 72 | + if (subtitle && toggle) {{ |
| 73 | + requestAnimationFrame(function() {{ |
| 74 | + if (subtitle.scrollHeight > subtitle.clientHeight |
| 75 | + || subtitle.scrollWidth > subtitle.clientWidth) {{ |
| 76 | + toggle.style.display = 'inline'; |
| 77 | + }} |
| 78 | + }}); |
| 79 | + toggle.onclick = function() {{ |
| 80 | + if (subtitle.style.maxHeight === 'none') {{ |
| 81 | + subtitle.style.maxHeight = '1.4em'; |
| 82 | + subtitle.style.whiteSpace = 'nowrap'; |
| 83 | + subtitle.style.textOverflow = 'ellipsis'; |
| 84 | + toggle.textContent = 'See more'; |
| 85 | + }} else {{ |
| 86 | + subtitle.style.maxHeight = 'none'; |
| 87 | + subtitle.style.whiteSpace = 'normal'; |
| 88 | + subtitle.style.textOverflow = 'clip'; |
| 89 | + toggle.textContent = 'See less'; |
| 90 | + }} |
| 91 | + }}; |
| 92 | + }} |
| 93 | +}})(); |
| 94 | +</script> |
61 | 95 | """ |
62 | 96 |
|
63 | 97 | # Simple HTML template for rendering a *group* card with a title, subtitle, and |
|
0 commit comments