Newer
Older
NocodeToolOnRDL / src / components / property / property.tsx
@Sakoda2269 Sakoda2269 8 days ago 5 KB custom hookを整理
import { ComponentType, type Component } from "../../types/component";
import { useContext, useEffect, useState } from "react";
import { TextProperty } from "./textProperties";
import { ButtonProperty } from "./buttonProperties";
import { TableProperty } from "./tableProperties";
import { ActiveTab } from "../../constants/activeTab";
import { ProjectContext } from "../../hooks/useProject";
import { CurrentScreenContext } from "../../hooks/useCurrentScreen";


export default function Property() {


    const projectContext = useContext(ProjectContext);
    const curScreenContext = useContext(CurrentScreenContext);

    if (projectContext === null || curScreenContext === null) return <div>loading...</div>

    const curScreenStates = curScreenContext.curScreenStates;


    if (curScreenStates.selectingComponent === null)
        return <div></div>

    return <ComponentPropertyArea
        selectingComponent={curScreenStates.selectingComponent}
    />;
}

function ComponentPropertyArea({ selectingComponent }: { selectingComponent: Component }) {

    const projectContext = useContext(ProjectContext);
    const curScreenContext = useContext(CurrentScreenContext);

    const componentName = selectingComponent.name;
    const [name, setName] = useState<string>(componentName);
    const [activeTab, setActiveTab] = useState<ActiveTab>(ActiveTab.GENERAL);

    useEffect(() => {
        // eslint-disable-next-line react-hooks/set-state-in-effect
        setName(componentName);
    }, [componentName])

    if (projectContext === null || curScreenContext === null) return <div>loading...</div>

    const projectActions = projectContext.projectActions;


    const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        setName(e.target.value);
    }

    function nameValidate() {
        if (!name.trim()) return false;
        return true;
    }

    const handleNameConfirm = (e: React.FocusEvent<HTMLInputElement, Element>) => {
        if (!nameValidate()) {
            setName(selectingComponent.name);
            return;
        }
        projectActions.updateComponent({ ...selectingComponent, name: e.target.value })
        // componentActions.updateConfirm({ ...component, name: e.target.value });
    }

    return (
        <div className="flex-col flex h-full">
            <nav className="flex w-full border-b-1">
                <button
                    className={`flex-1 text-sm py-4 px-1 block hover:text-blue-500 focus:outline-none ${activeTab == ActiveTab.GENERAL ? "text-blue-500 border-b-2 font-medium border-blue-500" : "text-gray-600"}`}
                    onClick={() => setActiveTab(ActiveTab.GENERAL)}
                >
                    一般
                </button>
                <button
                    className={`flex-1 text-sm py-4 px-1 block hover:text-blue-500 focus:outline-none ${activeTab == ActiveTab.STYLE ? "text-blue-500 border-b-2 font-medium border-blue-500" : "text-gray-600"}`}
                    onClick={() => setActiveTab(ActiveTab.STYLE)}
                >
                    スタイル
                </button>
                <button
                    className={`flex-1 text-sm py-4 px-1 block hover:text-blue-500 focus:outline-none ${activeTab == ActiveTab.ACTION ? "text-blue-500 border-b-2 font-medium border-blue-500" : "text-gray-600"}`}
                    onClick={() => setActiveTab(ActiveTab.ACTION)}
                >
                    アクション
                </button>
            </nav>
            <div className="flex-col mt-8 ml-4 mr-4 flex h-full overflow-y-auto">
                {activeTab === 0 && <div className="mb-4">
                    <label className="block font-medium text-gray-700 mb-2">
                        id
                    </label>
                    <input
                        type="text"
                        value={name}
                        onChange={(e) => handleNameChange(e)}
                        onBlur={(e) => handleNameConfirm(e)}
                        onKeyDown={(e) => {
                            if (e.key === "Enter") {
                                e.preventDefault()
                                    ; (e.currentTarget as HTMLInputElement).blur()
                            }
                        }}
                        className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-colors"
                    />
                </div>}
                {selectingComponent.type === ComponentType.Text &&
                    <TextProperty
                        activeTab={activeTab}
                        selectingComponent={selectingComponent}
                    />
                }
                {selectingComponent.type === ComponentType.Button &&
                    <ButtonProperty
                        activeTab={activeTab}
                        selectingComponent={selectingComponent}
                    />
                }
                {selectingComponent.type === ComponentType.Table &&
                    <TableProperty
                        activeTab={activeTab}
                        selectingComponent={selectingComponent}
                    />
                }
            </div>
        </div>
    )
}