Skip to content

Commit 16f2e4c

Browse files
committed
wip: wordwrap on very long label
1 parent 063d81a commit 16f2e4c

File tree

2 files changed

+63
-7
lines changed

2 files changed

+63
-7
lines changed

packages/webui/src/client/ui/ClockView/DirectorScreen.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,8 @@ function DirectorScreenRender({
402402
width={'80vw'}
403403
fontFamily="Roboto"
404404
fontSize="1em"
405+
minFontSize={70}
406+
maxFontSize={100}
405407
minLetterSpacing={0}
406408
useVariableFont={true}
407409
hardCutText={true}
@@ -436,6 +438,8 @@ function DirectorScreenRender({
436438
width: '90vw',
437439
fontFamily: 'Roboto Flex',
438440
fontSize: '2em',
441+
minFontSize: 70,
442+
maxFontSize: 120,
439443
minLetterSpacing: 2,
440444
useVariableFont: true,
441445
}}
@@ -512,6 +516,8 @@ function DirectorScreenRender({
512516
width: '90vw',
513517
fontFamily: 'Roboto Flex',
514518
fontSize: '2em',
519+
minFontSize: 70,
520+
maxFontSize: 120,
515521
minLetterSpacing: 2,
516522
useVariableFont: true,
517523
}}

packages/webui/src/client/ui/util/AdjustLabelFit.tsx

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ export interface AdjustLabelFitProps {
2424
fontSize?: string | number
2525

2626
/**
27-
* Minimum font size in pixels (for auto-scaling)
28-
* Default is 10px
27+
* Minimum font size in percentage relative to fontSize (for auto-scaling)
28+
* Default is 50
2929
*/
3030
minFontSize?: number
3131

3232
/**
33-
* Maximum font size in pixels (for auto-scaling)
34-
* Default is 100px
33+
* Maximum font size in percentage relative to fontSize (for auto-scaling)
34+
* Default is 120
3535
*/
3636
maxFontSize?: number
3737

@@ -70,6 +70,7 @@ export interface AdjustLabelFitProps {
7070

7171
/**
7272
* Hard cut length of the text if it doesn't fit
73+
* When unset, it will wrap text per letter
7374
*/
7475
hardCutText?: boolean
7576
}
@@ -83,8 +84,8 @@ export const AdjustLabelFit: React.FC<AdjustLabelFitProps> = ({
8384
width,
8485
fontFamily,
8586
fontSize,
86-
minFontSize = 10,
87-
maxFontSize = 100,
87+
minFontSize = 50,
88+
maxFontSize = 120,
8889
minLetterSpacing = -1,
8990
containerStyle = {},
9091
labelStyle = {},
@@ -104,6 +105,7 @@ export const AdjustLabelFit: React.FC<AdjustLabelFitProps> = ({
104105
overflow: 'hidden',
105106
...containerStyle,
106107
...(widthValue ? { width: widthValue } : {}),
108+
...(hardCutText ? {} : { wordBreak: 'break-all' }),
107109
}
108110

109111
// Label style - add optional font settings
@@ -169,7 +171,6 @@ export const AdjustLabelFit: React.FC<AdjustLabelFitProps> = ({
169171
const currentFontSize = parseFloat(window.getComputedStyle(labelElement).fontSize)
170172
const scaleFactor = containerWidth / textWidth
171173
const newFontSize = Math.max(currentFontSize * scaleFactor, minFontSize)
172-
173174
labelElement.style.fontSize = `${newFontSize}px`
174175

175176
// Remeasure after font size adjustment
@@ -214,6 +215,30 @@ export const AdjustLabelFit: React.FC<AdjustLabelFitProps> = ({
214215
const visibleChars = Math.floor(label.length * ratio) - 1
215216
labelElement.textContent = label.slice(0, Math.max(visibleChars, 1))
216217
}
218+
} else {
219+
// Apply line wrapping per letter if hardCutText is not set
220+
void labelElement.offsetWidth
221+
const finalTextWidth = labelElement.getBoundingClientRect().width
222+
if (finalTextWidth > containerWidth) {
223+
const currentFontSize = parseFloat(window.getComputedStyle(labelElement).fontSize)
224+
const minFontSizeValue = currentFontSize * (minFontSize / 100)
225+
labelElement.style.fontSize = `${minFontSizeValue}px`
226+
227+
labelElement.textContent = ''
228+
229+
for (let i = 0; i < label.length; i++) {
230+
const charSpan = document.createElement('span')
231+
charSpan.textContent = label[i]
232+
charSpan.style.display = 'inline-block'
233+
charSpan.style.wordBreak = 'break-all'
234+
charSpan.style.whiteSpace = 'normal'
235+
labelElement.appendChild(charSpan)
236+
}
237+
238+
// Apply wrapping styles
239+
labelElement.style.wordBreak = 'break-all'
240+
labelElement.style.whiteSpace = 'normal'
241+
}
217242
}
218243
}
219244
} else {
@@ -236,6 +261,31 @@ export const AdjustLabelFit: React.FC<AdjustLabelFitProps> = ({
236261
const visibleChars = Math.floor(label.length * ratio) - 1
237262
labelElement.textContent = label.slice(0, Math.max(visibleChars, 1))
238263
}
264+
} else {
265+
// Apply line wrapping per letter if hardCutText is not set
266+
void labelElement.offsetWidth
267+
const finalTextWidth = labelElement.getBoundingClientRect().width
268+
if (finalTextWidth > containerWidth) {
269+
const currentFontSize = parseFloat(window.getComputedStyle(labelElement).fontSize)
270+
// Use minFontSize as a percentage relative to fontSize
271+
const minFontSizeValue = (fontSize ? parseFloat(fontSizeValue || '0') : currentFontSize) * (minFontSize / 100)
272+
//labelElement.style.fontSize = `${minFontSizeValue}px`
273+
274+
labelElement.textContent = ''
275+
276+
for (let i = 0; i < label.length; i++) {
277+
const charSpan = document.createElement('span')
278+
charSpan.textContent = label[i]
279+
charSpan.style.display = 'inline-block'
280+
charSpan.style.wordBreak = 'break-all'
281+
charSpan.style.whiteSpace = 'normal'
282+
labelElement.appendChild(charSpan)
283+
}
284+
285+
// Apply wrapping styles
286+
labelElement.style.wordBreak = 'break-all'
287+
labelElement.style.whiteSpace = 'normal'
288+
}
239289
}
240290
}
241291
}

0 commit comments

Comments
 (0)