Skip to content

Commit

Permalink
refactor: remove size limits in title
Browse files Browse the repository at this point in the history
  • Loading branch information
cpvalente committed Jun 22, 2024
1 parent cfc3aab commit 6c20cb5
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 69 deletions.
34 changes: 18 additions & 16 deletions apps/client/src/common/components/title-card/TitleCard.scss
Original file line number Diff line number Diff line change
@@ -1,25 +1,37 @@
@use '../../../theme/viewerDefs' as *;

.title-card {
position: relative;
display: flex;
flex-direction: column;
gap: 0.5rem;
gap: 0.25rem;
}

.inline {
display: flex;
.title-card__title,
.title-card__secondary {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.title-card__title {
font-weight: 600;
font-size: clamp(32px, 3.5vw, 50px);
font-size: clamp(1.5rem, 3vw, 3rem);
color: var(--color-override, $viewer-color);
line-height: 1.1em;
line-height: 1.2em;
}

.title-card__secondary {
font-size: clamp(1rem, 2vw, 2.25rem);
color: var(--secondary-color-override, $viewer-secondary-color);
line-height: 1.2em;
}

.title-card__label {
position: absolute;
right: 1rem;
top: 0.5rem;
font-size: clamp(1rem, 1.5vw, 1.5rem);
font-weight: 400;
color: var(--secondary-color-override, $viewer-secondary-color);
margin-left: auto;
text-transform: uppercase;
Expand All @@ -28,13 +40,3 @@
color: var(--accent-color-override, $accent-color);
}
}

.title-card__secondary {
font-size: clamp(1.5rem, 2vw, 2.25rem);
color: var(--secondary-color-override, $viewer-secondary-color);
line-height: 1.1em;

&::after {
content: '\200b';
}
}
26 changes: 15 additions & 11 deletions apps/client/src/common/components/title-card/TitleCard.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
import { ForwardedRef, forwardRef } from 'react';

import { useTranslation } from '../../../translation/TranslationProvider';

import './TitleCard.scss';

interface TitleCardProps {
label: 'now' | 'next';
title: string;
label?: 'now' | 'next';
secondary?: string;
className?: string;
}

export default function TitleCard(props: TitleCardProps) {
const { label, title, secondary } = props;
const TitleCard = forwardRef((props: TitleCardProps, ref: ForwardedRef<HTMLDivElement>) => {
const { label, title, secondary, className = '' } = props;
const { getLocalizedString } = useTranslation();

const accent = label === 'now';

return (
<div className='title-card'>
<div className='inline'>
<span className='title-card__title'>{title}</span>
<span className={accent ? 'title-card__label title-card__label--accent' : 'title-card__label'}>
{getLocalizedString(`common.${label}`)}
</span>
</div>
<div className={`title-card ${className}`} ref={ref}>
<span className='title-card__title'>{title}</span>
<span className={accent ? 'title-card__label title-card__label--accent' : 'title-card__label'}>
{label && getLocalizedString(`common.${label}`)}
</span>
<div className='title-card__secondary'>{secondary}</div>
</div>
);
}
});

TitleCard.displayName = 'TitleCard';
export default TitleCard;
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,15 @@
font-size: 1.5rem;
letter-spacing: 0.5px;
color: $ui-white;

@include ellipsis-text;
}

.secondaryField {
grid-area: secondary;
font-size: 1.25rem;
letter-spacing: 0.5px;
@include ellipsis-text;
}

.schedule {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import { EditorUpdateFields } from '../EventEditor';

import style from '../EventEditor.module.scss';

interface CountedTextInputProps extends InputProps {
interface EventTextInputProps extends InputProps {
field: EditorUpdateFields;
label: string;
initialValue: string;
submitHandler: (field: EditorUpdateFields, value: string) => void;
}

export default function EventTextInput(props: CountedTextInputProps) {
export default function EventTextInput(props: EventTextInputProps) {
const { field, label, initialValue, submitHandler, maxLength } = props;
const ref = useRef<HTMLInputElement | null>(null);
const submitCallback = useCallback((newValue: string) => submitHandler(field, newValue), [field, submitHandler]);
Expand All @@ -34,7 +34,7 @@ export default function EventTextInput(props: CountedTextInputProps) {
variant='ontime-filled'
data-testid='input-textfield'
value={value}
maxLength={maxLength || 50}
maxLength={maxLength || 100}
onChange={onChange}
onBlur={onBlur}
onKeyDown={onKeyDown}
Expand Down
13 changes: 8 additions & 5 deletions apps/client/src/features/viewers/backstage/Backstage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import { getPropertyValue } from '../common/viewUtils';

import './Backstage.scss';

export const MotionTitleCard = motion(TitleCard);

interface BackstageProps {
customFields: CustomFields;
isMirrored: boolean;
Expand Down Expand Up @@ -124,7 +126,7 @@ export default function Backstage(props: BackstageProps) {
animate='visible'
exit='exit'
>
<TitleCard label='now' title={eventNow.title} secondary={secondaryTextNow} />
<TitleCard title={eventNow.title} secondary={secondaryTextNow} />
<div className='timer-group'>
<div className='aux-timers'>
<div className='aux-timers__label'>{getLocalizedString('common.started_at')}</div>
Expand All @@ -151,16 +153,17 @@ export default function Backstage(props: BackstageProps) {

<AnimatePresence>
{eventNext && (
<motion.div
<MotionTitleCard
className='event next'
key='next'
variants={titleVariants}
initial='hidden'
animate='visible'
exit='exit'
>
<TitleCard label='next' title={eventNext.title} secondary={secondaryTextNext} />
</motion.div>
label='next'
title={eventNext.title}
secondary={secondaryTextNext}
/>
)}
</AnimatePresence>
</div>
Expand Down
19 changes: 6 additions & 13 deletions apps/client/src/features/viewers/countdown/Countdown.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { OntimeEvent, OntimeRundownEntry, Playback, Settings, SupportedEvent, ViewSettings } from 'ontime-types';
import { millisToString, removeLeadingZero } from 'ontime-utils';

import { overrideStylesURL } from '../../../common/api/constants';
import { getCountdownOptions } from '../../../common/components/view-params-editor/constants';
Expand All @@ -12,6 +11,7 @@ import { ViewExtendedTimer } from '../../../common/models/TimeManager.type';
import { formatTime, getDefaultFormat } from '../../../common/utils/time';
import { useTranslation } from '../../../translation/TranslationProvider';
import SuperscriptTime from '../common/superscript-time/SuperscriptTime';
import { getFormattedTimer, isStringBoolean } from '../common/viewUtils';

import { fetchTimerData, TimerMessage } from './countdown.helpers';
import CountdownSelect from './CountdownSelect';
Expand Down Expand Up @@ -84,24 +84,17 @@ export default function Countdown(props: CountdownProps) {
const standby = time.playback !== Playback.Play && time.playback !== Playback.Roll && selectedId === follow?.id;
const finished = time.playback === Playback.Play && (time.current ?? 0) < 0 && time.startedAt;
const isRunningFinished = finished && runningMessage === TimerMessage.running;
const isSelected = runningMessage === TimerMessage.running;
const delayedTimerStyles = delay > 0 ? 'aux-timers__value--delayed' : '';

const clock = formatTime(time.clock);
const startTime = follow === null ? '...' : formatTime(follow.timeStart + delay);
const endTime = follow === null ? '...' : formatTime(follow.timeEnd + delay);

const formatTimer = (): string => {
if (runningMessage === TimerMessage.ended) {
return formatTime(runningTimer, { format12: 'hh:mm a', format24: 'HH:mm' });
}
let formattedTime = millisToString(isSelected ? runningTimer : runningTimer + delay);
if (isSelected || runningMessage === TimerMessage.waiting) {
formattedTime = removeLeadingZero(formattedTime);
}
return formattedTime;
};
const formattedTimer = formatTimer();
const hideSeconds = searchParams.get('hideTimerSeconds');
const formattedTimer = getFormattedTimer(runningTimer, time.timerType, getLocalizedString('common.minutes'), {
removeSeconds: isStringBoolean(hideSeconds),
removeLeadingZero: false,
});

const defaultFormat = getDefaultFormat(settings?.timeFormat);
const timeOption = getCountdownOptions(defaultFormat);
Expand Down
2 changes: 2 additions & 0 deletions apps/client/src/features/viewers/lower-thirds/LowerThird.scss
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
font-family: var(--lowerThird-font-family-override), Lato, Arial, sans-serif;
text-align: var(--lowerThird-text-align-override, left);
white-space: nowrap;
@include ellipsis-text();

&::after {
content: '\200b';
}
Expand Down
20 changes: 12 additions & 8 deletions apps/client/src/features/viewers/public/Public.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { getPropertyValue } from '../common/viewUtils';

import './Public.scss';

export const MotionTitleCard = motion(TitleCard);

interface BackstageProps {
customFields: CustomFields;
isMirrored: boolean;
Expand Down Expand Up @@ -83,31 +85,33 @@ export default function Public(props: BackstageProps) {
<div className='now-container'>
<AnimatePresence>
{publicEventNow && (
<motion.div
<MotionTitleCard
className='event now'
key='now'
variants={titleVariants}
initial='hidden'
animate='visible'
exit='exit'
>
<TitleCard label='now' title={publicEventNow.title} secondary={secondaryTextNow} />
</motion.div>
label='now'
title={publicEventNow.title}
secondary={secondaryTextNow}
/>
)}
</AnimatePresence>

<AnimatePresence>
{publicEventNext && (
<motion.div
<MotionTitleCard
className='event next'
key='next'
variants={titleVariants}
initial='hidden'
animate='visible'
exit='exit'
>
<TitleCard label='next' title={publicEventNext.title} secondary={secondaryTextNext} />
</motion.div>
label='next'
title={publicEventNext.title}
secondary={secondaryTextNext}
/>
)}
</AnimatePresence>
</div>
Expand Down
1 change: 0 additions & 1 deletion apps/client/src/features/viewers/studio/StudioClock.scss
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,6 @@ $orange-active: #f60;
display: flex;
align-items: start;
gap: 0.5em;
white-space: nowrap;

&--now {
color: var(--studio-active-label, $red-active);
Expand Down
2 changes: 1 addition & 1 deletion apps/client/src/features/viewers/studio/StudioClock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default function StudioClock(props: StudioClockProps) {
// TODO: can we prevent the Flash of Unstyled Content on the 7segment fonts?
// deferring rendering seems to affect styling (font and useFitText)
useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
const { fontSize: titleFontSize, ref: titleRef } = useFitText({ maxFontSize: 500 });
const { fontSize: titleFontSize, ref: titleRef } = useFitText({ minFontSize: 150, maxFontSize: 500 });

const activeIndicators = [...Array(12).keys()];
const secondsIndicators = [...Array(60).keys()];
Expand Down
2 changes: 1 addition & 1 deletion apps/client/src/features/viewers/timer/Timer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
padding: min(2vh, 16px) clamp(16px, 10vw, 64px);

display: grid;
grid-template-columns: auto;
grid-template-columns: 100%;
grid-template-rows: auto 1fr auto auto auto;
grid-template-areas:
'clock'
Expand Down
22 changes: 13 additions & 9 deletions apps/client/src/features/viewers/timer/Timer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ const titleVariants = {
},
};

export const MotionTitleCard = motion(TitleCard);

interface TimerProps {
customFields: CustomFields;
eventNext: OntimeEvent | null;
Expand Down Expand Up @@ -211,31 +213,33 @@ export default function Timer(props: TimerProps) {
<>
<AnimatePresence>
{eventNow?.title && (
<motion.div
<MotionTitleCard
className='event now'
key='now'
variants={titleVariants}
initial='hidden'
animate='visible'
exit='exit'
>
<TitleCard label='now' title={mainFieldNow} secondary={secondaryTextNow} />
</motion.div>
label='now'
title={mainFieldNow}
secondary={secondaryTextNow}
/>
)}
</AnimatePresence>

<AnimatePresence>
{eventNext?.title && (
<motion.div
className='event next'
<MotionTitleCard
key='next'
variants={titleVariants}
initial='hidden'
animate='visible'
exit='exit'
>
<TitleCard label='next' title={mainFieldNext} secondary={secondaryTextNext} />
</motion.div>
label='next'
title={mainFieldNext}
secondary={secondaryTextNext}
className='event next'
/>
)}
</AnimatePresence>
</>
Expand Down
8 changes: 7 additions & 1 deletion apps/client/src/theme/_mixins.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@use "ontimeStyles" as *;
@use 'ontimeStyles' as *;

//////////////////////////////////// general app elements

Expand All @@ -15,3 +15,9 @@
color: $ontime-color;
}
}

@mixin ellipsis-text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
1 change: 1 addition & 0 deletions apps/client/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export default defineConfig({
additionalData: `
@use './src/theme/ontimeColours' as *;
@use './src/theme/ontimeStyles' as *;
@use './src/theme/mixins' as *;
`,
},
},
Expand Down

0 comments on commit 6c20cb5

Please sign in to comment.