diff --git a/web/src/beta/components/Slider/index.stories.tsx b/web/src/beta/components/Slider/index.stories.tsx index 73c4a945df..80ff85c920 100644 --- a/web/src/beta/components/Slider/index.stories.tsx +++ b/web/src/beta/components/Slider/index.stories.tsx @@ -1,13 +1,51 @@ -import { action } from "@storybook/addon-actions"; -import { Meta } from "@storybook/react"; +import { useArgs } from "@storybook/preview-api"; +import { Meta, StoryObj } from "@storybook/react"; +import { useCallback } from "react"; -import Slider from "."; +import { styled } from "@reearth/services/theme"; -export default { +import Slider, { Props } from "."; + +const meta: Meta = { component: Slider, -} as Meta; +}; + +type Story = StoryObj; + +export default meta; + +export const Default: Story = (args: Props) => { + const [_, updateArgs] = useArgs(); + + const handleChange = useCallback((value: number) => updateArgs({ value: value }), [updateArgs]); + + return ( + +
+ +
+
+ +
+
+ +
+
+ ); +}; + +Default.args = { + value: 50, + min: 0, + max: 100, + step: 1, + disabled: false, +}; -export const Default = () => ; -export const Frame = () => ( - -); +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 10%; + margin: 2rem; + height: 300px; +`; diff --git a/web/src/beta/components/Slider/index.tsx b/web/src/beta/components/Slider/index.tsx index 5f32296901..1147a175e2 100644 --- a/web/src/beta/components/Slider/index.tsx +++ b/web/src/beta/components/Slider/index.tsx @@ -1,51 +1,64 @@ import RCSlider from "rc-slider"; import React, { ComponentProps } from "react"; -import { styled, css } from "@reearth/services/theme"; +import { styled } from "@reearth/services/theme"; import "rc-slider/assets/index.css"; -type Props = { +const SliderWithTooltip = RCSlider.createSliderWithTooltip(RCSlider); + +export type Props = { min: number; max: number; - frame?: boolean; -} & Omit, "defaultValue">; +} & Omit, "defaultValue">; -const Slider: React.FC = ({ frame = false, ...props }) => ( - - - +const Slider: React.FC = ({ ...props }) => ( + + + ); -const Wrapper = styled.div<{ frame: boolean }>` - display: flex; - align-items: center; - border: ${({ frame, theme }) => (frame ? `solid 1px ${theme.outline.main}` : "none")}; - border-radius: 3px; - background: ${({ frame, theme }) => (frame ? theme.bg[1] : "transparent")}; - width: 100%; - flex: 1; - box-sizing: border-box; - ${({ frame }) => - frame && - css` - padding: 6px 12px; - margin-right: 5px; - `}; -`; +const SliderStyled = styled.div<{ disabled: boolean }>` + .rc-slider-disabled { + background-color: transparent; + opacity: ${({ disabled }) => (disabled ? 0.6 : 1)}; + cursor: ${({ disabled }) => (disabled ? "not-allowed" : "inherit")}; + } + + .rc-slider-rail { + height: 8px; + } -const StyledSlider = styled(RCSlider)` .rc-slider-handle { - background-color: ${({ theme }) => theme.bg[2]}; - border: ${({ theme }) => theme.bg[2]}; + background-color: ${({ theme }) => theme.item.default}; + border: ${({ theme }) => theme.primary.weak}; + height: 12px; + width: 12px; + margin-top: -2px; } .rc-slider-track { - background-color: ${({ theme }) => theme.bg[2]}; + background-color: ${({ theme }) => theme.primary.weak}; + height: 8px; + } + + .rc-slider-rail { + background-color: ${({ theme }) => theme.outline.weaker}; + box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.25) inset; } - .rc-slider-handle:focus { - box-shadow: none; + .rc-slider-tooltip-arrow { + background-color: transparent; + border-top-color: ${({ theme }) => theme.bg[2]}; + bottom: 2px; + margin-left: -8px; + border-width: 9px 8px 0; + } + + .rc-slider-tooltip-inner { + background-color: ${({ theme }) => theme.bg[2]}; + color: ${({ theme }) => theme.content.main}; + box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.25); } `; diff --git a/web/src/beta/components/fields/PropertyFields/index.tsx b/web/src/beta/components/fields/PropertyFields/index.tsx index e2580fa16f..3926ffb641 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 SliderField from "../SliderField"; import SpacingInput, { SpacingValues } from "../SpacingInput"; import ToggleField from "../ToggleField"; @@ -53,7 +54,7 @@ const PropertyFields: React.FC = ({ propertyId, item }) => { max={sf.max} onChange={handlePropertyValueUpdate(item.schemaGroup, propertyId, sf.id, sf.type)} /> - ) : sf.type == "bool" ? ( + ) : sf.type === "bool" ? ( = ({ propertyId, item }) => { description={sf.description} onChange={handlePropertyValueUpdate(item.schemaGroup, propertyId, sf.id, sf.type)} /> + ) : sf.type === "number" ? ( + sf.ui === "slider" ? ( + + ) : ( +

{sf.name} number field

+ ) ) : (

{sf.name} field

); diff --git a/web/src/beta/components/fields/SliderField/index.stories.tsx b/web/src/beta/components/fields/SliderField/index.stories.tsx new file mode 100644 index 0000000000..8cf67861a5 --- /dev/null +++ b/web/src/beta/components/fields/SliderField/index.stories.tsx @@ -0,0 +1,67 @@ +import { useArgs } from "@storybook/preview-api"; +import { Meta, StoryObj } from "@storybook/react"; +import { useCallback } from "react"; + +import { styled } from "@reearth/services/theme"; + +import SliderField, { Props } from "."; + +const meta: Meta = { + component: SliderField, +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = (args: Props) => { + const [_, updateArgs] = useArgs(); + + const handleChange = useCallback((value: number) => updateArgs({ value: value }), [updateArgs]); + + return ( + +
+ +
+
+ +
+
+ +
+
+ ); +}; + +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 10%; + margin-left: 2rem; + margin-top: 2rem; + height: 300px; +`; + +Default.args = { + name: "Slider Field", + description: "Slider field Sample description", + value: 50, + min: 0, + max: 100, + step: 1, + disabled: false, + onChange: () => console.log("clicked"), +}; diff --git a/web/src/beta/components/fields/SliderField/index.tsx b/web/src/beta/components/fields/SliderField/index.tsx new file mode 100644 index 0000000000..34a56f886f --- /dev/null +++ b/web/src/beta/components/fields/SliderField/index.tsx @@ -0,0 +1,17 @@ +import Property from "@reearth/beta/components/fields"; +import Slider, { Props as SliderProps } from "@reearth/beta/components/Slider"; + +export type Props = { + name?: string; + description?: string; +} & SliderProps; + +const SliderField: React.FC = ({ name, description, ...args }: Props) => { + return ( + + + + ); +}; + +export default SliderField;