@@ -201,16 +201,27 @@ function measureBlock(b, room, size, S, align) {
201201 }
202202 case 'rows' : {
203203 // tag pill · text · muted meta · mark on the right; long text wraps under itself.
204- const rs = Math . round ( size * 0.8 ) , rlh = rs * LINE , ts = Math . round ( rs * 0.82 ) , ph = ts + 7 ;
205- const rows = ( b . rows || [ ] ) . map ( ( r ) => {
204+ // In a narrow card the tag and mark would leave the text a sliver (a fixed-width box wrapped it every
205+ // two words), so the tag heads its row on a line of its own, with the mark beside it.
206+ const rs = Math . round ( size * 0.8 ) , rlh = rs * LINE , ts = Math . round ( rs * 0.82 ) , ph = ts + 7 , tagLine = Math . max ( rlh , ph ) + 2 ;
207+ const sized = ( b . rows || [ ] ) . map ( ( r ) => {
206208 const tagW = r . tag ? String ( r . tag ) . length * ts * S . charWidth * 1.05 + 12 : 0 ;
207209 const markW = r . mark ? String ( r . mark ) . length * rs * S . charWidth + 10 : 0 ;
210+ return { r, tagW, markW, inline : room - tagW - ( tagW ? 6 : 0 ) - markW } ;
211+ } ) ;
212+ // Decided once per card, so its rows line up: all tags inline, or all on their own line.
213+ const heads = sized . some ( ( x ) => x . r . tag && x . inline < room * 0.6 ) ;
214+ const rows = sized . map ( ( { r, tagW, markW, inline } ) => {
215+ const head = heads && ! ! r . tag ;
208216 const meta = r . meta ? parse ( String ( r . meta ) . replace ( / / g, '\u00a0' ) , { muted : true } ) [ 0 ] : [ ] ; // a detail never splits
209- const lines = wrapRich ( parse ( String ( r . text ?? '' ) , { mono : r . mono } ) , room - tagW - ( tagW ? 6 : 0 ) - markW , rs , S , false , meta ) ;
210- return { r, tagW, markW, lines, h : Math . max ( lines . length * rlh , r . tag ? ph : 0 ) } ;
217+ const lines = wrapRich ( parse ( String ( r . text ?? '' ) , { mono : r . mono } ) , head ? room : inline , rs , S , false , meta ) ;
218+ const textW = Math . max ( ...lines . map ( ( l ) => l . w ) ) ;
219+ return { r, tagW, markW, lines, heads : head ,
220+ w : head ? Math . max ( tagW + 6 + markW , textW ) : tagW + ( tagW ? 6 : 0 ) + textW + markW ,
221+ h : head ? tagLine + lines . length * rlh : Math . max ( lines . length * rlh , r . tag ? ph : 0 ) } ;
211222 } ) ;
212223 const gap = 5 ;
213- return { w : Math . max ( 0 , ...rows . map ( ( x ) => x . tagW + ( x . tagW ? 6 : 0 ) + Math . max ( ... x . lines . map ( ( l ) => l . w ) ) + x . markW ) ) , h : rows . reduce ( ( s , x ) => s + x . h + gap , - gap ) ,
224+ return { w : Math . max ( 0 , ...rows . map ( ( x ) => x . w ) ) , h : rows . reduce ( ( s , x ) => s + x . h + gap , - gap ) ,
214225 draw : ( x , y , width , color ) => {
215226 let out = '' , ty = y ;
216227 for ( const row of rows ) {
@@ -219,8 +230,8 @@ function measureBlock(b, room, size, S, align) {
219230 out += `<rect class="g-row-tag" x="${ x } " y="${ ty + ( rlh - ph ) / 2 } " width="${ row . tagW } " height="${ ph } " rx="4" fill="${ esc ( t . fill || S . tagFill ) } " stroke="${ esc ( t . stroke || 'none' ) } " stroke-opacity="0.5"/>` ;
220231 out += `<text x="${ x + row . tagW / 2 } " y="${ ty + rlh / 2 } " font-size="${ ts } " font-weight="600" fill="${ esc ( t . text || S . tagText ) } " text-anchor="middle" dominant-baseline="central" font-family="${ esc ( S . labelFont || S . font ) } ">${ esc ( row . r . tag ) } </text>` ;
221232 }
222- const tx = x + row . tagW + ( row . tagW ? 6 : 0 ) ;
223- row . lines . forEach ( ( l , i ) => ( out += richLine ( l , tx , ty + rlh * ( i + 0.5 ) , rs , color , 'start' , S ) ) ) ;
233+ const tx = row . heads ? x : x + row . tagW + ( row . tagW ? 6 : 0 ) , top = row . heads ? ty + tagLine : ty ;
234+ row . lines . forEach ( ( l , i ) => ( out += richLine ( l , tx , top + rlh * ( i + 0.5 ) , rs , color , 'start' , S ) ) ) ;
224235 if ( row . r . mark ) out += `<text class="g-row-mark" x="${ x + width } " y="${ ty + rlh / 2 } " font-size="${ rs } " font-weight="600" fill="${ esc ( S . accent ) } " text-anchor="end" dominant-baseline="central" font-family="${ esc ( S . labelFont || S . font ) } ">${ esc ( row . r . mark ) } </text>` ;
225236 ty += row . h + gap ;
226237 }
0 commit comments