From 53683f9b7beb158aa3aeccbcf489f7ac4e0154d4 Mon Sep 17 00:00:00 2001 From: Valentina Date: Tue, 28 May 2024 16:06:36 +0200 Subject: [PATCH 1/4] fix #1335: theme editor font sizes inputs --- .../src/ThemeEditorFontSizeSlider.tsx | 31 +++++++ .../src/ThemeEditorFontSizesItem.tsx | 80 ++++++++----------- 2 files changed, 65 insertions(+), 46 deletions(-) create mode 100644 packages/chakra-ui-font-sizes/src/ThemeEditorFontSizeSlider.tsx diff --git a/packages/chakra-ui-font-sizes/src/ThemeEditorFontSizeSlider.tsx b/packages/chakra-ui-font-sizes/src/ThemeEditorFontSizeSlider.tsx new file mode 100644 index 0000000..f0d8442 --- /dev/null +++ b/packages/chakra-ui-font-sizes/src/ThemeEditorFontSizeSlider.tsx @@ -0,0 +1,31 @@ +import { Slider, SliderTrack, SliderFilledTrack, SliderThumb } from '@chakra-ui/react' +import React, { FC, useCallback } from 'react' + +export const ThemeEditorFontSizeSlider: FC<{ + setCurrentValue: (value: React.SetStateAction) => void + cssValue: any +}> = ({ setCurrentValue, cssValue }) => { + const handleSliderChange = useCallback( + (newValue: number) => { + setCurrentValue(`${newValue}${cssValue?.unit}`) + }, + [cssValue] + ) + + return ( + + + + + + + ) +} diff --git a/packages/chakra-ui-font-sizes/src/ThemeEditorFontSizesItem.tsx b/packages/chakra-ui-font-sizes/src/ThemeEditorFontSizesItem.tsx index 31dd07b..132eb67 100644 --- a/packages/chakra-ui-font-sizes/src/ThemeEditorFontSizesItem.tsx +++ b/packages/chakra-ui-font-sizes/src/ThemeEditorFontSizesItem.tsx @@ -1,6 +1,5 @@ -import React, { FC, useCallback, useMemo, useState, useEffect } from 'react' +import React, { FC, useCallback, useMemo, useState } from 'react' import { - Box, Flex, Tag, Text, @@ -13,6 +12,7 @@ import { } from '@chakra-ui/react' import { useDebouncyEffect } from 'use-debouncy' import { ElementsHighlighter } from '@hypertheme-editor/chakra-ui-core' +import { ThemeEditorFontSizeSlider } from './ThemeEditorFontSizeSlider' export type ThemeEditorFontSizesItemProps = { size: string @@ -27,46 +27,46 @@ const ThemeEditorFontSizesItem: FC = (props) => { const [currentValue, setCurrentValue] = useState(value) const cssValue = useMemo(() => { - return window && currentValue - ? (window as any).CSSStyleValue.parse('font-size', currentValue) - : undefined + if (!window) { + return (window as any).CSSStyleValue.parse('font-size', '0rem') + } else if (!currentValue?.length) { + return (window as any).CSSStyleValue.parse('font-size', '0rem') + } else { + return (window as any).CSSStyleValue.parse('font-size', currentValue) + } }, [currentValue]) - const handleSliderChange = useCallback( - (newValue: number) => { - setCurrentValue(`${newValue}${cssValue.unit}`) - }, - [cssValue.unit] - ) - - const handleInputChange = useCallback>( + const handleInputChange = useCallback( (event) => { - setCurrentValue(`${event.target.value}${cssValue.unit}`) + setCurrentValue(`${!event?.target?.value ? 0 : event.target.value}${cssValue?.unit}`) }, - [cssValue.unit] + [cssValue?.unit, setCurrentValue] ) const handleUnitChange = useCallback>( (event) => { - if (cssValue.unit === 'px' && (event.target.value === 'em' || event.target.value === 'rem')) { - setCurrentValue(`${cssValue.value / 16}${event.target.value}`) - } else if ( - (cssValue.unit === 'em' || cssValue.unit === 'rem') && - event.target.value === 'px' - ) { - setCurrentValue(`${(cssValue.value * 16).toFixed(0)}${event.target.value}`) + if (!cssValue?.unit) { + setCurrentValue(`${cssValue?.value || 0}rem`) } else { - setCurrentValue(`${cssValue.value}${event.target.value}`) + if ( + cssValue?.unit === 'px' && + (event.target.value === 'em' || event.target.value === 'rem') + ) { + setCurrentValue(`${cssValue?.value / 16}${event.target.value}`) + } else if ( + (cssValue?.unit === 'em' || cssValue?.unit === 'rem') && + event.target.value === 'px' + ) { + setCurrentValue(`${(cssValue?.value * 16).toFixed(0)}${event.target.value}`) + } else { + setCurrentValue(`${cssValue?.value}${event.target.value}`) + } } }, - [cssValue.unit, cssValue.value] + [cssValue?.unit, cssValue?.value] ) - useDebouncyEffect(() => onChange({ size, value: currentValue }), 500, [currentValue]) - - useEffect(() => { - setCurrentValue(value) - }, [value]) + useDebouncyEffect(() => onChange({ size, value: cssValue?.value }), 500, [cssValue]) return ( @@ -74,20 +74,7 @@ const ThemeEditorFontSizesItem: FC = (props) => { {size} - - - - - - + = (props) => { fontSize="0.875rem" w="70px" type="number" - value={cssValue.value} - onChange={handleInputChange} + value={cssValue?.value} + onChange={(e) => handleInputChange(e)} + onWheel={(e) => e.currentTarget.blur()} /> handleInputChange(e)} - onWheel={(e) => e.currentTarget.blur()} - /> - - + + + + { + const context = useContext(InputGroupContext) + const { currentFontValue, setCurrentFontValue } = context + + const fontSizeUnit = useMemo(() => { + const charactersList = Array.from(currentFontValue.matchAll(/[a-z]/g)) + const charactersSubstring = charactersList.toString().replaceAll(',', '') + + return charactersSubstring + }, [currentFontValue]) + + const fontSizeValue = useMemo(() => { + const numbersList = Array.from(currentFontValue.matchAll(/[^a-z]/g)) + let numbersSubstring = '' + numbersList.forEach((item) => { + numbersSubstring += item + }) + + const int = Number(numbersSubstring) + + return int + }, [currentFontValue]) + + const [sliderValue, setSliderValue] = useState(fontSizeValue) + + useEffect(() => { + let newValue = '0rem' + + if (fontSizeUnit === 'px') { + newValue = `${sliderValue}${fontSizeUnit}` + } else { + const digit = (sliderValue * 0.1).toFixed(2) + newValue = `${digit}${fontSizeUnit}` + } + + setCurrentFontValue(newValue) + }, [sliderValue, fontSizeUnit]) + + return ( + setSliderValue(value)} + > + + + + + + ) +} diff --git a/packages/chakra-ui-font-sizes/src/base-components/InputFields.tsx b/packages/chakra-ui-font-sizes/src/base-components/InputFields.tsx new file mode 100644 index 0000000..3e5956b --- /dev/null +++ b/packages/chakra-ui-font-sizes/src/base-components/InputFields.tsx @@ -0,0 +1,89 @@ +import { Flex, Input, Select } from '@chakra-ui/react' +import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react' +import { InputGroupContext } from '../ThemeEditorFontSizesItem' + +export const InputFields = () => { + const context = useContext(InputGroupContext) + const { currentFontValue, setCurrentFontValue } = context + + const fontSizeUnit = useMemo(() => { + const charactersList = Array.from(currentFontValue.matchAll(/[a-z]/g)) + const charactersSubstring = charactersList.toString().replaceAll(',', '') + + return charactersSubstring + }, [currentFontValue]) + + const fontSizeValue = useMemo(() => { + const numbersList = Array.from(currentFontValue.matchAll(/[^a-z]/g)) + let numbersSubstring = '' + numbersList.forEach((item) => { + numbersSubstring += item + }) + + const int = Number(numbersSubstring) + + return int + }, [currentFontValue]) + + const [inputValue, setInputValue] = useState(fontSizeValue) + + const handleUnitChange = useCallback>( + (event) => { + let newValue = '0rem' + if (!fontSizeUnit?.length) { + newValue = `${fontSizeValue || 0}rem` + } else { + if ( + fontSizeUnit === 'px' && + (event.target.value === 'em' || event.target.value === 'rem') + ) { + newValue = `${fontSizeValue / 16}${event.target.value}` + } else { + newValue = `${fontSizeValue}${event.target.value}` + } + } + setCurrentFontValue(newValue) + }, + [currentFontValue] + ) + + useEffect(() => { + let newValue = '0rem' + if (fontSizeUnit === 'px') { + newValue = `${!inputValue ? 0 : inputValue}${fontSizeUnit}` + } else { + const valueAsEm = Number(inputValue) / 16 + newValue = `${valueAsEm}${fontSizeUnit}` + } + setCurrentFontValue(newValue) + }, [inputValue, fontSizeUnit]) + + return ( + + e.currentTarget.blur()} + value={inputValue} + onChange={(e) => setInputValue(Number(e.target.value))} + /> + + + ) +} From 4180b0ebd5faddb3c5cc9e6bece83386919c6beb Mon Sep 17 00:00:00 2001 From: Valentina Date: Sun, 30 Jun 2024 20:09:31 +0200 Subject: [PATCH 4/4] fix #1335: input loses focus when composing --- .../theme-editor/ThemeDownloadButton.tsx | 3 -- .../theme-editor/ThemeEditorDrawerFooter.tsx | 1 + .../src/base-components/FontSizeSlider.tsx | 31 +++++--------- .../src/base-components/InputFields.tsx | 41 +++++-------------- 4 files changed, 23 insertions(+), 53 deletions(-) diff --git a/packages/chakra-ui-core/src/components/theme-editor/ThemeDownloadButton.tsx b/packages/chakra-ui-core/src/components/theme-editor/ThemeDownloadButton.tsx index 215719a..8f068fc 100644 --- a/packages/chakra-ui-core/src/components/theme-editor/ThemeDownloadButton.tsx +++ b/packages/chakra-ui-core/src/components/theme-editor/ThemeDownloadButton.tsx @@ -113,9 +113,6 @@ export const ThemeDownloadButton: FC = ({ w="fit-content" px={10} onClick={handleDownload(selectedLanguage)} - position="absolute" - bottom={2} - zIndex={10} {...rest} > Export diff --git a/packages/chakra-ui-core/src/components/theme-editor/ThemeEditorDrawerFooter.tsx b/packages/chakra-ui-core/src/components/theme-editor/ThemeEditorDrawerFooter.tsx index cdcbf4b..a48fc33 100644 --- a/packages/chakra-ui-core/src/components/theme-editor/ThemeEditorDrawerFooter.tsx +++ b/packages/chakra-ui-core/src/components/theme-editor/ThemeEditorDrawerFooter.tsx @@ -20,6 +20,7 @@ export const ThemeEditorDrawerFooter: FC = ({ { @@ -20,39 +20,30 @@ export const FontSizeSlider = () => { numbersSubstring += item }) - const int = Number(numbersSubstring) + const int = Number.isNaN(Number(numbersSubstring)) ? 0 : Number(numbersSubstring) return int }, [currentFontValue]) - const [sliderValue, setSliderValue] = useState(fontSizeValue) - - useEffect(() => { - let newValue = '0rem' - - if (fontSizeUnit === 'px') { - newValue = `${sliderValue}${fontSizeUnit}` - } else { - const digit = (sliderValue * 0.1).toFixed(2) - newValue = `${digit}${fontSizeUnit}` - } - - setCurrentFontValue(newValue) - }, [sliderValue, fontSizeUnit]) + const [isMouseOver, setIsMouseOver] = useState(false) return ( setSliderValue(value)} + focusThumbOnChange={isMouseOver} + value={fontSizeValue} + onChange={(value) => setCurrentFontValue(`${value}${fontSizeUnit}`)} + onMouseOver={() => setIsMouseOver(true)} + onMouseLeave={() => setIsMouseOver(false)} > - + ) } diff --git a/packages/chakra-ui-font-sizes/src/base-components/InputFields.tsx b/packages/chakra-ui-font-sizes/src/base-components/InputFields.tsx index 3e5956b..c8b0ce9 100644 --- a/packages/chakra-ui-font-sizes/src/base-components/InputFields.tsx +++ b/packages/chakra-ui-font-sizes/src/base-components/InputFields.tsx @@ -1,5 +1,5 @@ import { Flex, Input, Select } from '@chakra-ui/react' -import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react' +import React, { useCallback, useContext, useMemo } from 'react' import { InputGroupContext } from '../ThemeEditorFontSizesItem' export const InputFields = () => { @@ -20,44 +20,23 @@ export const InputFields = () => { numbersSubstring += item }) - const int = Number(numbersSubstring) - - return int + return numbersSubstring }, [currentFontValue]) - const [inputValue, setInputValue] = useState(fontSizeValue) - const handleUnitChange = useCallback>( (event) => { let newValue = '0rem' - if (!fontSizeUnit?.length) { - newValue = `${fontSizeValue || 0}rem` + if (fontSizeUnit === 'px' && (event.target.value === 'em' || event.target.value === 'rem')) { + newValue = `${Number(fontSizeValue) / 16}${event.target.value}` } else { - if ( - fontSizeUnit === 'px' && - (event.target.value === 'em' || event.target.value === 'rem') - ) { - newValue = `${fontSizeValue / 16}${event.target.value}` - } else { - newValue = `${fontSizeValue}${event.target.value}` - } + newValue = `${fontSizeValue}${event.target.value}` } + setCurrentFontValue(newValue) }, [currentFontValue] ) - useEffect(() => { - let newValue = '0rem' - if (fontSizeUnit === 'px') { - newValue = `${!inputValue ? 0 : inputValue}${fontSizeUnit}` - } else { - const valueAsEm = Number(inputValue) / 16 - newValue = `${valueAsEm}${fontSizeUnit}` - } - setCurrentFontValue(newValue) - }, [inputValue, fontSizeUnit]) - return ( { w="70px" borderRadius="6px" size="sm" + value={fontSizeValue} + onChange={(e) => + setCurrentFontValue(`${!e.target.value ? '' : e.target.value}${fontSizeUnit}`) + } onWheel={(e) => e.currentTarget.blur()} - value={inputValue} - onChange={(e) => setInputValue(Number(e.target.value))} />