+
{children}
);
diff --git a/src/components/common/Dock/DockManager.tsx b/src/components/common/Dock/DockManager.tsx
new file mode 100644
index 0000000..2c0112f
--- /dev/null
+++ b/src/components/common/Dock/DockManager.tsx
@@ -0,0 +1,92 @@
+// Copyright (c) Hubert Bukowski. All rights reserved.
+// Licensed under the MIT License.
+// See LICENSE file in the project root for full license information.
+//
+// @jsxImportSource @emotion/react
+
+import React from 'react'
+import DockContainer from './DockContainer';
+import DockItem, { DockItemProps } from './DockItem';
+import { DockDirection } from './types';
+
+export type DockedReactNode = [ DockDirection, React.ReactNode ];
+export interface RelocationInfo {
+ index: number,
+ dock: DockDirection,
+}
+
+export interface DockManagerProps {
+ dockedNodes: DockedReactNode[],
+}
+
+export default ({ dockedNodes }: DockManagerProps) => {
+ let topLineCount = 1;
+ let bottomLineCount = 1;
+ let leftLineCount = 1;
+ let rightLineCount = 1;
+
+ const mapChild = (dockedNode: DockedReactNode, index: number) => {
+ const [dock, child] = dockedNode;
+
+ const props: DockItemProps = {
+ rowStart: `top-${topLineCount}`,
+ rowEnd: `bottom-${bottomLineCount}`,
+ columnStart: `left-${leftLineCount}`,
+ columnEnd: `right-${rightLineCount}`,
+ dock,
+ };
+
+ let key: React.Key = index.toString(36);
+
+ if (child && typeof child === 'object' && 'props' in child) {
+ switch (dock) {
+ case 'Top': {
+ ++topLineCount;
+ props.rowEnd = `top-${topLineCount}`;
+ break;
+ }
+
+ case 'Bottom': {
+ ++bottomLineCount;
+ props.rowStart = `bottom-${bottomLineCount}`;
+ break;
+ }
+
+ case 'Left': {
+ ++leftLineCount;
+ props.columnEnd = `left-${leftLineCount}`;
+ break;
+ }
+
+ case 'Right': {
+ ++rightLineCount;
+ props.columnStart = `right-${rightLineCount}`;
+ break;
+ }
+
+ default: {
+ break;
+ }
+ }
+
+ if (child.key) {
+ key = child.key;
+ }
+ }
+
+ return
{child}
+ }
+
+ const wrappedChildren = dockedNodes.map(mapChild);
+
+ const topLines = [...Array(topLineCount + 1).keys()].slice(1).map(num => `[top-${num}]`);
+ const bottomLines = [...Array(bottomLineCount + 1).keys()].slice(1).reverse().map(num => `[bottom-${num}]`);
+ const leftLines = [...Array(leftLineCount + 1).keys()].slice(1).map(num => `[left-${num}]`);
+ const rightLines = [...Array(rightLineCount + 1).keys()].slice(1).reverse().map(num => `[right-${num}]`);
+
+ return (
+
+ {wrappedChildren}
+
+ );
+}
diff --git a/src/components/common/Dock/DockWrapper.tsx b/src/components/common/Dock/DockWrapper.tsx
index 1f9f5ba..002e6d6 100644
--- a/src/components/common/Dock/DockWrapper.tsx
+++ b/src/components/common/Dock/DockWrapper.tsx
@@ -4,8 +4,8 @@
//
// @jsxImportSource @emotion/react
-import { PropsWithChildren } from 'react';
+import React from 'react';
-export default ({ children }: PropsWithChildren) => (
+export default ({ children }: React.PropsWithChildren) => (
<>{children}>
);
diff --git a/src/components/common/Dock/index.ts b/src/components/common/Dock/index.ts
index a9fd34b..f81195a 100644
--- a/src/components/common/Dock/index.ts
+++ b/src/components/common/Dock/index.ts
@@ -6,4 +6,4 @@
export { default } from './Dock';
export { default as DockWrapper } from './DockWrapper';
-export type { DockAttachedDirectionProps, DockAttachedDelayProps, DockAttachedProps } from './types';
+export type { DockAttachedProps } from './types';
diff --git a/src/components/common/Dock/types.ts b/src/components/common/Dock/types.ts
index ee08e77..f454503 100644
--- a/src/components/common/Dock/types.ts
+++ b/src/components/common/Dock/types.ts
@@ -6,39 +6,16 @@
export type DockDirection = 'Top' | 'Bottom' | 'Left' | 'Right' | 'Fill';
-export interface DockAttachedDirectionProps {
- 'dock-top'?: boolean,
- 'dock-bottom'?: boolean,
- 'dock-left'?: boolean,
- 'dock-right'?: boolean,
- 'dock-fill'?: boolean,
-}
-
-export interface DockAttachedDelayProps {
- 'dock-showDelay'?: number,
- 'dock-hideDelay'?: number,
-}
+export const dockDirectionPropName = 'dock-direction';
-export interface DockAttachedProps extends DockAttachedDirectionProps, DockAttachedDelayProps {
+export interface DockAttachedProps {
+ 'dock-direction'?: DockDirection,
}
-export type DockAttachedDirectionProp = keyof DockAttachedDirectionProps;
-export type DockAttachedDelayProp = keyof DockAttachedDelayProps;
export type DockAttachedProp = keyof DockAttachedProps;
-export const defaultDockAttachedDirectionProps: Required
= {
- 'dock-top': false,
- 'dock-bottom': false,
- 'dock-left': false,
- 'dock-right': false,
- 'dock-fill': false,
-}
-
-export const dockAttachedDirectionProps = Object.getOwnPropertyNames(defaultDockAttachedDirectionProps) as DockAttachedDirectionProp[];
-
-export const defaultDockAttachedDelayProps: Required = {
- 'dock-showDelay': 0,
- 'dock-hideDelay': 0,
+const fullDockAttachedProps: DockAttachedProps = {
+ 'dock-direction': undefined,
}
-export const dockAttachedDelayProps = Object.getOwnPropertyNames(defaultDockAttachedDelayProps) as DockAttachedDelayProp[];
+export const dockAttachedProps = Object.getOwnPropertyNames(fullDockAttachedProps) as DockAttachedProps[];
diff --git a/src/components/common/FullscreenViewport.tsx b/src/components/common/FullscreenViewport.tsx
index b0f35c8..1f1407e 100644
--- a/src/components/common/FullscreenViewport.tsx
+++ b/src/components/common/FullscreenViewport.tsx
@@ -4,7 +4,7 @@
//
// @jsxImportSource @emotion/react
-import { PropsWithChildren } from 'react';
+import React from 'react';
import { CSSObject } from '@emotion/react';
import { Fill, FullScreen } from '../../styles/layout';
import { mergeStyles } from '../../styles/mergeStyles';
@@ -20,7 +20,7 @@ const fitContentStyle: CSSObject = mergeStyles(Fill, {
minHeight: 'fit-content',
});
-export default ({ children }: PropsWithChildren) => (
+export default ({ children }: React.PropsWithChildren) => (
{children}
diff --git a/src/components/common/ModalDialog.tsx b/src/components/common/ModalDialog.tsx
index 10ad449..904c36a 100644
--- a/src/components/common/ModalDialog.tsx
+++ b/src/components/common/ModalDialog.tsx
@@ -6,7 +6,7 @@
import { CSSObject } from '@emotion/react';
import FocusTrap from 'focus-trap-react';
-import { PropsWithChildren, useEffect } from 'react';
+import React from 'react';
import { Fill } from '../../styles/layout';
import { mergeStyles } from '../../styles/mergeStyles';
import { BackgroundColor, DimerColor } from '../../styles/themes';
@@ -48,7 +48,7 @@ const contentStyle: CSSObject = {
margin: '0.5rem',
}
-export default ({ onClose, children }: PropsWithChildren
) => {
+export default ({ onClose, children }: React.PropsWithChildren) => {
const closeOnEscapeKey = (e: KeyboardEvent) => {
if (e.key === 'Escape' && onClose) {
onClose();
@@ -64,7 +64,7 @@ export default ({ onClose, children }: PropsWithChildren) => {
window.removeEventListener('keydown', closeOnEscapeKey);
};
- useEffect(() => {
+ React.useEffect(() => {
addListener();
return removeListener;
}, []);
diff --git a/src/components/common/ModalDialogLink.tsx b/src/components/common/ModalDialogLink.tsx
index 328881c..6afb9d4 100644
--- a/src/components/common/ModalDialogLink.tsx
+++ b/src/components/common/ModalDialogLink.tsx
@@ -4,16 +4,16 @@
//
// @jsxImportSource @emotion/react
-import { PropsWithChildren, ReactNode } from 'react';
+import React from 'react';
import { Link, Outlet, Route, Routes } from 'react-router-dom';
import RoutedModalDialog from './RoutedModalDialog';
export interface ModalDialogLinkProps {
- content: ReactNode,
+ content: React.ReactNode,
to: string,
}
-export default ({ content, to, children }: PropsWithChildren) => {
+export default ({ content, to, children }: React.PropsWithChildren) => {
const dialog = {content};
return (
diff --git a/src/components/common/RoutedModalDialog.tsx b/src/components/common/RoutedModalDialog.tsx
index c975ab7..194ccd2 100644
--- a/src/components/common/RoutedModalDialog.tsx
+++ b/src/components/common/RoutedModalDialog.tsx
@@ -4,11 +4,11 @@
//
// @jsxImportSource @emotion/react
-import { PropsWithChildren } from 'react';
+import React from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import ModalDialog from './ModalDialog';
-export default ({ children }: PropsWithChildren) => {
+export default ({ children }: React.PropsWithChildren) => {
const navigate = useNavigate();
const location = useLocation();
const navigateBack = () => {
diff --git a/src/components/common/Toolbar.tsx b/src/components/common/Toolbar.tsx
index a0ee5f6..1e9d815 100644
--- a/src/components/common/Toolbar.tsx
+++ b/src/components/common/Toolbar.tsx
@@ -5,7 +5,7 @@
// @jsxImportSource @emotion/react
import { CSSObject } from '@emotion/react';
-import { PropsWithChildren } from 'react';
+import React from 'react';
const style: CSSObject = {
label: 'Toolbar-Main',
@@ -13,7 +13,7 @@ const style: CSSObject = {
flexDirection: 'row',
};
-export default ({ children }: PropsWithChildren) => (
+export default ({ children }: React.PropsWithChildren) => (
{children}
diff --git a/src/components/views/main/Footer.tsx b/src/components/views/main/Footer.tsx
index a212515..2a56a33 100644
--- a/src/components/views/main/Footer.tsx
+++ b/src/components/views/main/Footer.tsx
@@ -11,8 +11,8 @@ import VersionLabel from '../../specialized/VersionLabel';
export default () => (
);
diff --git a/src/components/views/main/MainView.tsx b/src/components/views/main/MainView.tsx
index dd064fd..c5d0371 100644
--- a/src/components/views/main/MainView.tsx
+++ b/src/components/views/main/MainView.tsx
@@ -5,15 +5,14 @@
// @jsxImportSource @emotion/react
import { CSSObject, Global } from '@emotion/react';
+import React from 'react';
import FullscreenViewport from '../../common/FullscreenViewport';
import Footer from './Footer';
import Header from './Header';
-import { Fill } from '../../../styles/layout';
-import { mergeStyles } from '../../../styles/mergeStyles';
import Toolbox from './Toolbox';
-import TileGalleryView from '../tileGallery/TileGalleryView';
-import Dock from '../../common/Dock';
-import DockWrapper from '../../common/Dock/DockWrapper';
+import DockManager from '../../common/Dock/DockManager';
+import Workspace from './Workspace';
+import { DockDirection } from '../../common/Dock/types';
const globalStyle : CSSObject = {
body: {
@@ -21,24 +20,22 @@ const globalStyle : CSSObject = {
},
};
-const MainStyle: CSSObject = mergeStyles(Fill, {
- label: 'MainView-Main',
-});
+type DockElement = [ DockDirection, React.ReactNode ];
-export default () => (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
-);
+const children: DockElement[] = [
+ ['Top', ],
+ ['Bottom', ],
+ ['Left', ],
+ ['Fill', ],
+];
+
+export default () => {
+ return (
+ <>
+
+
+
+
+ >
+ );
+};
diff --git a/src/components/views/main/Workspace.tsx b/src/components/views/main/Workspace.tsx
new file mode 100644
index 0000000..e2018e6
--- /dev/null
+++ b/src/components/views/main/Workspace.tsx
@@ -0,0 +1,23 @@
+// Copyright (c) Hubert Bukowski. All rights reserved.
+// Licensed under the MIT License.
+// See LICENSE file in the project root for full license information.
+//
+// @jsxImportSource @emotion/react
+
+import { CSSObject } from '@emotion/react';
+import { Fill } from '../../../styles/layout';
+import { mergeStyles } from '../../../styles/mergeStyles';
+import { DockWrapper } from '../../common/Dock';
+import TileGalleryView from '../tileGallery/TileGalleryView';
+
+const style: CSSObject = mergeStyles(Fill, {
+ label: 'Workspace-Main',
+});
+
+export default () => (
+
+
+
+
+
+);
diff --git a/src/emotion.d.tsx b/src/emotion.d.tsx
index 36a78c4..6333ee1 100644
--- a/src/emotion.d.tsx
+++ b/src/emotion.d.tsx
@@ -6,6 +6,7 @@
import '@emotion/react';
import type { Property } from 'csstype';
+import { DockDirection } from './components/common/Dock/types';
declare module '@emotion/react' {
export interface Theme {
@@ -17,12 +18,6 @@ declare module '@emotion/react' {
declare module 'react' {
export interface Attributes {
- 'dock-top'?: boolean,
- 'dock-bottom'?: boolean,
- 'dock-left'?: boolean,
- 'dock-right'?: boolean,
- 'dock-fill'?: boolean,
- 'dock-showDelay'?: number,
- 'dock-hideDelay'?: number,
+ 'dock-direction'?: DockDirection,
}
}
diff --git a/src/hooks/useThrottledState.ts b/src/hooks/useThrottledState.ts
index 096b297..b7104cd 100644
--- a/src/hooks/useThrottledState.ts
+++ b/src/hooks/useThrottledState.ts
@@ -4,14 +4,14 @@
//
// @jsxImportSource @emotion/react
-import { Dispatch, SetStateAction, useMemo, useRef, useState } from 'react';
+import React from 'react';
-export default (initialState: S | (() => S), timeout: number | ((value: S) => number)): [S, Dispatch>] => {
- const [value, setValue] = useState(initialState);
- const timeoutForCurrentState = useMemo(() => ((typeof timeout === 'function') ? timeout(value) : timeout), [value]);
- const timeoutId = useRef();
+export default (initialState: S | (() => S), timeout: number | ((value: S) => number)): [S, React.Dispatch>] => {
+ const [value, setValue] = React.useState(initialState);
+ const timeoutForCurrentState = React.useMemo(() => ((typeof timeout === 'function') ? timeout(value) : timeout), [value]);
+ const timeoutId = React.useRef();
- const setValueThrottled: Dispatch> = (action: SetStateAction) => {
+ const setValueThrottled: React.Dispatch> = (action: React.SetStateAction) => {
clearTimeout(timeoutId.current);
timeoutId.current = setTimeout(() => {
setValue(action);