Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

「WIP」:sparkles: feat: add Editor Layout new Components #107

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/DraggablePanel/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ export const useStyle = createStyles(({ token, css, cx }, prefix: string) => {
fixed: cx(
`${prefix}-fixed`,
css`
background: ${token.colorBgContainer};
overflow: hidden;
`,
),
Expand Down
14 changes: 14 additions & 0 deletions src/Layout/demos/basic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Layout } from '@ant-design/pro-editor';

export default () => {
return (
<Layout
style={{
maxWidth: '100%',
}}
leftPannel={{
children: <div>Left Pannel</div>,
}}
/>
);
};
164 changes: 164 additions & 0 deletions src/Layout/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import { DraggablePanel } from '@ant-design/pro-editor';
import { FlexProps, TabsProps } from 'antd';
import { Size } from 're-resizable';
import { ReactNode } from 'react';
import { Flexbox } from 'react-layout-kit';
import { ConfigProvider } from '../ConfigProvider';
import { getPrefixCls } from '../theme';
import { useStyle } from './style';

interface HeaderFooterSettings {
Icon?: ReactNode;
extra?: ReactNode;
flex?: FlexProps;
hide?: boolean;
render?: (props: HeaderFooterSettings) => ReactNode;
children?: ReactNode;
}

interface LayoutProps {
header?: HeaderFooterSettings;
footer?: HeaderFooterSettings;
leftPannel?: PannelSettings;
rightPannel?: PannelSettings;
bottomPannel?: PannelSettings;
centerPannel?: PannelSettings;
type?: string;
}

interface PannelSettings {
children: ReactNode | ReactNode[];
direction?: 'horizontal' | 'vertical';
tabs?: TabsProps;
icon?: ReactNode;
extra?: ReactNode;
hide?: boolean;
minWidth?: number;
minHeight?: number;
style?: React.CSSProperties;
className?: string;
}

const getPannelProps = (
index: number,
):
| {
placement: 'left' | 'right' | 'bottom';
className?: string;
defaultSize?: Partial<Size>;
}
| false => {
switch (['left', 'right', 'bottom', 'center'][index]) {
case 'left':
return {
placement: 'left',
defaultSize: {
width: '200',
},
};
case 'right':
return {
placement: 'right',
defaultSize: {
width: '200',
},
};
case 'bottom':
return {
placement: 'bottom',
defaultSize: {
height: '200',
},
};
case 'center':
return false;
default:
return false;
}
};

const BasicLayout = (props: LayoutProps) => {
const { header, footer, leftPannel, rightPannel, bottomPannel, centerPannel, type, ...rest } =
props;

const prefixCls = getPrefixCls('layout');
const { styles, cx } = useStyle(prefixCls);

const DraggablePanelRender = (props: PannelSettings, index: number) => {
const {
children = '',
className,
style,
minHeight = 200,
minWidth = 200,
...rest
} = props || {};
const pannelProps = getPannelProps(index);
if (!pannelProps) {
return (
<div className={cx(styles.centerPannel)}>
<div className={cx(styles.pannel, className)}>{children}</div>
</div>
);
}
const { placement } = pannelProps;
return (
<DraggablePanel
expandable={false}
style={{ border: 'none', ...style }}
placement={placement}
minHeight={minHeight}
minWidth={minWidth}
{...pannelProps}
{...rest}
>
<div className={cx(styles.pannel, className)}>{children}</div>
</DraggablePanel>
);
};

const [LeftPannelDom, RightPannelDom, BottomPannelDom, CenterPannelDom] = [
leftPannel,
rightPannel,
bottomPannel,
centerPannel,
].map(DraggablePanelRender);

const HeaderDom = (props: HeaderFooterSettings) => {
const { children, render } = props || {};
if (render) {
return render(props);
}
return <div className={styles.header}>{children}</div>;
};

const FooterDom = (props: HeaderFooterSettings) => {
const { children } = props || {};
return <div className={styles.footer}>{children}</div>;
};

return (
<>
<Flexbox className={styles.layout} {...rest}>
<HeaderDom />
<div className={styles.container}>
{LeftPannelDom}
{CenterPannelDom}
{RightPannelDom}
</div>
{BottomPannelDom}
<FooterDom />
</Flexbox>
</>
);
};

const WrapperLayout = (props) => {
return (
<ConfigProvider>
<BasicLayout {...props} />
</ConfigProvider>
);
};

export { WrapperLayout as Layout };
13 changes: 13 additions & 0 deletions src/Layout/index.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
title: Layout 基础布局
atomId: Layout
group: 基础组件
---

# Layout 基础布局

## 代码演示

### 基础用法

<code src="./demos/basic.tsx" ></code>
77 changes: 77 additions & 0 deletions src/Layout/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { STUDIO_UI_PREFIX, createStyles } from '../theme';

export const useStyle = createStyles(({ css, token, cx }, prefixCls: string) => {
return {
layout: cx(
prefixCls,
css`
height: 100vh;
width: 100vw;
background-color: ${token.colorBgContainer};
overflow: hidden;
border-radius: ${token.borderRadius}px;

.${STUDIO_UI_PREFIX}-draggable-panel {
border: none;
}
`,
),
header: cx(
`${prefixCls}-header`,
css`
height: 48px;
border-radius: ${token.borderRadius}px;
background-color: ${token.colorFillQuaternary};
margin-bottom: ${token.margin / 4}px;
`,
),
footer: cx(
`${prefixCls}-footer`,
css`
height: 28px;
width: 100%;
margin-top: ${token.margin / 4}px;
background-color: ${token.colorFillQuaternary};
`,
),

centerPannel: cx(
`${prefixCls}-center-pannel`,
css`
flex: 1;

.${prefixCls}-pannel {
height: calc(100% - ${token.margin / 2 + 1}px);
width: calc(100% - ${token.margin / 2 - 2}px);
margin: ${token.margin / 4 + 2}px ${token.margin / 4 - 1}px;
}
`,
),

container: cx(
`${prefixCls}-container`,
css`
flex: 1;
display: flex;
`,
),
pannel: cx(
`${prefixCls}-pannel`,
css`
border-radius: ${token.borderRadius}px;
background-color: ${token.colorFillQuaternary};
margin: ${token.margin / 4 + 2}px;
height: calc(100% - ${token.margin / 2 + 1}px);
width: calc(100% - ${token.margin / 2 + 1}px);
`,
),
tip: cx(
`${prefixCls}-tip`,
css`
position: absolute;
left: 50%;
transform: translate(-50%);
`,
),
};
});
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ export * from './Highlight';
export * from './IconPicker';
export { default as InteractContainer } from './InteractContainer';
export type { CanvasInteractRule, InteractStatus, InteractStatusNode } from './InteractContainer';
export { Layout } from './Layout';
export { default as LevaPanel } from './LevaPanel';
export type { LevaPanelProps } from './LevaPanel';
export { default as Markdown, type MarkdownProps } from './Markdown';
export * from './ProBuilder';
export * from './Snippet';
export * from './ProEditor';
export * from './Snippet';
export * from './SortableList';
export * from './SortableTree';
export { default as TipGuide } from './TipGuide';
Expand Down
Loading