From 5d6da57cc5b7e24959c4ff8e9732f2e3b6dd3269 Mon Sep 17 00:00:00 2001 From: nina992 Date: Wed, 23 Aug 2023 09:29:04 +0300 Subject: [PATCH 01/13] feat(web): add spacing input field --- .../properties/SpacingInput/index.stories.tsx | 28 +++++++ .../properties/SpacingInput/index.tsx | 77 +++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 web/src/beta/components/properties/SpacingInput/index.stories.tsx create mode 100644 web/src/beta/components/properties/SpacingInput/index.tsx diff --git a/web/src/beta/components/properties/SpacingInput/index.stories.tsx b/web/src/beta/components/properties/SpacingInput/index.stories.tsx new file mode 100644 index 0000000000..36841c4e80 --- /dev/null +++ b/web/src/beta/components/properties/SpacingInput/index.stories.tsx @@ -0,0 +1,28 @@ +import { Meta, Story } from "@storybook/react"; + +import SpacingInput from "./index"; + +export default { + title: "Components/SpacingInput", + component: SpacingInput, +} as Meta; + +const Template: Story = args => ; + +export const Default = Template.bind({}); +Default.args = { + name: "Padding", + description: "Adjust the padding values", +}; + +export const WithValues = Template.bind({}); +WithValues.args = { + name: "Padding", + description: "Adjust the padding values", + value: { + top: "10px", + left: "20px", + right: "30px", + bottom: "40px", + }, +}; diff --git a/web/src/beta/components/properties/SpacingInput/index.tsx b/web/src/beta/components/properties/SpacingInput/index.tsx new file mode 100644 index 0000000000..885e38b16b --- /dev/null +++ b/web/src/beta/components/properties/SpacingInput/index.tsx @@ -0,0 +1,77 @@ +import { useState } from "react"; + +import { styled } from "@reearth/services/theme"; + +import Property from ".."; + +type Props = { + name?: string; + description?: string; + value?: { top: string; left: string; right: string; bottom: string }; + onChange?: (values: { top: string; left: string; right: string; bottom: string }) => void; +}; + +const SpacingInput: React.FC = ({ name, description, value, onChange }) => { + const [spacingValues, setSpacingValues] = useState( + value || { top: "", left: "", right: "", bottom: "" }, + ); + + const handleInputChange = (position: string, newValue: string) => { + const updatedValues = { ...spacingValues, [position]: newValue }; + setSpacingValues(updatedValues); + onChange?.(updatedValues); + }; + + return ( + + + + {["top", "left", "right", "bottom"].map(position => ( + handleInputChange(position, e.target.value)} + placeholder={position} + position={position} + /> + ))} + + + + ); +}; + +export default SpacingInput; + +const StyledContainer = styled.div` + display: flex; + align-items: center; +`; + +const StyledRectangle = styled.div` + display: flex; + position: relative; + width: 200px; + height: 120px; + border: 1px dotted ${({ theme }) => theme.outline.weak}; + box-sizing: border-box; +`; + +const SpacingInputField = styled.input<{ position: string }>` + outline: none; + background: ${({ theme }) => theme.bg[1]}; + color: ${({ theme }) => theme.content.main}; + border: 1px solid ${({ theme }) => theme.outline.weak}; + border-radius: 4px; + padding: 4px 8px; + transition: all 0.3s; + position: absolute; + ${({ position }) => (position === "top" || position === "bottom" ? "left" : "right")}: 50%; + transform: ${({ position }) => + position === "top" || position === "bottom" ? "translateX(-50%)" : "translateX(50%)"}; + text-align: center; + + :focus { + border-color: ${({ theme }) => theme.outline.main}; + } +`; From c167ad9fc57690596bf7bb51506d4fd929d59657 Mon Sep 17 00:00:00 2001 From: nina992 Date: Wed, 23 Aug 2023 20:58:24 +0300 Subject: [PATCH 02/13] fix-styles --- .../fields/SpacingInput/index.stories.tsx | 9 +- .../components/fields/SpacingInput/index.tsx | 90 +++++++++++-------- 2 files changed, 59 insertions(+), 40 deletions(-) diff --git a/web/src/beta/components/fields/SpacingInput/index.stories.tsx b/web/src/beta/components/fields/SpacingInput/index.stories.tsx index 36841c4e80..a5ae5dc7e4 100644 --- a/web/src/beta/components/fields/SpacingInput/index.stories.tsx +++ b/web/src/beta/components/fields/SpacingInput/index.stories.tsx @@ -3,7 +3,6 @@ import { Meta, Story } from "@storybook/react"; import SpacingInput from "./index"; export default { - title: "Components/SpacingInput", component: SpacingInput, } as Meta; @@ -20,9 +19,9 @@ WithValues.args = { name: "Padding", description: "Adjust the padding values", value: { - top: "10px", - left: "20px", - right: "30px", - bottom: "40px", + top: "10", + left: "20", + right: "30", + bottom: "40", }, }; diff --git a/web/src/beta/components/fields/SpacingInput/index.tsx b/web/src/beta/components/fields/SpacingInput/index.tsx index 885e38b16b..364b525613 100644 --- a/web/src/beta/components/fields/SpacingInput/index.tsx +++ b/web/src/beta/components/fields/SpacingInput/index.tsx @@ -1,77 +1,97 @@ -import { useState } from "react"; +import React, { useState } from "react"; import { styled } from "@reearth/services/theme"; import Property from ".."; +type SpacingValues = { + top: string; + left: string; + right: string; + bottom: string; +}; + type Props = { name?: string; description?: string; - value?: { top: string; left: string; right: string; bottom: string }; - onChange?: (values: { top: string; left: string; right: string; bottom: string }) => void; + value?: SpacingValues; + onChange?: (values: SpacingValues) => void; }; const SpacingInput: React.FC = ({ name, description, value, onChange }) => { - const [spacingValues, setSpacingValues] = useState( + const [spacingValues, setSpacingValues] = useState( value || { top: "", left: "", right: "", bottom: "" }, ); - const handleInputChange = (position: string, newValue: string) => { + const handleInputChange = (position: keyof SpacingValues, newValue: string) => { const updatedValues = { ...spacingValues, [position]: newValue }; setSpacingValues(updatedValues); onChange?.(updatedValues); }; + function getSpacingPosition(spacingValue: SpacingValues, position: keyof SpacingValues): string { + return spacingValue[position]; + } + return ( - - - {["top", "left", "right", "bottom"].map(position => ( + + {["top", "left", "right", "bottom"].map(position => ( + handleInputChange(position, e.target.value)} - placeholder={position} - position={position} + value={getSpacingPosition(spacingValues, position as keyof SpacingValues)} + onChange={e => handleInputChange(position as keyof SpacingValues, e.target.value)} /> - ))} - - + px + + ))} + ); }; export default SpacingInput; -const StyledContainer = styled.div` - display: flex; - align-items: center; -`; - const StyledRectangle = styled.div` display: flex; position: relative; - width: 200px; - height: 120px; - border: 1px dotted ${({ theme }) => theme.outline.weak}; + width: 289px; + height: 84px; + background: ${({ theme }) => theme.bg[1]}; + border: 1px dashed ${({ theme }) => theme.outline.weak}; box-sizing: border-box; `; -const SpacingInputField = styled.input<{ position: string }>` - outline: none; - background: ${({ theme }) => theme.bg[1]}; - color: ${({ theme }) => theme.content.main}; +const SpacingField = styled.div<{ position: string }>` border: 1px solid ${({ theme }) => theme.outline.weak}; border-radius: 4px; padding: 4px 8px; - transition: all 0.3s; + display: flex; + align-items: center; + gap: 10px; position: absolute; - ${({ position }) => (position === "top" || position === "bottom" ? "left" : "right")}: 50%; - transform: ${({ position }) => - position === "top" || position === "bottom" ? "translateX(-50%)" : "translateX(50%)"}; + ${({ position }) => + position === "top" + ? "top: 0; left: 50%; transform: translateX(-50%);" + : position === "left" + ? "left: 0; top: 50%; transform: translateY(-50%);" + : position === "right" + ? "right: 0; top: 50%; transform: translateY(-50%);" + : "bottom: 0; left: 50%; transform: translateX(-50%);"}; +`; + +const SpacingInputField = styled.input` + background: transparent; + color: ${({ theme }) => theme.content.main}; + width: 14px; + height: 20px; text-align: center; + border: none; + font-size: 12px; +`; - :focus { - border-color: ${({ theme }) => theme.outline.main}; - } +const ValueText = styled.span` + font-size: 12px; + color: ${({ theme }) => theme.content.weak}; + line-height: 20px; `; From 4c64f10e7da48bc4721c6c03db9cfd264ea87577 Mon Sep 17 00:00:00 2001 From: nina992 Date: Wed, 23 Aug 2023 21:00:24 +0300 Subject: [PATCH 03/13] fix-type --- .../beta/components/fields/SpacingInput/index.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/web/src/beta/components/fields/SpacingInput/index.tsx b/web/src/beta/components/fields/SpacingInput/index.tsx index 364b525613..e2822873f4 100644 --- a/web/src/beta/components/fields/SpacingInput/index.tsx +++ b/web/src/beta/components/fields/SpacingInput/index.tsx @@ -5,10 +5,10 @@ import { styled } from "@reearth/services/theme"; import Property from ".."; type SpacingValues = { - top: string; - left: string; - right: string; - bottom: string; + top: number; + left: number; + right: number; + bottom: number; }; type Props = { @@ -20,7 +20,7 @@ type Props = { const SpacingInput: React.FC = ({ name, description, value, onChange }) => { const [spacingValues, setSpacingValues] = useState( - value || { top: "", left: "", right: "", bottom: "" }, + value || { top: 0, left: 0, right: 0, bottom: 0 }, ); const handleInputChange = (position: keyof SpacingValues, newValue: string) => { @@ -29,7 +29,7 @@ const SpacingInput: React.FC = ({ name, description, value, onChange }) = onChange?.(updatedValues); }; - function getSpacingPosition(spacingValue: SpacingValues, position: keyof SpacingValues): string { + function getSpacingPosition(spacingValue: SpacingValues, position: keyof SpacingValues): number { return spacingValue[position]; } From 4d304404ee8e723030c526c0ec9ca58f3e1f6203 Mon Sep 17 00:00:00 2001 From: nina992 Date: Fri, 25 Aug 2023 17:09:01 +0300 Subject: [PATCH 04/13] number-input --- .../fields/NumberInput/index.stories.tsx | 70 ++++++++ .../components/fields/NumberInput/index.tsx | 161 ++++++++++++++++++ .../components/fields/SpacingInput/index.tsx | 52 ++---- web/src/beta/components/fields/index.tsx | 2 +- web/src/services/i18n/translations/en.yml | 2 + web/src/services/i18n/translations/ja.yml | 2 + 6 files changed, 253 insertions(+), 36 deletions(-) create mode 100644 web/src/beta/components/fields/NumberInput/index.stories.tsx create mode 100644 web/src/beta/components/fields/NumberInput/index.tsx diff --git a/web/src/beta/components/fields/NumberInput/index.stories.tsx b/web/src/beta/components/fields/NumberInput/index.stories.tsx new file mode 100644 index 0000000000..36769d59df --- /dev/null +++ b/web/src/beta/components/fields/NumberInput/index.stories.tsx @@ -0,0 +1,70 @@ +import { Meta, StoryObj } from "@storybook/react"; + +import NumberInput, { Props } from "./index"; + +const meta: Meta = { + component: NumberInput, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + value: 42, + inputDescription: "Value", + suffix: "px", + }, +}; + +export const Disabled: Story = { + args: { + value: 15, + inputDescription: "Disabled", + suffix: "px", + disabled: true, + }, +}; + +export const Range: Story = { + args: { + value: 50, + inputDescription: "Range", + suffix: "px", + min: 4, + max: 100, + }, +}; + +export const NoValue: Story = { + args: { + inputDescription: "No Value", + suffix: "px", + }, +}; + +export const WithMinValue: Story = { + args: { + value: 5, + inputDescription: "With Min Value", + suffix: "px", + min: 0, + }, +}; + +export const WithMaxValue: Story = { + args: { + value: 95, + inputDescription: "With Max Value", + suffix: "px", + max: 100, + }, +}; + +export const Editable: Story = { + args: { + value: 25, + inputDescription: "Editable", + suffix: "px", + }, +}; diff --git a/web/src/beta/components/fields/NumberInput/index.tsx b/web/src/beta/components/fields/NumberInput/index.tsx new file mode 100644 index 0000000000..0ff6ad93bc --- /dev/null +++ b/web/src/beta/components/fields/NumberInput/index.tsx @@ -0,0 +1,161 @@ +import React, { useState, useCallback, useRef, useEffect } from "react"; + +import Text from "@reearth/beta/components/Text"; +import { useT } from "@reearth/services/i18n"; +import { useNotification } from "@reearth/services/state"; +import { styled, useTheme } from "@reearth/services/theme"; +import { metricsSizes } from "@reearth/services/theme/reearthTheme/common/metrics"; + +export type Props = { + className?: string; + suffix?: string; + min?: number; + max?: number; + disabled?: boolean; + inputDescription?: string; + value?: number; + onChange?: (value?: number | undefined) => void; +}; + +const NumberInput: React.FC = ({ + className, + value, + inputDescription, + suffix, + onChange, + min, + max, + disabled = false, +}) => { + const [innerValue, setInnerValue] = useState(value); + const [, setNotification] = useNotification(); + + const isEditing = useRef(false); + const t = useT(); + + const theme = useTheme(); + + useEffect(() => { + setInnerValue(value); + }, [value]); + + const callChange = useCallback( + (newValue: number | undefined) => { + if (!onChange || !isEditing.current) { + return; + } + + if (newValue === undefined) { + setInnerValue(undefined); + onChange(undefined); + } else if (typeof max === "number" && isFinite(max) && newValue > max) { + setNotification({ type: "warning", text: t("You have passed the maximum value.") }); + setInnerValue(undefined); + onChange(undefined); + } else if (typeof min === "number" && isFinite(min) && newValue < min) { + setNotification({ type: "warning", text: t("You have passed the minimum value.") }); + setInnerValue(undefined); + onChange(undefined); + } else if (!isNaN(newValue)) { + setInnerValue(newValue); + onChange(newValue); + } + }, + [onChange, max, min, setNotification, t], + ); + + const handleChange = useCallback((e: React.ChangeEvent) => { + setInnerValue(parseFloat(e.currentTarget.value)); + }, []); + + const handleKeyPress = useCallback( + (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + callChange(parseFloat(e.currentTarget.value)); + } + }, + [callChange], + ); + + const handleFocus = useCallback(() => { + isEditing.current = true; + }, []); + + const handleBlur = useCallback( + (e: React.SyntheticEvent) => { + callChange(parseFloat(e.currentTarget.value)); + isEditing.current = false; + }, + [callChange], + ); + + return ( + + + + {suffix && ( + + {suffix} + + )} + + {inputDescription && ( + + {inputDescription} + + )} + + ); +}; + +const Wrapper = styled.div` + width: 100%; + text-align: center; +`; + +type FormProps = { inactive: boolean }; + +const FormWrapper = styled.div` + display: flex; + align-items: center; + background: ${({ theme }) => theme.bg[1]}; + border: 1px solid ${({ theme }) => theme.outline.weak}; + border-radius: 4px; + padding: ${metricsSizes.xs}px ${metricsSizes.s}px; + gap: 12px; + width: 100%; + color: ${({ inactive, theme }) => (inactive ? theme.content.weak : theme.content.main)}; + &:focus-within { + border-color: ${({ theme }) => theme.select.main}; + } + box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.25) inset; +`; + +const StyledInput = styled.input` + display: block; + border: none; + background: ${({ theme }) => theme.bg[1]}; + outline: none; + color: inherit; + width: 100%; + &::-webkit-inner-spin-button, + &::-webkit-outer-spin-button { + -webkit-appearance: none; + } + &[type="number"] { + -moz-appearance: textfield; + } +`; + +export default NumberInput; diff --git a/web/src/beta/components/fields/SpacingInput/index.tsx b/web/src/beta/components/fields/SpacingInput/index.tsx index e2822873f4..41080372a9 100644 --- a/web/src/beta/components/fields/SpacingInput/index.tsx +++ b/web/src/beta/components/fields/SpacingInput/index.tsx @@ -3,6 +3,7 @@ import React, { useState } from "react"; import { styled } from "@reearth/services/theme"; import Property from ".."; +import NumberInput from "../NumberInput"; type SpacingValues = { top: number; @@ -23,27 +24,26 @@ const SpacingInput: React.FC = ({ name, description, value, onChange }) = value || { top: 0, left: 0, right: 0, bottom: 0 }, ); - const handleInputChange = (position: keyof SpacingValues, newValue: string) => { + const handleInputChange = ( + position: keyof SpacingValues, + newValue: string | number | undefined, + ) => { const updatedValues = { ...spacingValues, [position]: newValue }; setSpacingValues(updatedValues); onChange?.(updatedValues); }; - function getSpacingPosition(spacingValue: SpacingValues, position: keyof SpacingValues): number { - return spacingValue[position]; - } - return ( {["top", "left", "right", "bottom"].map(position => ( - - handleInputChange(position as keyof SpacingValues, e.target.value)} - /> - px - + handleInputChange(position as keyof SpacingValues, newValue)} + /> ))} @@ -57,18 +57,12 @@ const StyledRectangle = styled.div` position: relative; width: 289px; height: 84px; - background: ${({ theme }) => theme.bg[1]}; border: 1px dashed ${({ theme }) => theme.outline.weak}; box-sizing: border-box; `; -const SpacingField = styled.div<{ position: string }>` - border: 1px solid ${({ theme }) => theme.outline.weak}; - border-radius: 4px; - padding: 4px 8px; - display: flex; - align-items: center; - gap: 10px; +const SpacingField = styled(NumberInput)<{ position: string }>` + width: 40px; position: absolute; ${({ position }) => position === "top" @@ -80,18 +74,6 @@ const SpacingField = styled.div<{ position: string }>` : "bottom: 0; left: 50%; transform: translateX(-50%);"}; `; -const SpacingInputField = styled.input` - background: transparent; - color: ${({ theme }) => theme.content.main}; - width: 14px; - height: 20px; - text-align: center; - border: none; - font-size: 12px; -`; - -const ValueText = styled.span` - font-size: 12px; - color: ${({ theme }) => theme.content.weak}; - line-height: 20px; -`; +function getSpacingPosition(spacingValue: SpacingValues, position: keyof SpacingValues): number { + return spacingValue[position]; +} diff --git a/web/src/beta/components/fields/index.tsx b/web/src/beta/components/fields/index.tsx index 74f9f25e6d..ab777770fd 100644 --- a/web/src/beta/components/fields/index.tsx +++ b/web/src/beta/components/fields/index.tsx @@ -29,7 +29,7 @@ export default Property; const Wrapper = styled.div` display: flex; flex-direction: column; - gap: 4px; + gap: 8px; `; const Description = styled(Text)` diff --git a/web/src/services/i18n/translations/en.yml b/web/src/services/i18n/translations/en.yml index 89d9d1d244..0db08b507f 100644 --- a/web/src/services/i18n/translations/en.yml +++ b/web/src/services/i18n/translations/en.yml @@ -436,3 +436,5 @@ Failed to update widget.: Failed to update widget. Failed to remove widget.: Failed to remove widget. Failed to update widget alignment.: Failed to update widget alignment. Failed to update the widget align system.: Failed to update the widget align system. +You have passed the maximum value.: You have passed the maximum value. +You have passed the minimum value.: You have passed the minimum value. \ No newline at end of file diff --git a/web/src/services/i18n/translations/ja.yml b/web/src/services/i18n/translations/ja.yml index 6a46015761..85237db3b7 100644 --- a/web/src/services/i18n/translations/ja.yml +++ b/web/src/services/i18n/translations/ja.yml @@ -397,3 +397,5 @@ Failed to update widget.: ウィジェットのアップデートに失敗しま Failed to remove widget.: ウィジェットの削除に失敗しました。 Failed to update widget alignment.: ウィジェットのアラインメントのアップデートに失敗しました。 Failed to update the widget align system.: ウィジェットのアラインシステムのアップデートに失敗しました。 +You have passed the maximum value.: You have passed the maximum value. +You have passed the minimum value.: You have passed the minimum value. \ No newline at end of file From ba1c41fc4d4f7e051858dbaa6ec3760815fb7625 Mon Sep 17 00:00:00 2001 From: nina992 Date: Mon, 28 Aug 2023 18:10:14 +0300 Subject: [PATCH 05/13] move-numberinput-out --- web/src/beta/components/fields/SpacingInput/index.tsx | 2 +- .../fields/{ => common}/NumberInput/index.stories.tsx | 0 .../beta/components/fields/{ => common}/NumberInput/index.tsx | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename web/src/beta/components/fields/{ => common}/NumberInput/index.stories.tsx (100%) rename web/src/beta/components/fields/{ => common}/NumberInput/index.tsx (100%) diff --git a/web/src/beta/components/fields/SpacingInput/index.tsx b/web/src/beta/components/fields/SpacingInput/index.tsx index 41080372a9..c11d6c94ce 100644 --- a/web/src/beta/components/fields/SpacingInput/index.tsx +++ b/web/src/beta/components/fields/SpacingInput/index.tsx @@ -3,7 +3,7 @@ import React, { useState } from "react"; import { styled } from "@reearth/services/theme"; import Property from ".."; -import NumberInput from "../NumberInput"; +import NumberInput from "../common/NumberInput"; type SpacingValues = { top: number; diff --git a/web/src/beta/components/fields/NumberInput/index.stories.tsx b/web/src/beta/components/fields/common/NumberInput/index.stories.tsx similarity index 100% rename from web/src/beta/components/fields/NumberInput/index.stories.tsx rename to web/src/beta/components/fields/common/NumberInput/index.stories.tsx diff --git a/web/src/beta/components/fields/NumberInput/index.tsx b/web/src/beta/components/fields/common/NumberInput/index.tsx similarity index 100% rename from web/src/beta/components/fields/NumberInput/index.tsx rename to web/src/beta/components/fields/common/NumberInput/index.tsx From 0da79c16625239c1cd2eadef27a5fdcf05ec1087 Mon Sep 17 00:00:00 2001 From: nina992 Date: Tue, 29 Aug 2023 08:17:18 +0300 Subject: [PATCH 06/13] set-min-max-width --- web/src/beta/components/fields/SpacingInput/index.tsx | 8 ++++++-- .../components/fields/common/NumberInput/index.tsx | 10 ++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/web/src/beta/components/fields/SpacingInput/index.tsx b/web/src/beta/components/fields/SpacingInput/index.tsx index c11d6c94ce..3bfa7897dc 100644 --- a/web/src/beta/components/fields/SpacingInput/index.tsx +++ b/web/src/beta/components/fields/SpacingInput/index.tsx @@ -5,7 +5,7 @@ import { styled } from "@reearth/services/theme"; import Property from ".."; import NumberInput from "../common/NumberInput"; -type SpacingValues = { +export type SpacingValues = { top: number; left: number; right: number; @@ -16,10 +16,12 @@ type Props = { name?: string; description?: string; value?: SpacingValues; + min?: number; + max?: number; onChange?: (values: SpacingValues) => void; }; -const SpacingInput: React.FC = ({ name, description, value, onChange }) => { +const SpacingInput: React.FC = ({ name, description, value, min, max, onChange }) => { const [spacingValues, setSpacingValues] = useState( value || { top: 0, left: 0, right: 0, bottom: 0 }, ); @@ -42,6 +44,8 @@ const SpacingInput: React.FC = ({ name, description, value, onChange }) = suffix="px" key={position} position={position} + min={min} + max={max} onChange={newValue => handleInputChange(position as keyof SpacingValues, newValue)} /> ))} diff --git a/web/src/beta/components/fields/common/NumberInput/index.tsx b/web/src/beta/components/fields/common/NumberInput/index.tsx index 0ff6ad93bc..d8e2cc3886 100644 --- a/web/src/beta/components/fields/common/NumberInput/index.tsx +++ b/web/src/beta/components/fields/common/NumberInput/index.tsx @@ -65,7 +65,10 @@ const NumberInput: React.FC = ({ ); const handleChange = useCallback((e: React.ChangeEvent) => { - setInnerValue(parseFloat(e.currentTarget.value)); + const newValue = parseFloat(e.currentTarget.value); + setInnerValue(newValue); + const minWidth = Math.max(metricsSizes.xs, `${newValue}`.length * 10); + e.currentTarget.style.width = `${minWidth}px`; }, []); const handleKeyPress = useCallback( @@ -128,13 +131,16 @@ type FormProps = { inactive: boolean }; const FormWrapper = styled.div` display: flex; + flex-direction: row; align-items: center; background: ${({ theme }) => theme.bg[1]}; border: 1px solid ${({ theme }) => theme.outline.weak}; border-radius: 4px; padding: ${metricsSizes.xs}px ${metricsSizes.s}px; gap: 12px; - width: 100%; + width: auto; + min-width: min-content; + max-width: 275px; color: ${({ inactive, theme }) => (inactive ? theme.content.weak : theme.content.main)}; &:focus-within { border-color: ${({ theme }) => theme.select.main}; From 302220cae1b1a6024dd91dd0f0b9e4b434f783a3 Mon Sep 17 00:00:00 2001 From: nina992 Date: Tue, 29 Aug 2023 08:32:07 +0300 Subject: [PATCH 07/13] add-to-property-field --- web/src/beta/components/fields/PropertyFields/index.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/web/src/beta/components/fields/PropertyFields/index.tsx b/web/src/beta/components/fields/PropertyFields/index.tsx index d927a6f49a..0e069ee6ae 100644 --- a/web/src/beta/components/fields/PropertyFields/index.tsx +++ b/web/src/beta/components/fields/PropertyFields/index.tsx @@ -2,6 +2,7 @@ import TextInput from "@reearth/beta/components/fields/TextInput"; import { type Item } from "@reearth/services/api/propertyApi/utils"; import ColorField from "../ColorField"; +import SpacingInput, { SpacingValues } from "../SpacingInput"; import useHooks from "./hooks"; @@ -40,6 +41,14 @@ const PropertyFields: React.FC = ({ propertyId, item }) => { onChange={handlePropertyValueUpdate(item.schemaGroup, propertyId, sf.id, sf.type)} /> ) + ) : sf.type === "spacing" ? ( + ) : (

{sf.name} field

); From ccfa246e489681c2fbd3b45e8505d292907f7775 Mon Sep 17 00:00:00 2001 From: nina992 Date: Tue, 29 Aug 2023 18:35:19 +0300 Subject: [PATCH 08/13] propertyField-min-max --- web/src/beta/components/fields/PropertyFields/index.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/src/beta/components/fields/PropertyFields/index.tsx b/web/src/beta/components/fields/PropertyFields/index.tsx index 0e069ee6ae..257c514682 100644 --- a/web/src/beta/components/fields/PropertyFields/index.tsx +++ b/web/src/beta/components/fields/PropertyFields/index.tsx @@ -47,6 +47,8 @@ const PropertyFields: React.FC = ({ propertyId, item }) => { name={sf.name} value={(value as SpacingValues) ?? ""} description={sf.description} + min={sf.min} + max={sf.max} onChange={handlePropertyValueUpdate(item.schemaGroup, propertyId, sf.id, sf.type)} /> ) : ( From 44316037267368c3b331e4490bcb84f9fac74ac4 Mon Sep 17 00:00:00 2001 From: nina992 Date: Wed, 30 Aug 2023 13:17:32 +0300 Subject: [PATCH 09/13] Panel-Setting --- web/src/beta/components/fields/SpacingInput/index.tsx | 4 ++-- web/src/beta/components/fields/common/NumberInput/index.tsx | 3 ++- .../StoryPanel/Block/builtin/common/ActionPanel/index.tsx | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/web/src/beta/components/fields/SpacingInput/index.tsx b/web/src/beta/components/fields/SpacingInput/index.tsx index 3bfa7897dc..53a6df5487 100644 --- a/web/src/beta/components/fields/SpacingInput/index.tsx +++ b/web/src/beta/components/fields/SpacingInput/index.tsx @@ -58,11 +58,11 @@ export default SpacingInput; const StyledRectangle = styled.div` display: flex; - position: relative; - width: 289px; + width: 100%; height: 84px; border: 1px dashed ${({ theme }) => theme.outline.weak}; box-sizing: border-box; + position: relative; `; const SpacingField = styled(NumberInput)<{ position: string }>` diff --git a/web/src/beta/components/fields/common/NumberInput/index.tsx b/web/src/beta/components/fields/common/NumberInput/index.tsx index d8e2cc3886..5d5bd06ffa 100644 --- a/web/src/beta/components/fields/common/NumberInput/index.tsx +++ b/web/src/beta/components/fields/common/NumberInput/index.tsx @@ -140,7 +140,7 @@ const FormWrapper = styled.div` gap: 12px; width: auto; min-width: min-content; - max-width: 275px; + max-width: 64px; color: ${({ inactive, theme }) => (inactive ? theme.content.weak : theme.content.main)}; &:focus-within { border-color: ${({ theme }) => theme.select.main}; @@ -155,6 +155,7 @@ const StyledInput = styled.input` outline: none; color: inherit; width: 100%; + max-width: 64px; &::-webkit-inner-spin-button, &::-webkit-outer-spin-button { -webkit-appearance: none; diff --git a/web/src/beta/features/Editor/StoryPanel/Block/builtin/common/ActionPanel/index.tsx b/web/src/beta/features/Editor/StoryPanel/Block/builtin/common/ActionPanel/index.tsx index ae0f4c5536..816689adc2 100644 --- a/web/src/beta/features/Editor/StoryPanel/Block/builtin/common/ActionPanel/index.tsx +++ b/web/src/beta/features/Editor/StoryPanel/Block/builtin/common/ActionPanel/index.tsx @@ -169,7 +169,7 @@ const SettingsHeading = styled.div` `; const SettingsContent = styled.div` - height: 100px; + height: 134px; width: 200px; padding: 8px; box-sizing: border-box; From 1bfa946cc04c9c56d070252fa544f3a4ebb42245 Mon Sep 17 00:00:00 2001 From: nina992 Date: Wed, 30 Aug 2023 13:34:27 +0300 Subject: [PATCH 10/13] height --- web/src/beta/components/fields/SpacingInput/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/beta/components/fields/SpacingInput/index.tsx b/web/src/beta/components/fields/SpacingInput/index.tsx index 53a6df5487..ba717e406a 100644 --- a/web/src/beta/components/fields/SpacingInput/index.tsx +++ b/web/src/beta/components/fields/SpacingInput/index.tsx @@ -59,7 +59,7 @@ export default SpacingInput; const StyledRectangle = styled.div` display: flex; width: 100%; - height: 84px; + height: 94px; border: 1px dashed ${({ theme }) => theme.outline.weak}; box-sizing: border-box; position: relative; From 09cfc9d84bfdb95b830c091ac3d9bddc918825d2 Mon Sep 17 00:00:00 2001 From: nina992 Date: Thu, 31 Aug 2023 10:28:10 +0300 Subject: [PATCH 11/13] pr-comments1 --- .../components/fields/SpacingInput/index.tsx | 22 +++++++++++-------- .../fields/common/NumberInput/index.tsx | 18 +++++++-------- .../builtin/common/ActionPanel/index.tsx | 2 +- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/web/src/beta/components/fields/SpacingInput/index.tsx b/web/src/beta/components/fields/SpacingInput/index.tsx index ba717e406a..ac4af706fe 100644 --- a/web/src/beta/components/fields/SpacingInput/index.tsx +++ b/web/src/beta/components/fields/SpacingInput/index.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useMemo, useState } from "react"; import { styled } from "@reearth/services/theme"; @@ -20,16 +20,20 @@ type Props = { max?: number; onChange?: (values: SpacingValues) => void; }; +type Position = keyof SpacingValues; const SpacingInput: React.FC = ({ name, description, value, min, max, onChange }) => { const [spacingValues, setSpacingValues] = useState( value || { top: 0, left: 0, right: 0, bottom: 0 }, ); - const handleInputChange = ( - position: keyof SpacingValues, - newValue: string | number | undefined, - ) => { + const memoizedSpacingValues = useMemo(() => { + return ["top", "left", "right", "bottom"].map(position => { + return getSpacingPosition(spacingValues, position as Position); + }); + }, [spacingValues]); + + const handleInputChange = (position: Position, newValue?: number) => { const updatedValues = { ...spacingValues, [position]: newValue }; setSpacingValues(updatedValues); onChange?.(updatedValues); @@ -38,15 +42,15 @@ const SpacingInput: React.FC = ({ name, description, value, min, max, onC return ( - {["top", "left", "right", "bottom"].map(position => ( + {["top", "left", "right", "bottom"].map((position, index) => ( handleInputChange(position as keyof SpacingValues, newValue)} + onChange={newValue => handleInputChange(position as Position, newValue)} /> ))} @@ -78,6 +82,6 @@ const SpacingField = styled(NumberInput)<{ position: string }>` : "bottom: 0; left: 50%; transform: translateX(-50%);"}; `; -function getSpacingPosition(spacingValue: SpacingValues, position: keyof SpacingValues): number { +function getSpacingPosition(spacingValue: SpacingValues, position: Position): number { return spacingValue[position]; } diff --git a/web/src/beta/components/fields/common/NumberInput/index.tsx b/web/src/beta/components/fields/common/NumberInput/index.tsx index 5d5bd06ffa..e1be1e661b 100644 --- a/web/src/beta/components/fields/common/NumberInput/index.tsx +++ b/web/src/beta/components/fields/common/NumberInput/index.tsx @@ -39,7 +39,7 @@ const NumberInput: React.FC = ({ setInnerValue(value); }, [value]); - const callChange = useCallback( + const handleValueChange = useCallback( (newValue: number | undefined) => { if (!onChange || !isEditing.current) { return; @@ -74,10 +74,10 @@ const NumberInput: React.FC = ({ const handleKeyPress = useCallback( (e: React.KeyboardEvent) => { if (e.key === "Enter") { - callChange(parseFloat(e.currentTarget.value)); + handleValueChange(parseFloat(e.currentTarget.value)); } }, - [callChange], + [handleValueChange], ); const handleFocus = useCallback(() => { @@ -86,15 +86,15 @@ const NumberInput: React.FC = ({ const handleBlur = useCallback( (e: React.SyntheticEvent) => { - callChange(parseFloat(e.currentTarget.value)); + handleValueChange(parseFloat(e.currentTarget.value)); isEditing.current = false; }, - [callChange], + [handleValueChange], ); return ( - + = ({ {suffix} )} - + {inputDescription && ( {inputDescription} @@ -127,9 +127,7 @@ const Wrapper = styled.div` text-align: center; `; -type FormProps = { inactive: boolean }; - -const FormWrapper = styled.div` +const InputWrapper = styled.div<{ inactive: boolean }>` display: flex; flex-direction: row; align-items: center; diff --git a/web/src/beta/features/Editor/StoryPanel/Block/builtin/common/ActionPanel/index.tsx b/web/src/beta/features/Editor/StoryPanel/Block/builtin/common/ActionPanel/index.tsx index 816689adc2..c6bf0aa8ed 100644 --- a/web/src/beta/features/Editor/StoryPanel/Block/builtin/common/ActionPanel/index.tsx +++ b/web/src/beta/features/Editor/StoryPanel/Block/builtin/common/ActionPanel/index.tsx @@ -169,7 +169,7 @@ const SettingsHeading = styled.div` `; const SettingsContent = styled.div` - height: 134px; + min-height: 134px; width: 200px; padding: 8px; box-sizing: border-box; From 7958e7e69b8ab897b89e880b7ba161a1fd2ccefd Mon Sep 17 00:00:00 2001 From: nina992 Date: Thu, 31 Aug 2023 11:56:42 +0300 Subject: [PATCH 12/13] fix-digit --- .../fields/common/NumberInput/index.tsx | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/web/src/beta/components/fields/common/NumberInput/index.tsx b/web/src/beta/components/fields/common/NumberInput/index.tsx index e1be1e661b..2a9404bc76 100644 --- a/web/src/beta/components/fields/common/NumberInput/index.tsx +++ b/web/src/beta/components/fields/common/NumberInput/index.tsx @@ -29,6 +29,7 @@ const NumberInput: React.FC = ({ }) => { const [innerValue, setInnerValue] = useState(value); const [, setNotification] = useNotification(); + const inputRef = useRef(null); const isEditing = useRef(false); const t = useT(); @@ -39,6 +40,14 @@ const NumberInput: React.FC = ({ setInnerValue(value); }, [value]); + useEffect(() => { + // Calculate and set the minimum width for the input field + if (inputRef.current) { + const minWidth = Math.max(metricsSizes.xs, inputRef.current.value.length * 10); + inputRef.current.style.width = `${minWidth}px`; + } + }, []); + const handleValueChange = useCallback( (newValue: number | undefined) => { if (!onChange || !isEditing.current) { @@ -65,9 +74,9 @@ const NumberInput: React.FC = ({ ); const handleChange = useCallback((e: React.ChangeEvent) => { - const newValue = parseFloat(e.currentTarget.value); - setInnerValue(newValue); - const minWidth = Math.max(metricsSizes.xs, `${newValue}`.length * 10); + const newValue = e.currentTarget.value; + setInnerValue(parseFloat(newValue)); + const minWidth = Math.max(metricsSizes.xs, newValue.length * 10); e.currentTarget.style.width = `${minWidth}px`; }, []); @@ -86,7 +95,8 @@ const NumberInput: React.FC = ({ const handleBlur = useCallback( (e: React.SyntheticEvent) => { - handleValueChange(parseFloat(e.currentTarget.value)); + const newValue = parseFloat(e.currentTarget.value); + handleValueChange(newValue); isEditing.current = false; }, [handleValueChange], @@ -104,8 +114,9 @@ const NumberInput: React.FC = ({ onFocus={handleFocus} onBlur={handleBlur} min={min} + ref={inputRef} max={max} - step="any" + step={"any"} /> {suffix && ( @@ -153,7 +164,6 @@ const StyledInput = styled.input` outline: none; color: inherit; width: 100%; - max-width: 64px; &::-webkit-inner-spin-button, &::-webkit-outer-spin-button { -webkit-appearance: none; From ad5fa8b528fbd23d55af017fd33b5385840d37ca Mon Sep 17 00:00:00 2001 From: nina992 Date: Thu, 31 Aug 2023 12:06:36 +0300 Subject: [PATCH 13/13] merge-with-main2 --- .../beta/components/fields/PropertyFields/index.tsx | 11 +++++++++++ .../features/Editor/StoryPanel/ActionPanel/index.tsx | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/web/src/beta/components/fields/PropertyFields/index.tsx b/web/src/beta/components/fields/PropertyFields/index.tsx index 7be829a1c8..e2580fa16f 100644 --- a/web/src/beta/components/fields/PropertyFields/index.tsx +++ b/web/src/beta/components/fields/PropertyFields/index.tsx @@ -2,6 +2,7 @@ import TextInput from "@reearth/beta/components/fields/TextInput"; import { type Item } from "@reearth/services/api/propertyApi/utils"; import ColorField from "../ColorField"; +import SpacingInput, { SpacingValues } from "../SpacingInput"; import ToggleField from "../ToggleField"; import useHooks from "./hooks"; @@ -42,6 +43,16 @@ const PropertyFields: React.FC = ({ propertyId, item }) => { onChange={handlePropertyValueUpdate(item.schemaGroup, propertyId, sf.id, sf.type)} /> ) + ) : sf.type === "spacing" ? ( + ) : sf.type == "bool" ? (