diff --git a/Caecae/src/App/main.tsx b/Caecae/src/App/main.tsx index 83a31ad..7cb15b2 100644 --- a/Caecae/src/App/main.tsx +++ b/Caecae/src/App/main.tsx @@ -4,12 +4,7 @@ import "./main.css"; // 임시 React component const App = () => { - return ( -
-

Hello, React!

-

Hello, Typescript!

-
- ); + return
; }; ReactDOM.createRoot(document.getElementById("root")!).render(); diff --git a/Caecae/src/Job/.gitkeep b/Caecae/src/Job/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/Caecae/src/Job/Overlay/OverlayWork.tsx b/Caecae/src/Job/Overlay/OverlayWork.tsx new file mode 100644 index 0000000..cf67c55 --- /dev/null +++ b/Caecae/src/Job/Overlay/OverlayWork.tsx @@ -0,0 +1,54 @@ +import { createState } from "../../Shared/Hyundux/State"; +import { makePayLoad } from "../../Shared/Hyundux/Util/StoreUtil"; +import Reducer from "../../Shared/Hyundux/Reducer"; +import Action from "../../Shared/Hyundux/Actions"; + +const WORK_NAME = "Overlay"; + +// state type +interface OverlayPayLoad { + isShowing: boolean; + index: number; + isOnButton: boolean; +} + +const initOverlayState = createState(WORK_NAME, { + isShowing: false, + index: 0, + isOnButton: false, +}); + +// define reducer +const overlayReducer: Reducer = { + type: WORK_NAME, + reducer: async function reducer(state, action) { + const payLoad = state.payload; + switch (action.actionName) { + case "toggleOverlay": { + return makePayLoad(state, { isShowing: !payLoad.isShowing }); + } + case "nextPage": { + return makePayLoad(state, { index: payLoad.index + 1 }); + } + default: + return state; + } + }, +}; +// actions +const action = { + toggleOverlay: (): Action => { + return { + type: WORK_NAME, + actionName: "toggleOverlay", + }; + }, + nextPage: (): Action => { + return { + type: WORK_NAME, + actionName: "nextPage", + }; + }, +}; + +export { action, initOverlayState, overlayReducer }; diff --git a/Caecae/src/Shared/Hyundux/Example_Counter/ConuntUI.tsx b/Caecae/src/Shared/Hyundux/Example_Counter/ConuntUI.tsx index 3e9cd70..d1ba6e8 100644 --- a/Caecae/src/Shared/Hyundux/Example_Counter/ConuntUI.tsx +++ b/Caecae/src/Shared/Hyundux/Example_Counter/ConuntUI.tsx @@ -1,9 +1,9 @@ -import useBind from "../Hooks/Binding.tsx"; +import useWork from "../Hooks/useWork.tsx"; import { action, initCountState, countReducer } from "./CountWorkFlow.tsx"; import store from "../Store.tsx"; const Counter = () => { - const state = useBind(initCountState, countReducer); + const state = useWork(initCountState, countReducer); function temp1() { store.dispatch(action.countUp()); diff --git a/Caecae/src/Shared/Hyundux/Hooks/Binding.tsx b/Caecae/src/Shared/Hyundux/Hooks/Binding.tsx deleted file mode 100644 index 2c8c21f..0000000 --- a/Caecae/src/Shared/Hyundux/Hooks/Binding.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { useState } from 'react'; -import HState from '../State'; -import store from '../Store'; -import Reducer from '../Reducer'; - - -function useBind(initialState: HState, reducer: Reducer): PayLoad { - const [state, setState] = useState>(initialState); - store.subscribe(state, reducer, (newState) => { - setState(newState) - }); - - return state.payload; -} - -export default useBind; diff --git a/Caecae/src/Shared/Hyundux/Hooks/useWork.tsx b/Caecae/src/Shared/Hyundux/Hooks/useWork.tsx new file mode 100644 index 0000000..2463f22 --- /dev/null +++ b/Caecae/src/Shared/Hyundux/Hooks/useWork.tsx @@ -0,0 +1,18 @@ +import { useState } from "react"; +import HState from "../State"; +import store from "../Store"; +import Reducer from "../Reducer"; + +function useWork( + initialState: HState, + reducer: Reducer +): PayLoad { + const [state, setState] = useState>(initialState); + store.subscribe(state, reducer, (newState) => { + setState(newState); + }); + + return state.payload; +} + +export default useWork; diff --git a/Caecae/src/Shared/Hyundux/Store.tsx b/Caecae/src/Shared/Hyundux/Store.tsx index ed8d341..71a09ee 100644 --- a/Caecae/src/Shared/Hyundux/Store.tsx +++ b/Caecae/src/Shared/Hyundux/Store.tsx @@ -5,35 +5,56 @@ import removeFirst from "./Util/RemoveFirst"; import replaceFirst from "./Util/ReplaceFirst"; const store: { - states: State[], - reducers: Reducer[], - subscribe: (initState: State, reducer: Reducer, cb: (state: State) => void) => void, - dispatch: (action: Action) => void, - publish: (state: State) => void, - subscribeList: Map(state: State) => void>, + states: State[]; + reducers: Reducer[]; + subscribe: ( + initState: State, + reducer: Reducer, + cb: (state: State) => void + ) => void; + dispatch: (action: Action) => void; + publish: (state: State) => void; + subscribeList: Map(state: State) => void>; } = { - states: [], - reducers: [], - subscribeList: new Map(), - dispatch: async function (action) { - const reducer = this.reducers.filter(reducer => reducer.type == action.type)[0].reducer - const { removed, newArray } = removeFirst(this.states, (state) => state.type == action.type) - const newState = await reducer(removed, action); - // 여기서 모든것을 바로 state를 적용하는것이 아니라 이게 다른 state도 propagation하는지도 확인해야함 - this.states = [...newArray, newState]; - this.publish(newState); - }, - publish: function (state) { - const publishedCallBack = this.subscribeList.get(state.type); - if (publishedCallBack !== undefined) { - publishedCallBack(state); - } - }, - subscribe: function (state: State, reducer: Reducer, cb: (state: State) => void) { - this.states = replaceFirst(this.states, state, (element) => element.type == state.type) - this.reducers = replaceFirst(this.reducers, reducer as Reducer, (element) => element.type == state.type) - this.subscribeList.set(state.type, cb as (state: State) => void); + states: [], + reducers: [], + subscribeList: new Map(), + dispatch: async function (action) { + const reducer = this.reducers.filter( + (reducer) => reducer.type == action.type + )[0].reducer; + const { removed, newArray } = removeFirst( + this.states, + (state) => state.type == action.type + ); + const newState = await reducer(removed, action); + // 여기서 모든것을 바로 state를 적용하는것이 아니라 이게 다른 state도 propagation하는지도 확인해야함 + this.states = [...newArray, newState]; + this.publish(newState); + }, + publish: function (state) { + const publishedCallBack = this.subscribeList.get(state.type); + if (publishedCallBack !== undefined) { + publishedCallBack(state); } -} + }, + subscribe: function ( + state: State, + reducer: Reducer, + cb: (state: State) => void + ) { + this.states = replaceFirst( + this.states, + state, + (element) => element.type == state.type + ); + this.reducers = replaceFirst( + this.reducers, + reducer as Reducer, + (element) => element.type == state.type + ); + this.subscribeList.set(state.type, cb as (state: State) => void); + }, +}; -export default store +export default store; diff --git a/Caecae/src/Shared/Util/FindChildrenElement.tsx b/Caecae/src/Shared/Util/FindChildrenElement.tsx new file mode 100644 index 0000000..08a8d17 --- /dev/null +++ b/Caecae/src/Shared/Util/FindChildrenElement.tsx @@ -0,0 +1,22 @@ +import React, { isValidElement, ReactElement, ReactNode } from "react"; + +const findChildrenElement = ( + elements: ReactNode, + checkFn: (element: ReactElement) => boolean +): ReactElement | null => { + let returnElement: ReactElement | null = null; + React.Children.forEach(elements, (element) => { + if (!isValidElement(element)) { + return; + } + if (element.type === React.Fragment) { + return; + } + if (checkFn(element)) { + returnElement = element.props.element; + } + }); + return returnElement; +}; + +export default findChildrenElement; diff --git a/Caecae/src/Shared/assets/xButton.svg b/Caecae/src/Shared/assets/xButton.svg new file mode 100644 index 0000000..e394c82 --- /dev/null +++ b/Caecae/src/Shared/assets/xButton.svg @@ -0,0 +1,3 @@ + + + diff --git a/Caecae/src/Widget/Component/Overlay/Overlay.tsx b/Caecae/src/Widget/Component/Overlay/Overlay.tsx new file mode 100644 index 0000000..da2b4f8 --- /dev/null +++ b/Caecae/src/Widget/Component/Overlay/Overlay.tsx @@ -0,0 +1,46 @@ +import React, { ReactNode } from "react"; +import useWork from "../../../Shared/Hyundux/Hooks/useWork"; +import { + initOverlayState, + overlayReducer, + action, +} from "../../../Job/Overlay/OverlayWork"; +import store from "../../../Shared/Hyundux/Store"; +import findChildrenElement from "../../../Shared/Util/FindChildrenElement"; + +interface OverLayProps { + children: ReactNode; +} + +const OverLay: React.FC = ({ children }) => { + const state = useWork(initOverlayState, overlayReducer); + const content = findChildrenElement( + children, + (element) => + element.props.index !== undefined && element.props.index == state.index + ); + + if (state.isShowing) { + return ( +
+
+ { + store.dispatch(action.toggleOverlay()); + }} + /> + {content} +
+
+ ); + } else { + return null; + } +}; + +export default OverLay; diff --git a/Caecae/src/Widget/Component/Overlay/OverlayContent.tsx b/Caecae/src/Widget/Component/Overlay/OverlayContent.tsx new file mode 100644 index 0000000..09e99b9 --- /dev/null +++ b/Caecae/src/Widget/Component/Overlay/OverlayContent.tsx @@ -0,0 +1,12 @@ +import React, { ReactElement } from "react"; + +interface OverLayContentProps { + index: number; + element: ReactElement; +} + +const OverLayContent: React.FC = () => { + return null; +}; + +export default OverLayContent;