Skip to content

Commit daa84cb

Browse files
committed
fix: fix ref issue.
1 parent c9cda99 commit daa84cb

File tree

8 files changed

+216
-97
lines changed

8 files changed

+216
-97
lines changed

core/README-zh.md

Lines changed: 72 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ import Layout from '@uiw/react-layout';
2121
const { Header, Footer, Sider, Content } = Layout;
2222
// or
2323
import Layout, { LayoutHeader, LayoutContent, LayoutSider, LayoutFooter } from '@uiw/react-layout';
24-
Layout.Header = LayoutHeader
25-
Layout.Content = LayoutContent
26-
Layout.Sider = LayoutSider
27-
Layout.Footer = LayoutFooter
24+
25+
Layout.Header === LayoutHeader
26+
Layout.Content === LayoutContent
27+
Layout.Sider === LayoutSider
28+
Layout.Footer === LayoutFooter
2829
```
2930

3031
## 基本用法
@@ -148,6 +149,54 @@ export default Demo;
148149
| hasSider | 表示子元素里有 Sider,一般不用指定。可用于服务端渲染时避免样式闪动 | boolean | - |
149150
<!-- | theme | 主题颜色 | `light`、`dark` | `dark` | -->
150151

152+
## Header
153+
154+
```ts
155+
import Layout, { LayoutHeader } from '@uiw/react-layout';
156+
Layout.Header === LayoutHeader
157+
```
158+
159+
```ts
160+
import React from 'react';
161+
export interface LayoutHeaderProps extends React.HTMLAttributes<HTMLElement> {
162+
prefixCls?: string;
163+
children?: React.ReactNode;
164+
}
165+
export declare const LayoutHeader: React.ForwardRefExoticComponent<LayoutHeaderProps & React.RefAttributes<HTMLElement>>;
166+
```
167+
168+
## Content
169+
170+
```ts
171+
import Layout, { LayoutContent } from '@uiw/react-layout';
172+
Layout.Content === LayoutContent
173+
```
174+
175+
```ts
176+
import React from 'react';
177+
export interface LayoutContentProps extends React.HTMLAttributes<HTMLElement> {
178+
prefixCls?: string;
179+
children?: React.ReactNode;
180+
}
181+
export declare const LayoutContent: React.ForwardRefExoticComponent<LayoutContentProps & React.RefAttributes<HTMLElement>>;
182+
```
183+
184+
## Footer
185+
186+
```ts
187+
import Layout, { LayoutFooter } from '@uiw/react-layout';
188+
Layout.Footer === LayoutFooter
189+
```
190+
191+
```ts
192+
import React from 'react';
193+
export interface LayoutFooterProps extends React.HTMLAttributes<HTMLElement> {
194+
prefixCls?: string;
195+
children?: React.ReactNode;
196+
}
197+
export declare const LayoutFooter: React.ForwardRefExoticComponent<LayoutFooterProps & React.RefAttributes<HTMLElement>>;
198+
```
199+
151200
## Layout.Sider
152201

153202
| 参数 | 说明 | 类型 | 默认值 |
@@ -158,16 +207,23 @@ export default Demo;
158207
| collapsedWidth | 收缩宽度,设置为 `0` | boolean | `80` |
159208
| width | 宽度 | number/string | 200 |
160209

161-
## Contributors
162-
163-
As always, thanks to our amazing contributors!
164-
165-
<a href="https://github.com/jaywcjlove/github-action-contributors/graphs/contributors">
166-
<img src="https://jaywcjlove.github.io/github-action-contributors/CONTRIBUTORS.svg" />
167-
</a>
168-
169-
Made with [github-action-contributors](https://github.com/jaywcjlove/github-action-contributors).
170-
171-
### License
210+
```ts
211+
import Layout, { LayoutSider } from '@uiw/react-layout';
212+
Layout.Sider === LayoutSider
213+
```
172214

173-
Licensed under the MIT License.
215+
```ts
216+
import React from 'react';
217+
export declare function randomid(): string;
218+
export interface LayoutSiderProps extends React.HTMLAttributes<HTMLElement> {
219+
prefixCls?: string;
220+
children?: React.ReactNode;
221+
/** Width of the sidebar */
222+
width?: number | string;
223+
/** Width of the collapsed sidebar, by setting to 0 a special trigger will appear */
224+
collapsedWidth?: number;
225+
/** To set the current status */
226+
collapsed?: boolean;
227+
}
228+
export declare const LayoutSider: React.ForwardRefExoticComponent<LayoutSiderProps & React.RefAttributes<HTMLDivElement>>;
229+
```

core/README.md

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ import Layout from '@uiw/react-layout';
2323
const { Header, Footer, Sider, Content } = Layout;
2424
// or
2525
import Layout, { LayoutHeader, LayoutContent, LayoutSider, LayoutFooter } from '@uiw/react-layout';
26-
Layout.Header = LayoutHeader
27-
Layout.Content = LayoutContent
28-
Layout.Sider = LayoutSider
29-
Layout.Footer = LayoutFooter
26+
27+
Layout.Header === LayoutHeader
28+
Layout.Content === LayoutContent
29+
Layout.Sider === LayoutSider
30+
Layout.Footer === LayoutFooter
3031
```
3132

3233
## Basic Usage
@@ -150,7 +151,55 @@ The layout wrapper, in which `Header` `Sider` `Content` `Footer` or `Layout` its
150151
| hasSider | hasSider Whether contain Sider in children, don't have to assign it normally. Useful in ssr avoid style flickering | boolean | - |
151152
<!-- | theme | Color theme of the sidebar | `light`、`dark` | `dark` | -->
152153

153-
## Layout.Sider
154+
## Header
155+
156+
```ts
157+
import Layout, { LayoutHeader } from '@uiw/react-layout';
158+
Layout.Header === LayoutHeader
159+
```
160+
161+
```ts
162+
import React from 'react';
163+
export interface LayoutHeaderProps extends React.HTMLAttributes<HTMLElement> {
164+
prefixCls?: string;
165+
children?: React.ReactNode;
166+
}
167+
export declare const LayoutHeader: React.ForwardRefExoticComponent<LayoutHeaderProps & React.RefAttributes<HTMLElement>>;
168+
```
169+
170+
## Content
171+
172+
```ts
173+
import Layout, { LayoutContent } from '@uiw/react-layout';
174+
Layout.Content === LayoutContent
175+
```
176+
177+
```ts
178+
import React from 'react';
179+
export interface LayoutContentProps extends React.HTMLAttributes<HTMLElement> {
180+
prefixCls?: string;
181+
children?: React.ReactNode;
182+
}
183+
export declare const LayoutContent: React.ForwardRefExoticComponent<LayoutContentProps & React.RefAttributes<HTMLElement>>;
184+
```
185+
186+
## Footer
187+
188+
```ts
189+
import Layout, { LayoutFooter } from '@uiw/react-layout';
190+
Layout.Footer === LayoutFooter
191+
```
192+
193+
```ts
194+
import React from 'react';
195+
export interface LayoutFooterProps extends React.HTMLAttributes<HTMLElement> {
196+
prefixCls?: string;
197+
children?: React.ReactNode;
198+
}
199+
export declare const LayoutFooter: React.ForwardRefExoticComponent<LayoutFooterProps & React.RefAttributes<HTMLElement>>;
200+
```
201+
202+
## Sider
154203

155204
| Property | Description | Type | Default |
156205
|--------- |-------- |--------- |-------- |
@@ -160,6 +209,27 @@ The layout wrapper, in which `Header` `Sider` `Content` `Footer` or `Layout` its
160209
| collapsedWidth | Width of the collapsed sidebar, by setting to 0 a special trigger will appear | boolean | `80` |
161210
| width | Width of the sidebar | number/string | 200 |
162211

212+
```ts
213+
import Layout, { LayoutSider } from '@uiw/react-layout';
214+
Layout.Sider === LayoutSider
215+
```
216+
217+
```ts
218+
import React from 'react';
219+
export declare function randomid(): string;
220+
export interface LayoutSiderProps extends React.HTMLAttributes<HTMLElement> {
221+
prefixCls?: string;
222+
children?: React.ReactNode;
223+
/** Width of the sidebar */
224+
width?: number | string;
225+
/** Width of the collapsed sidebar, by setting to 0 a special trigger will appear */
226+
collapsedWidth?: number;
227+
/** To set the current status */
228+
collapsed?: boolean;
229+
}
230+
export declare const LayoutSider: React.ForwardRefExoticComponent<LayoutSiderProps & React.RefAttributes<HTMLDivElement>>;
231+
```
232+
163233
## Contributors
164234

165235
As always, thanks to our amazing contributors!

core/src/Content.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ export interface LayoutContentProps extends React.HTMLAttributes<HTMLElement> {
55
children?: React.ReactNode;
66
}
77

8-
export function LayoutContent(props: LayoutContentProps) {
8+
export const LayoutContent = React.forwardRef<HTMLElement, LayoutContentProps>((props, ref) => {
99
const { prefixCls = 'w-layout-content', className, children, ...other } = props;
10+
const cls = [prefixCls, className].filter(Boolean).join(' ').trim();
1011
return (
11-
<main className={[prefixCls, className].filter(Boolean).join(' ').trim()} {...other}>
12+
<main ref={ref} className={cls} {...other}>
1213
{children}
1314
</main>
1415
);
15-
}
16+
});

core/src/Footer.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ export interface LayoutFooterProps extends React.HTMLAttributes<HTMLElement> {
55
children?: React.ReactNode;
66
}
77

8-
export function LayoutFooter(props: LayoutFooterProps) {
8+
export const LayoutFooter = React.forwardRef<HTMLElement, LayoutFooterProps>((props, ref) => {
99
const { prefixCls = 'w-layout-footer', className, children, ...other } = props;
10+
const cls = [prefixCls, className].filter(Boolean).join(' ').trim();
1011
return (
11-
<footer className={[prefixCls, className].filter(Boolean).join(' ').trim()} {...other}>
12+
<footer ref={ref} className={cls} {...other}>
1213
{children}
1314
</footer>
1415
);
15-
}
16+
});

core/src/Header.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ export interface LayoutHeaderProps extends React.HTMLAttributes<HTMLElement> {
55
children?: React.ReactNode;
66
}
77

8-
export function LayoutHeader(props: LayoutHeaderProps) {
8+
export const LayoutHeader = React.forwardRef<HTMLElement, LayoutHeaderProps>((props, ref) => {
99
const { prefixCls = 'w-layout-header', className, children, ...other } = props || {};
10+
const cls = [prefixCls, className].filter(Boolean).join(' ').trim();
1011
return (
11-
<header className={[prefixCls, className].filter(Boolean).join(' ').trim()} {...other}>
12+
<header ref={ref} className={cls} {...other}>
1213
{children}
1314
</header>
1415
);
15-
}
16+
});

core/src/Layout.tsx

Lines changed: 40 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
1-
import React from 'react';
1+
import React, { useState } from 'react';
22
import { LayoutHeader } from './Header';
33
import { LayoutSider } from './Sider';
44
import { LayoutFooter } from './Footer';
55
import { LayoutContent } from './Content';
66

77
export interface LayoutContextProps {
8-
siderHook: {
9-
addSider: (id: string) => void;
10-
removeSider: (id: string) => void;
11-
};
8+
addSider: (id: string) => void;
9+
removeSider: (id: string) => void;
1210
}
11+
1312
export const LayoutContext = React.createContext<LayoutContextProps>({
14-
siderHook: {
15-
addSider: () => null,
16-
removeSider: () => null,
17-
},
13+
addSider: () => null,
14+
removeSider: () => null,
1815
});
1916

2017
export interface LayoutProps extends React.HTMLAttributes<HTMLElement> {
@@ -25,49 +22,38 @@ export interface LayoutState {
2522
siders: string[];
2623
}
2724

28-
export default class Layout extends React.Component<LayoutProps, LayoutState> {
29-
static Header: typeof LayoutHeader;
30-
static Footer: typeof LayoutFooter;
31-
static Sider: typeof LayoutSider;
32-
static Content: typeof LayoutContent;
33-
public static defaultProps: LayoutProps = {
34-
prefixCls: 'w-layout',
25+
const Layout = React.forwardRef<HTMLElement, LayoutProps>((props, ref) => {
26+
const { prefixCls = 'w-layout', className, hasSider, children, ...other } = props;
27+
const [siders, setSiders] = useState<string[]>([]);
28+
const addSider = (id: string) => {
29+
setSiders((state) => [...state, id]);
3530
};
36-
state = { siders: [] };
37-
getSiderHook() {
38-
return {
39-
addSider: (id: string) => {
40-
this.setState((state) => ({
41-
siders: [...state.siders, id],
42-
}));
43-
},
44-
removeSider: (id: string) => {
45-
this.setState((state) => ({
46-
siders: state.siders.filter((currentId) => currentId !== id),
47-
}));
48-
},
49-
};
50-
}
51-
render() {
52-
const { prefixCls, className, hasSider, children, ...other } = this.props;
53-
return (
54-
<LayoutContext.Provider value={{ siderHook: this.getSiderHook() }}>
55-
<section
56-
className={[
57-
prefixCls,
58-
className,
59-
(typeof hasSider === 'boolean' && hasSider) || this.state.siders.length > 0
60-
? `${prefixCls}-has-sider`
61-
: null,
62-
]
63-
.filter(Boolean)
64-
.join(' ')
65-
.trim()}
66-
{...other}
67-
>
68-
{children}
69-
</section>
70-
</LayoutContext.Provider>
71-
);
72-
}
73-
}
31+
const removeSider = (id: string) => {
32+
setSiders((state) => [...state.filter((currentId) => currentId !== id)]);
33+
};
34+
const cls = [
35+
prefixCls,
36+
className,
37+
(typeof hasSider === 'boolean' && hasSider) || siders.length > 0 ? `${prefixCls}-has-sider` : null,
38+
]
39+
.filter(Boolean)
40+
.join(' ')
41+
.trim();
42+
return (
43+
<LayoutContext.Provider value={{ addSider, removeSider }}>
44+
<section ref={ref} className={cls} {...other}>
45+
{children}
46+
</section>
47+
</LayoutContext.Provider>
48+
);
49+
});
50+
51+
type LoginComponent = typeof Layout & {
52+
Header: typeof LayoutHeader;
53+
Footer: typeof LayoutFooter;
54+
Sider: typeof LayoutSider;
55+
Content: typeof LayoutContent;
56+
};
57+
Layout.displayName = 'Layout';
58+
59+
export default Layout as LoginComponent;

0 commit comments

Comments
 (0)