Skip to content

Commit

Permalink
chore(web): add date time field component (#740)
Browse files Browse the repository at this point in the history
Co-authored-by: nina992 <nouralali992@gmail.com>
  • Loading branch information
nina992 and nina992 committed Oct 18, 2023
1 parent 86dbb58 commit 6c8a42f
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 3 deletions.
16 changes: 16 additions & 0 deletions web/src/beta/components/fields/DateTimeField/index.stories.tsx
@@ -0,0 +1,16 @@
import { action } from "@storybook/addon-actions";
import { Meta, StoryObj } from "@storybook/react";

import DateTimeField from ".";

const meta: Meta<typeof DateTimeField> = {
component: DateTimeField,
};

export default meta;

type Story = StoryObj<typeof DateTimeField>;

export const DateTimeFieldInput: Story = {
render: () => <DateTimeField name="Date Time Field" onChange={action("onchange")} />,
};
63 changes: 63 additions & 0 deletions web/src/beta/components/fields/DateTimeField/index.tsx
@@ -0,0 +1,63 @@
import { useCallback, useEffect, useState } from "react";

import { styled } from "@reearth/services/theme";

import Property from "..";
import TextInput from "../common/TextInput";

export type Props = {
name?: string;
description?: string;
value?: string;
onChange?: (value?: string | undefined) => void;
};

const DateTimeField: React.FC<Props> = ({ name, description, value, onChange }) => {
const [time, setTime] = useState<string>();
const [date, setDate] = useState<string>();

const handleTimeChange = useCallback(
(newValue: string | undefined) => {
if (newValue === undefined) return;

setTime(newValue);
onChange?.(date + " " + newValue);
},
[date, onChange],
);

const handleDateChange = useCallback(
(newValue: string | undefined) => {
if (newValue === undefined) return;

setDate(newValue);
onChange?.(newValue + " " + time);
},
[time, onChange],
);

useEffect(() => {
if (value) {
const [dateString, timeString] = value.split(" ");
setTime(timeString);
setDate(dateString);
}
}, [value]);

return (
<Property name={name} description={description}>
<Wrapper>
<TextInput type="date" value={value} onChange={handleDateChange} />
<TextInput type="time" value={value} onChange={handleTimeChange} />
</Wrapper>
</Property>
);
};

export default DateTimeField;

const Wrapper = styled.div`
display: flex;
align-items: stretch;
gap: 4px;
`;
12 changes: 11 additions & 1 deletion web/src/beta/components/fields/PropertyFields/index.tsx
Expand Up @@ -15,6 +15,8 @@ import type { FlyTo } from "@reearth/beta/lib/core/types";
import type { Camera, LatLng } from "@reearth/beta/utils/value";
import type { Item } from "@reearth/services/api/propertyApi/utils";

import DateTimeField from "../DateTimeField";

import useHooks from "./hooks";

type Props = {
Expand Down Expand Up @@ -96,7 +98,15 @@ const PropertyFields: React.FC<Props> = ({ propertyId, item, currentCamera, onFl
const handleChange = handlePropertyValueUpdate(sf.id, sf.type, selected);

return sf.type === "string" ? (
sf.ui === "color" ? (
sf.ui === "datetime" ? (
<DateTimeField
key={sf.id}
name={sf.name}
value={(value as string) ?? ""}
description={sf.description}
onChange={handleChange}
/>
) : sf.ui === "color" ? (
<ColorField
key={sf.id}
name={sf.name}
Expand Down
6 changes: 5 additions & 1 deletion web/src/beta/components/fields/common/TextInput/index.tsx
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { HTMLInputTypeAttribute, useCallback, useEffect, useRef, useState } from "react";

import { styled } from "@reearth/services/theme";

Expand All @@ -7,6 +7,7 @@ export type Props = {
placeholder?: string;
timeout?: number;
autoFocus?: boolean;
type?: HTMLInputTypeAttribute;
onChange?: (text: string) => void;
onBlur?: () => void;
onExit?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
Expand All @@ -20,6 +21,7 @@ const TextInput: React.FC<Props> = ({
onChange,
onBlur,
onExit,
type,
}) => {
const [currentValue, setCurrentValue] = useState(value ?? "");
const timeoutRef = useRef<NodeJS.Timeout>();
Expand Down Expand Up @@ -63,6 +65,7 @@ const TextInput: React.FC<Props> = ({

return (
<StyledInput
type={type}
value={currentValue ?? ""}
placeholder={placeholder}
autoFocus={autoFocus}
Expand All @@ -87,4 +90,5 @@ const StyledInput = styled.input`
:focus {
border-color: ${({ theme }) => theme.outline.main};
}
color-scheme: dark;
`;
3 changes: 2 additions & 1 deletion web/src/services/api/propertyApi/utils.ts
Expand Up @@ -56,7 +56,8 @@ export type SchemaFieldType<T extends ValueType = ValueType> = {
| "layer"
| "cameraPose"
| "padding"
| "margin";
| "margin"
| "datetime";
choices?: {
key: string;
label: string;
Expand Down

0 comments on commit 6c8a42f

Please sign in to comment.