Skip to content

Commit 060b2ac

Browse files
committed
feat: useLetterSpacing option (default false) and static opticalfontSize option (default 120)
1 parent 046917c commit 060b2ac

File tree

2 files changed

+47
-40
lines changed

2 files changed

+47
-40
lines changed

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,9 @@ function DirectorScreenRender({
405405
fontSize="0.9em"
406406
minFontWidth={70}
407407
maxFontWidth={100}
408-
defaultWidth={90}
409-
minLetterSpacing={0}
408+
defaultWidth={100}
409+
defaultOpticalSize={120}
410+
useLetterSpacing={false}
410411
hardCutText={true}
411412
/>
412413
{playlist.currentPartInfo?.partInstanceId ? (
@@ -445,7 +446,8 @@ function DirectorScreenRender({
445446
minFontWidth: 55,
446447
maxFontWidth: 100,
447448
defaultWidth: 90,
448-
minLetterSpacing: 0,
449+
useLetterSpacing: false,
450+
defaultOpticalSize: 120,
449451
}}
450452
/>
451453
</div>
@@ -495,7 +497,8 @@ function DirectorScreenRender({
495497
minFontWidth={70}
496498
maxFontWidth={100}
497499
defaultWidth={90}
498-
minLetterSpacing={0}
500+
defaultOpticalSize={120}
501+
useLetterSpacing={false}
499502
hardCutText={true}
500503
/>
501504
) : undefined}
@@ -546,7 +549,8 @@ function DirectorScreenRender({
546549
minFontWidth: 55,
547550
maxFontWidth: 100,
548551
defaultWidth: 90,
549-
minLetterSpacing: 0,
552+
useLetterSpacing: false,
553+
defaultOpticalSize: 120,
550554
}}
551555
/>
552556
) : (

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

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ export interface AdjustLabelFitProps {
4545
*/
4646
maxFontWidth?: number
4747

48+
/**
49+
* Enable letter spacing adjustment to fit text
50+
* Default is false
51+
*/
52+
useLetterSpacing?: boolean
53+
4854
/**
4955
* Minimum letter spacing in pixels
5056
* Default is -1px
@@ -84,8 +90,9 @@ export const AdjustLabelFit: React.FC<AdjustLabelFitProps> = ({
8490
fontSize,
8591
minFontWidth = 50,
8692
maxFontWidth = 120,
87-
defaultOpticalSize = 40,
93+
defaultOpticalSize = 120,
8894
defaultWidth = 100,
95+
useLetterSpacing = false,
8996
minLetterSpacing = -1,
9097
containerStyle = {},
9198
labelStyle = {},
@@ -145,7 +152,6 @@ export const AdjustLabelFit: React.FC<AdjustLabelFitProps> = ({
145152

146153
// Apply the new width setting
147154
labelElement.style.fontVariationSettings = `'opsz' ${defaultOpticalSize}, 'wdth' ${defaultWidth}`
148-
149155
// Reset label content if it was cut
150156
labelElement.textContent = label
151157

@@ -163,65 +169,62 @@ export const AdjustLabelFit: React.FC<AdjustLabelFitProps> = ({
163169
void labelElement.offsetWidth
164170

165171
const containerWidth = containerElement.clientWidth
166-
// Remeasure after font size adjustment
167-
void labelElement.offsetWidth
168172
const newTextWidth = labelElement.getBoundingClientRect().width
169173

170174
// If text now fits with font size adjustment alone, we're done
171175
if (newTextWidth <= containerWidth) return
172176

173177
const widthRatio = containerWidth / newTextWidth
174178
let currentWidth = defaultWidth * widthRatio
175-
const currentOpticalSize = 100 - defaultOpticalSize * widthRatio
176179

177180
// Use a reasonable range for width variation
178181
currentWidth = Math.max(currentWidth, minFontWidth)
179182
currentWidth = Math.min(currentWidth, maxFontWidth)
180183

181-
labelElement.style.fontVariationSettings = `'opsz' ${currentOpticalSize}, 'wdth' ${currentWidth}`
184+
labelElement.style.fontVariationSettings = `'opsz' ${defaultOpticalSize}, 'wdth' ${currentWidth}`
182185

183186
// Remeasure text width after adjustment:
184187
void labelElement.offsetWidth
185188
const adjustedTextWidth = labelElement.getBoundingClientRect().width
186189

187190
// Letter spacing if text still overflows
188-
if (adjustedTextWidth > containerWidth) {
191+
if (useLetterSpacing && adjustedTextWidth > containerWidth) {
189192
const overflow = adjustedTextWidth - containerWidth
190193
const letterCount = label.length - 1 // Spaces between letters
191194
let letterSpacing = letterCount > 0 ? -overflow / letterCount : 0
192195

193196
letterSpacing = Math.max(letterSpacing, minLetterSpacing)
194197
labelElement.style.letterSpacing = `${letterSpacing}px`
198+
}
195199

196-
// Hard cut text if enabled and letterspacing is not enough:
197-
if (hardCutText) {
198-
void labelElement.offsetWidth
199-
const finalTextWidth = labelElement.getBoundingClientRect().width
200-
if (finalTextWidth > containerWidth) {
201-
const ratio = containerWidth / finalTextWidth
202-
const visibleChars = Math.floor(label.length * ratio) - 1
203-
labelElement.textContent = label.slice(0, Math.max(visibleChars, 1))
204-
}
205-
} else {
206-
// Apply line wrapping per letter if hardCutText is not set
207-
void labelElement.offsetWidth
208-
const finalTextWidth = labelElement.getBoundingClientRect().width
209-
if (finalTextWidth > containerWidth) {
210-
labelElement.textContent = ''
211-
212-
for (let i = 0; i < label.length; i++) {
213-
const charSpan = document.createElement('span')
214-
charSpan.textContent = label[i]
215-
charSpan.style.display = 'inline-block'
216-
charSpan.style.wordBreak = 'break-all'
217-
charSpan.style.whiteSpace = 'normal'
218-
labelElement.appendChild(charSpan)
219-
}
220-
221-
// Apply wrapping styles
222-
labelElement.style.wordBreak = 'break-all'
223-
labelElement.style.whiteSpace = 'normal'
200+
// Hard cut text or wrap per letter:
201+
if (hardCutText) {
202+
void labelElement.offsetWidth
203+
const finalTextWidth = labelElement.getBoundingClientRect().width
204+
if (finalTextWidth > containerWidth) {
205+
const ratio = containerWidth / finalTextWidth
206+
const visibleChars = Math.floor(label.length * ratio) - 1
207+
labelElement.textContent = label.slice(0, Math.max(visibleChars, 1))
208+
}
209+
} else {
210+
// Apply line wrapping per letter if hardCutText is not set
211+
void labelElement.offsetWidth
212+
const finalTextWidth = labelElement.getBoundingClientRect().width
213+
if (finalTextWidth > containerWidth) {
214+
labelElement.textContent = ''
215+
216+
for (let i = 0; i < label.length; i++) {
217+
const charSpan = document.createElement('span')
218+
charSpan.textContent = label[i]
219+
charSpan.style.display = 'inline-block'
220+
charSpan.style.wordBreak = 'break-all'
221+
charSpan.style.whiteSpace = 'normal'
222+
labelElement.appendChild(charSpan)
224223
}
224+
225+
// Apply wrapping styles
226+
labelElement.style.wordBreak = 'break-all'
227+
labelElement.style.whiteSpace = 'normal'
225228
}
226229
}
227230
}

0 commit comments

Comments
 (0)