diff --git a/apps/client/package.json b/apps/client/package.json index 5a6149ceb7..409bde8a87 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -1,6 +1,6 @@ { "name": "ontime-ui", - "version": "2.0.0-beta1", + "version": "2.0.0-beta2", "private": true, "dependencies": { "@chakra-ui/react": "^2.5.1", diff --git a/apps/client/src/appConstants.ts b/apps/client/src/appConstants.ts index 7fc7179fe0..a44531dca8 100644 --- a/apps/client/src/appConstants.ts +++ b/apps/client/src/appConstants.ts @@ -3,7 +3,6 @@ const minimalLocation = 'minimal'; const speakerLocation = 'speaker'; const smLocation = 'sm'; const publicLocation = 'public'; -const pipLocation = 'pip'; const studioLocation = 'studio'; const cuesheetLocation = 'cuesheet'; const countdownLocation = 'countdown'; @@ -17,7 +16,6 @@ export const viewerLocations = [ { link: smLocation, label: 'Backstage screen' }, { link: publicLocation, label: 'Public screen' }, { link: lowerLocation, label: 'Lower thirds' }, - { link: pipLocation, label: 'Picture in Picture' }, { link: studioLocation, label: 'Studio clock' }, { link: countdownLocation, label: 'Countdown' }, { link: cuesheetLocation, label: 'Cuesheet' }, diff --git a/apps/client/src/common/components/input/colour-input/ColourInput.module.scss b/apps/client/src/common/components/input/colour-input/ColourInput.module.scss deleted file mode 100644 index f0f4022518..0000000000 --- a/apps/client/src/common/components/input/colour-input/ColourInput.module.scss +++ /dev/null @@ -1,7 +0,0 @@ -input[type="color"] { - appearance: none; - cursor: pointer; - height: 32px; - width: 32px; - padding: 0; -} diff --git a/apps/client/src/common/components/input/colour-input/ColourInput.tsx b/apps/client/src/common/components/input/colour-input/ColourInput.tsx deleted file mode 100644 index b9040352fa..0000000000 --- a/apps/client/src/common/components/input/colour-input/ColourInput.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { Input } from '@chakra-ui/react'; - -import { EventEditorSubmitActions } from '../../../../features/event-editor/EventEditor'; - -import style from './ColourInput.module.scss'; - -interface ColourInputProps { - value: string; - name: EventEditorSubmitActions; - handleChange: (newValue: EventEditorSubmitActions, name: string) => void; -} - -export default function ColourInput(props: ColourInputProps) { - const { value, name, handleChange } = props; - return ( - handleChange(name, event.target.value)} - /> - ); -} diff --git a/apps/client/src/common/components/input/colour-input/Swatch.tsx b/apps/client/src/common/components/input/colour-input/Swatch.tsx new file mode 100644 index 0000000000..9c192afede --- /dev/null +++ b/apps/client/src/common/components/input/colour-input/Swatch.tsx @@ -0,0 +1,26 @@ +import { IoBan } from '@react-icons/all-files/io5/IoBan'; + +import { cx } from '../../../utils/styleUtils'; + +import style from './SwatchSelect.module.scss'; + +interface SwatchProps { + color: string; + onClick: (color: string) => void; + isSelected?: boolean; +} + +export default function Swatch(props: SwatchProps) { + const { color, isSelected, onClick } = props; + + const classes = cx([style.swatch, isSelected ? style.selected : null]); + + if (!color) { + return ( +
+ +
+ ); + } + return
onClick(color)} />; +} diff --git a/apps/client/src/common/components/input/colour-input/SwatchSelect.module.scss b/apps/client/src/common/components/input/colour-input/SwatchSelect.module.scss new file mode 100644 index 0000000000..11571f22ab --- /dev/null +++ b/apps/client/src/common/components/input/colour-input/SwatchSelect.module.scss @@ -0,0 +1,24 @@ + +.list { + display: flex; + gap: 4px; +} + +.swatch { + cursor: pointer; + aspect-ratio: 1; + width: 2rem; + height: 2rem; + border-radius: 16px; + border: 4px solid #262626; + + &.selected { + border: 2px solid #578AF4; + } +} + +.center { + display: grid; + place-content: center; + color: #578AF4; +} \ No newline at end of file diff --git a/apps/client/src/common/components/input/colour-input/SwatchSelect.tsx b/apps/client/src/common/components/input/colour-input/SwatchSelect.tsx new file mode 100644 index 0000000000..07682b11c5 --- /dev/null +++ b/apps/client/src/common/components/input/colour-input/SwatchSelect.tsx @@ -0,0 +1,50 @@ +import { useCallback } from 'react'; + +import { EventEditorSubmitActions } from '../../../../features/event-editor/EventEditor'; + +import Swatch from './Swatch'; + +import style from './SwatchSelect.module.scss'; + +interface ColourInputProps { + value: string; + name: EventEditorSubmitActions; + handleChange: (newValue: EventEditorSubmitActions, name: string) => void; +} + +const colours = [ + '', + '#FFCC78', // $orange-400 + '#FFAB33', // $orange-600 + '#77C785', // $green-400 + '#339E4E', // $green-600 + '#779BE7', // $blue-400 + '#3E75E8', // $blue-600 + '#FF7878', // $red-400 + '#ED3333', // $red-600 + '#A790F5', // $violet-400 + '#8064E1', // $violet-600 + '#9d9d9d', // $gray-500 + '#ececec', // $gray-100 +]; + +export default function SwatchSelect(props: ColourInputProps) { + const { value, name, handleChange } = props; + + const setColour = useCallback( + (newValue: string) => { + if (newValue !== value) { + handleChange(name, newValue); + } + }, + [handleChange, name, value], + ); + + return ( +
+ {colours.map((colour) => ( + + ))} +
+ ); +} diff --git a/apps/client/src/common/components/input/delay-input/DelayInput.tsx b/apps/client/src/common/components/input/delay-input/DelayInput.tsx index 6b987ab4b8..c53ef0994c 100644 --- a/apps/client/src/common/components/input/delay-input/DelayInput.tsx +++ b/apps/client/src/common/components/input/delay-input/DelayInput.tsx @@ -11,6 +11,8 @@ const inputStyleProps = { size: 'sm', color: '#E69056', variant: 'ontime-filled', + fontSize: '15px', + letterSpacing: '0.3px', }; interface DelayInputProps { @@ -24,7 +26,9 @@ export default function DelayInput(props: DelayInputProps) { const inputRef = useRef(null); useEffect(() => { - if (value == null) return; + if (!value) { + return; + } setValue(value); }, [value]); @@ -36,7 +40,6 @@ export default function DelayInput(props: DelayInputProps) { (newValue?: string) => { if (newValue === '') setValue(0); const delayValue = clamp(Number(newValue), -60, 60); - if (delayValue === value) return; setValue(delayValue); @@ -49,15 +52,18 @@ export default function DelayInput(props: DelayInputProps) { * @description Handles common keys for submit and cancel * @param {KeyboardEvent} event */ - const onKeyDownHandler = useCallback((key: string) => { - if (key === 'Enter') { - inputRef.current?.blur(); - validate(inputRef.current?.value); - } else if (key === 'Escape') { - inputRef.current?.blur(); - setValue(value); - } - }, [validate, value]); + const onKeyDownHandler = useCallback( + (key: string) => { + if (key === 'Enter') { + inputRef.current?.blur(); + validate(inputRef.current?.value); + } else if (key === 'Escape') { + inputRef.current?.blur(); + setValue(value); + } + }, + [validate, value], + ); const labelText = `${Math.abs(value) !== 1 ? 'minutes' : 'minute'} ${ value !== undefined && value >= 0 ? 'delayed' : 'ahead' diff --git a/apps/client/src/common/components/input/text-input/TextInput.tsx b/apps/client/src/common/components/input/text-input/TextInput.tsx index 08ee1d13f5..bfc429ad3f 100644 --- a/apps/client/src/common/components/input/text-input/TextInput.tsx +++ b/apps/client/src/common/components/input/text-input/TextInput.tsx @@ -15,15 +15,19 @@ interface BaseProps { submitHandler: (field: EventEditorSubmitActions, newValue: string) => void; } -interface TextAreaProps { +interface TextInputProps extends BaseProps { + isTextArea?: false; +} + +interface TextAreaProps extends BaseProps { isTextArea: true; resize?: 'horizontal' | 'vertical' | 'none'; } -type TextInputProps = BaseProps & TextAreaProps; +type InputProps = TextInputProps | TextAreaProps; -export default function TextInput(props: TextInputProps) { - const { isTextArea, isFullHeight, size = 'sm', field, initialText = '', submitHandler, resize = 'none' } = props; +export default function TextInput(props: InputProps) { + const { isTextArea, isFullHeight, size = 'sm', field, initialText = '', submitHandler } = props; const inputRef = useRef(null); const submitCallback = useCallback((newValue: string) => submitHandler(field, newValue), [field, submitHandler]); @@ -31,6 +35,11 @@ export default function TextInput(props: TextInputProps) { const textInputProps = useReactiveTextInput(initialText, submitCallback, { submitOnEnter: true }); const textAreaProps = useReactiveTextInput(initialText, submitCallback); + let resize = 'none'; + if (isTextArea) { + resize = (props as TextAreaProps)?.resize ?? 'none'; + } + return isTextArea ? (