@refinedev/antd 5.1.1 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +77 -0
- package/dist/components/buttons/create/index.d.ts.map +1 -1
- package/dist/components/crud/show/index.d.ts.map +1 -1
- package/dist/components/index.d.ts +5 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/pages/auth/components/forgotPassword/index.d.ts.map +1 -1
- package/dist/components/pages/auth/components/login/index.d.ts.map +1 -1
- package/dist/components/pages/auth/components/register/index.d.ts.map +1 -1
- package/dist/components/pages/auth/components/styles.d.ts +2 -0
- package/dist/components/pages/auth/components/styles.d.ts.map +1 -1
- package/dist/components/pages/auth/components/updatePassword/index.d.ts.map +1 -1
- package/dist/components/pages/auth/index.d.ts +4 -1
- package/dist/components/pages/auth/index.d.ts.map +1 -1
- package/dist/components/themedLayout/header/index.d.ts +4 -0
- package/dist/components/themedLayout/header/index.d.ts.map +1 -0
- package/dist/components/themedLayout/index.d.ts +4 -0
- package/dist/components/themedLayout/index.d.ts.map +1 -0
- package/dist/components/themedLayout/sider/index.d.ts +4 -0
- package/dist/components/themedLayout/sider/index.d.ts.map +1 -0
- package/dist/components/themedLayout/sider/styles.d.ts +3 -0
- package/dist/components/themedLayout/sider/styles.d.ts.map +1 -0
- package/dist/components/themedLayout/title/index.d.ts +4 -0
- package/dist/components/themedLayout/title/index.d.ts.map +1 -0
- package/dist/components/themedLayout/types.d.ts +3 -0
- package/dist/components/themedLayout/types.d.ts.map +1 -0
- package/dist/definitions/index.d.ts +1 -0
- package/dist/definitions/index.d.ts.map +1 -1
- package/dist/definitions/themes/index.d.ts +6 -0
- package/dist/definitions/themes/index.d.ts.map +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/iife/index.js +4 -4
- package/dist/iife/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/refine.config.js +96 -0
- package/src/components/buttons/create/index.tsx +1 -0
- package/src/components/crud/show/index.tsx +1 -0
- package/src/components/index.ts +6 -0
- package/src/components/pages/auth/components/forgotPassword/index.tsx +53 -7
- package/src/components/pages/auth/components/login/index.tsx +61 -10
- package/src/components/pages/auth/components/register/index.tsx +63 -11
- package/src/components/pages/auth/components/styles.ts +14 -7
- package/src/components/pages/auth/components/updatePassword/index.tsx +51 -7
- package/src/components/pages/auth/index.tsx +7 -1
- package/src/components/themedLayout/header/index.tsx +44 -0
- package/src/components/themedLayout/index.tsx +41 -0
- package/src/components/themedLayout/sider/index.tsx +296 -0
- package/src/components/themedLayout/sider/styles.ts +9 -0
- package/src/components/themedLayout/title/index.tsx +81 -0
- package/src/components/themedLayout/types.ts +13 -0
- package/src/definitions/index.ts +1 -0
- package/src/definitions/themes/index.ts +50 -0
- package/src/index.tsx +2 -0
@@ -16,12 +16,21 @@ import {
|
|
16
16
|
LayoutProps,
|
17
17
|
CardProps,
|
18
18
|
FormProps,
|
19
|
+
theme,
|
19
20
|
} from "antd";
|
20
21
|
import { useTranslate, useUpdatePassword } from "@refinedev/core";
|
21
22
|
|
22
|
-
import {
|
23
|
+
import {
|
24
|
+
layoutStyles,
|
25
|
+
containerStyles,
|
26
|
+
titleStyles,
|
27
|
+
headStyles,
|
28
|
+
bodyStyles,
|
29
|
+
} from "../styles";
|
30
|
+
import { ThemedTitle } from "@components";
|
23
31
|
|
24
32
|
const { Title } = Typography;
|
33
|
+
const { useToken } = theme;
|
25
34
|
|
26
35
|
type UpdatePasswordProps = UpdatePasswordPageProps<
|
27
36
|
LayoutProps,
|
@@ -39,7 +48,9 @@ export const UpdatePasswordPage: React.FC<UpdatePasswordProps> = ({
|
|
39
48
|
contentProps,
|
40
49
|
renderContent,
|
41
50
|
formProps,
|
51
|
+
title,
|
42
52
|
}) => {
|
53
|
+
const { token } = useToken();
|
43
54
|
const [form] = Form.useForm<UpdatePasswordFormTypes>();
|
44
55
|
const translate = useTranslate();
|
45
56
|
const authProvider = useActiveAuthProvider();
|
@@ -48,8 +59,27 @@ export const UpdatePasswordPage: React.FC<UpdatePasswordProps> = ({
|
|
48
59
|
v3LegacyAuthProviderCompatible: Boolean(authProvider?.isLegacy),
|
49
60
|
});
|
50
61
|
|
62
|
+
const PageTitle =
|
63
|
+
title === false ? null : (
|
64
|
+
<div
|
65
|
+
style={{
|
66
|
+
display: "flex",
|
67
|
+
justifyContent: "center",
|
68
|
+
marginBottom: "32px",
|
69
|
+
}}
|
70
|
+
>
|
71
|
+
{title ?? <ThemedTitle collapsed={false} />}
|
72
|
+
</div>
|
73
|
+
);
|
74
|
+
|
51
75
|
const CardTitle = (
|
52
|
-
<Title
|
76
|
+
<Title
|
77
|
+
level={3}
|
78
|
+
style={{
|
79
|
+
color: token.colorPrimaryTextHover,
|
80
|
+
...titleStyles,
|
81
|
+
}}
|
82
|
+
>
|
53
83
|
{translate("pages.updatePassword.title", "Set New Password")}
|
54
84
|
</Title>
|
55
85
|
);
|
@@ -57,8 +87,12 @@ export const UpdatePasswordPage: React.FC<UpdatePasswordProps> = ({
|
|
57
87
|
const CardContent = (
|
58
88
|
<Card
|
59
89
|
title={CardTitle}
|
60
|
-
headStyle={
|
61
|
-
|
90
|
+
headStyle={headStyles}
|
91
|
+
bodyStyle={bodyStyles}
|
92
|
+
style={{
|
93
|
+
...containerStyles,
|
94
|
+
backgroundColor: token.colorBgElevated,
|
95
|
+
}}
|
62
96
|
{...(contentProps ?? {})}
|
63
97
|
>
|
64
98
|
<Form<UpdatePasswordFormTypes>
|
@@ -114,7 +148,6 @@ export const UpdatePasswordPage: React.FC<UpdatePasswordProps> = ({
|
|
114
148
|
},
|
115
149
|
}),
|
116
150
|
]}
|
117
|
-
style={{ marginBottom: "12px" }}
|
118
151
|
>
|
119
152
|
<Input
|
120
153
|
type="password"
|
@@ -122,7 +155,11 @@ export const UpdatePasswordPage: React.FC<UpdatePasswordProps> = ({
|
|
122
155
|
size="large"
|
123
156
|
/>
|
124
157
|
</Form.Item>
|
125
|
-
<Form.Item
|
158
|
+
<Form.Item
|
159
|
+
style={{
|
160
|
+
marginBottom: 0,
|
161
|
+
}}
|
162
|
+
>
|
126
163
|
<Button
|
127
164
|
type="primary"
|
128
165
|
size="large"
|
@@ -150,7 +187,14 @@ export const UpdatePasswordPage: React.FC<UpdatePasswordProps> = ({
|
|
150
187
|
}}
|
151
188
|
>
|
152
189
|
<Col xs={22}>
|
153
|
-
{renderContent ?
|
190
|
+
{renderContent ? (
|
191
|
+
renderContent(CardContent, PageTitle)
|
192
|
+
) : (
|
193
|
+
<>
|
194
|
+
{PageTitle}
|
195
|
+
{CardContent}
|
196
|
+
</>
|
197
|
+
)}
|
154
198
|
</Col>
|
155
199
|
</Row>
|
156
200
|
</Layout>
|
@@ -9,7 +9,13 @@ import {
|
|
9
9
|
UpdatePasswordPage,
|
10
10
|
} from "./components";
|
11
11
|
|
12
|
-
export type AuthProps = AuthPageProps<LayoutProps, CardProps, FormProps
|
12
|
+
export type AuthProps = AuthPageProps<LayoutProps, CardProps, FormProps> & {
|
13
|
+
renderContent?: (
|
14
|
+
content: React.ReactNode,
|
15
|
+
title: React.ReactNode,
|
16
|
+
) => React.ReactNode;
|
17
|
+
title?: React.ReactNode;
|
18
|
+
};
|
13
19
|
|
14
20
|
/**
|
15
21
|
* **refine** has a default auth page form served on the `/login` route when the `authProvider` configuration is provided.
|
@@ -0,0 +1,44 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import { Layout as AntdLayout, Typography, Avatar, Space, theme } from "antd";
|
3
|
+
import { useActiveAuthProvider, useGetIdentity } from "@refinedev/core";
|
4
|
+
import { RefineThemedLayoutHeaderProps } from "../types";
|
5
|
+
|
6
|
+
const { Text } = Typography;
|
7
|
+
const { useToken } = theme;
|
8
|
+
|
9
|
+
export const ThemedHeader: React.FC<RefineThemedLayoutHeaderProps> = () => {
|
10
|
+
const { token } = useToken();
|
11
|
+
|
12
|
+
const authProvider = useActiveAuthProvider();
|
13
|
+
const { data: user } = useGetIdentity({
|
14
|
+
v3LegacyAuthProviderCompatible: Boolean(authProvider?.isLegacy),
|
15
|
+
});
|
16
|
+
|
17
|
+
const shouldRenderHeader = user && (user.name || user.avatar);
|
18
|
+
|
19
|
+
if (!shouldRenderHeader) {
|
20
|
+
return null;
|
21
|
+
}
|
22
|
+
|
23
|
+
return (
|
24
|
+
<AntdLayout.Header
|
25
|
+
style={{
|
26
|
+
backgroundColor: token.colorBgElevated,
|
27
|
+
display: "flex",
|
28
|
+
justifyContent: "flex-end",
|
29
|
+
alignItems: "center",
|
30
|
+
padding: "0px 24px",
|
31
|
+
height: "64px",
|
32
|
+
}}
|
33
|
+
>
|
34
|
+
<Space>
|
35
|
+
<Space size="middle">
|
36
|
+
{user?.name && <Text strong>{user.name}</Text>}
|
37
|
+
{user?.avatar && (
|
38
|
+
<Avatar src={user?.avatar} alt={user?.name} />
|
39
|
+
)}
|
40
|
+
</Space>
|
41
|
+
</Space>
|
42
|
+
</AntdLayout.Header>
|
43
|
+
);
|
44
|
+
};
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import { Grid, Layout as AntdLayout } from "antd";
|
3
|
+
|
4
|
+
import { ThemedSider as DefaultSider } from "./sider";
|
5
|
+
import { ThemedHeader as DefaultHeader } from "./header";
|
6
|
+
import { RefineThemedLayoutProps } from "./types";
|
7
|
+
|
8
|
+
export const ThemedLayout: React.FC<RefineThemedLayoutProps> = ({
|
9
|
+
children,
|
10
|
+
Header,
|
11
|
+
Sider,
|
12
|
+
Title,
|
13
|
+
Footer,
|
14
|
+
OffLayoutArea,
|
15
|
+
}) => {
|
16
|
+
const breakpoint = Grid.useBreakpoint();
|
17
|
+
const SiderToRender = Sider ?? DefaultSider;
|
18
|
+
const HeaderToRender = Header ?? DefaultHeader;
|
19
|
+
const isSmall = typeof breakpoint.sm === "undefined" ? true : breakpoint.sm;
|
20
|
+
|
21
|
+
return (
|
22
|
+
<AntdLayout style={{ minHeight: "100vh" }}>
|
23
|
+
<SiderToRender Title={Title} />
|
24
|
+
<AntdLayout>
|
25
|
+
<HeaderToRender />
|
26
|
+
<AntdLayout.Content>
|
27
|
+
<div
|
28
|
+
style={{
|
29
|
+
minHeight: 360,
|
30
|
+
padding: isSmall ? 24 : 12,
|
31
|
+
}}
|
32
|
+
>
|
33
|
+
{children}
|
34
|
+
</div>
|
35
|
+
{OffLayoutArea && <OffLayoutArea />}
|
36
|
+
</AntdLayout.Content>
|
37
|
+
{Footer && <Footer />}
|
38
|
+
</AntdLayout>
|
39
|
+
</AntdLayout>
|
40
|
+
);
|
41
|
+
};
|
@@ -0,0 +1,296 @@
|
|
1
|
+
import React, { useState } from "react";
|
2
|
+
import { Layout, Menu, Grid, Drawer, Button, theme } from "antd";
|
3
|
+
import {
|
4
|
+
DashboardOutlined,
|
5
|
+
LogoutOutlined,
|
6
|
+
UnorderedListOutlined,
|
7
|
+
BarsOutlined,
|
8
|
+
LeftOutlined,
|
9
|
+
RightOutlined,
|
10
|
+
} from "@ant-design/icons";
|
11
|
+
import {
|
12
|
+
useTranslate,
|
13
|
+
useLogout,
|
14
|
+
useTitle,
|
15
|
+
CanAccess,
|
16
|
+
ITreeMenu,
|
17
|
+
useIsExistAuthentication,
|
18
|
+
useRouterContext,
|
19
|
+
useMenu,
|
20
|
+
useRefineContext,
|
21
|
+
useLink,
|
22
|
+
useRouterType,
|
23
|
+
useActiveAuthProvider,
|
24
|
+
pickNotDeprecated,
|
25
|
+
} from "@refinedev/core";
|
26
|
+
|
27
|
+
import { drawerButtonStyles } from "./styles";
|
28
|
+
import { RefineThemedLayoutSiderProps } from "../types";
|
29
|
+
import { ThemedTitle } from "@components";
|
30
|
+
|
31
|
+
const { SubMenu } = Menu;
|
32
|
+
const { useToken } = theme;
|
33
|
+
|
34
|
+
export const ThemedSider: React.FC<RefineThemedLayoutSiderProps> = ({
|
35
|
+
Title: TitleFromProps,
|
36
|
+
render,
|
37
|
+
meta,
|
38
|
+
}) => {
|
39
|
+
const { token } = useToken();
|
40
|
+
|
41
|
+
const [collapsed, setCollapsed] = useState<boolean>(false);
|
42
|
+
const [drawerOpen, setDrawerOpen] = useState<boolean>(false);
|
43
|
+
const isExistAuthentication = useIsExistAuthentication();
|
44
|
+
const routerType = useRouterType();
|
45
|
+
const NewLink = useLink();
|
46
|
+
const { Link: LegacyLink } = useRouterContext();
|
47
|
+
const Link = routerType === "legacy" ? LegacyLink : NewLink;
|
48
|
+
const TitleFromContext = useTitle();
|
49
|
+
const translate = useTranslate();
|
50
|
+
const { menuItems, selectedKey, defaultOpenKeys } = useMenu({ meta });
|
51
|
+
const breakpoint = Grid.useBreakpoint();
|
52
|
+
const { hasDashboard } = useRefineContext();
|
53
|
+
const authProvider = useActiveAuthProvider();
|
54
|
+
const { mutate: mutateLogout } = useLogout({
|
55
|
+
v3LegacyAuthProviderCompatible: Boolean(authProvider?.isLegacy),
|
56
|
+
});
|
57
|
+
|
58
|
+
const isMobile =
|
59
|
+
typeof breakpoint.lg === "undefined" ? false : !breakpoint.lg;
|
60
|
+
|
61
|
+
const RenderToTitle = TitleFromProps ?? TitleFromContext ?? ThemedTitle;
|
62
|
+
|
63
|
+
const renderTreeView = (tree: ITreeMenu[], selectedKey?: string) => {
|
64
|
+
return tree.map((item: ITreeMenu) => {
|
65
|
+
const {
|
66
|
+
icon,
|
67
|
+
label,
|
68
|
+
route,
|
69
|
+
key,
|
70
|
+
name,
|
71
|
+
children,
|
72
|
+
parentName,
|
73
|
+
meta,
|
74
|
+
options,
|
75
|
+
} = item;
|
76
|
+
|
77
|
+
if (children.length > 0) {
|
78
|
+
return (
|
79
|
+
<CanAccess
|
80
|
+
key={item.key}
|
81
|
+
resource={name.toLowerCase()}
|
82
|
+
action="list"
|
83
|
+
params={{
|
84
|
+
resource: item,
|
85
|
+
}}
|
86
|
+
>
|
87
|
+
<SubMenu
|
88
|
+
key={item.key}
|
89
|
+
icon={icon ?? <UnorderedListOutlined />}
|
90
|
+
title={label}
|
91
|
+
>
|
92
|
+
{renderTreeView(children, selectedKey)}
|
93
|
+
</SubMenu>
|
94
|
+
</CanAccess>
|
95
|
+
);
|
96
|
+
}
|
97
|
+
const isSelected = key === selectedKey;
|
98
|
+
const isRoute = !(
|
99
|
+
pickNotDeprecated(meta?.parent, options?.parent, parentName) !==
|
100
|
+
undefined && children.length === 0
|
101
|
+
);
|
102
|
+
|
103
|
+
return (
|
104
|
+
<CanAccess
|
105
|
+
key={item.key}
|
106
|
+
resource={name.toLowerCase()}
|
107
|
+
action="list"
|
108
|
+
params={{
|
109
|
+
resource: item,
|
110
|
+
}}
|
111
|
+
>
|
112
|
+
<Menu.Item
|
113
|
+
key={item.key}
|
114
|
+
icon={icon ?? (isRoute && <UnorderedListOutlined />)}
|
115
|
+
>
|
116
|
+
<Link to={route ?? ""}>{label}</Link>
|
117
|
+
{!collapsed && isSelected && (
|
118
|
+
<div className="ant-menu-tree-arrow" />
|
119
|
+
)}
|
120
|
+
</Menu.Item>
|
121
|
+
</CanAccess>
|
122
|
+
);
|
123
|
+
});
|
124
|
+
};
|
125
|
+
|
126
|
+
const logout = isExistAuthentication && (
|
127
|
+
<Menu.Item
|
128
|
+
key="logout"
|
129
|
+
onClick={() => mutateLogout()}
|
130
|
+
icon={<LogoutOutlined />}
|
131
|
+
>
|
132
|
+
{translate("buttons.logout", "Logout")}
|
133
|
+
</Menu.Item>
|
134
|
+
);
|
135
|
+
|
136
|
+
const dashboard = hasDashboard ? (
|
137
|
+
<Menu.Item key="dashboard" icon={<DashboardOutlined />}>
|
138
|
+
<Link to="/">{translate("dashboard.title", "Dashboard")}</Link>
|
139
|
+
{!collapsed && selectedKey === "/" && (
|
140
|
+
<div className="ant-menu-tree-arrow" />
|
141
|
+
)}
|
142
|
+
</Menu.Item>
|
143
|
+
) : null;
|
144
|
+
|
145
|
+
const items = renderTreeView(menuItems, selectedKey);
|
146
|
+
|
147
|
+
const renderSider = () => {
|
148
|
+
if (render) {
|
149
|
+
return render({
|
150
|
+
dashboard,
|
151
|
+
items,
|
152
|
+
logout,
|
153
|
+
collapsed,
|
154
|
+
});
|
155
|
+
}
|
156
|
+
return (
|
157
|
+
<>
|
158
|
+
{dashboard}
|
159
|
+
{items}
|
160
|
+
{logout}
|
161
|
+
</>
|
162
|
+
);
|
163
|
+
};
|
164
|
+
|
165
|
+
const renderMenu = () => {
|
166
|
+
return (
|
167
|
+
<>
|
168
|
+
<Menu
|
169
|
+
selectedKeys={selectedKey ? [selectedKey] : []}
|
170
|
+
defaultOpenKeys={defaultOpenKeys}
|
171
|
+
mode="inline"
|
172
|
+
style={{
|
173
|
+
marginTop: "8px",
|
174
|
+
border: "none",
|
175
|
+
}}
|
176
|
+
onClick={() => {
|
177
|
+
setDrawerOpen(false);
|
178
|
+
if (!breakpoint.lg) {
|
179
|
+
setCollapsed(true);
|
180
|
+
}
|
181
|
+
}}
|
182
|
+
>
|
183
|
+
{renderSider()}
|
184
|
+
</Menu>
|
185
|
+
</>
|
186
|
+
);
|
187
|
+
};
|
188
|
+
|
189
|
+
const renderDrawerSider = () => {
|
190
|
+
return (
|
191
|
+
<>
|
192
|
+
<Drawer
|
193
|
+
open={drawerOpen}
|
194
|
+
onClose={() => setDrawerOpen(false)}
|
195
|
+
placement="left"
|
196
|
+
closable={false}
|
197
|
+
width={200}
|
198
|
+
bodyStyle={{
|
199
|
+
padding: 0,
|
200
|
+
}}
|
201
|
+
maskClosable={true}
|
202
|
+
>
|
203
|
+
<Layout>
|
204
|
+
<Layout.Sider
|
205
|
+
style={{
|
206
|
+
height: "100vh",
|
207
|
+
overflow: "hidden",
|
208
|
+
backgroundColor: token.colorBgContainer,
|
209
|
+
borderRight: `1px solid ${token.colorBgElevated}`,
|
210
|
+
}}
|
211
|
+
>
|
212
|
+
<div
|
213
|
+
style={{
|
214
|
+
width: "200px",
|
215
|
+
padding: "0 16px",
|
216
|
+
display: "flex",
|
217
|
+
justifyContent: "flex-start",
|
218
|
+
alignItems: "center",
|
219
|
+
height: "64px",
|
220
|
+
backgroundColor: token.colorBgElevated,
|
221
|
+
}}
|
222
|
+
>
|
223
|
+
<RenderToTitle collapsed={false} />
|
224
|
+
</div>
|
225
|
+
{renderMenu()}
|
226
|
+
</Layout.Sider>
|
227
|
+
</Layout>
|
228
|
+
</Drawer>
|
229
|
+
<Button
|
230
|
+
style={drawerButtonStyles}
|
231
|
+
size="large"
|
232
|
+
onClick={() => setDrawerOpen(true)}
|
233
|
+
icon={<BarsOutlined />}
|
234
|
+
></Button>
|
235
|
+
</>
|
236
|
+
);
|
237
|
+
};
|
238
|
+
|
239
|
+
if (isMobile) {
|
240
|
+
return renderDrawerSider();
|
241
|
+
}
|
242
|
+
|
243
|
+
return (
|
244
|
+
<Layout.Sider
|
245
|
+
style={{
|
246
|
+
backgroundColor: token.colorBgContainer,
|
247
|
+
borderRight: `1px solid ${token.colorBgElevated}`,
|
248
|
+
}}
|
249
|
+
collapsible
|
250
|
+
collapsed={collapsed}
|
251
|
+
onCollapse={(collapsed) => setCollapsed(collapsed)}
|
252
|
+
collapsedWidth={80}
|
253
|
+
breakpoint="lg"
|
254
|
+
trigger={
|
255
|
+
<Button
|
256
|
+
type="text"
|
257
|
+
style={{
|
258
|
+
borderRadius: 0,
|
259
|
+
height: "100%",
|
260
|
+
width: "100%",
|
261
|
+
backgroundColor: token.colorBgElevated,
|
262
|
+
}}
|
263
|
+
>
|
264
|
+
{collapsed ? (
|
265
|
+
<RightOutlined
|
266
|
+
style={{
|
267
|
+
color: token.colorPrimary,
|
268
|
+
}}
|
269
|
+
/>
|
270
|
+
) : (
|
271
|
+
<LeftOutlined
|
272
|
+
style={{
|
273
|
+
color: token.colorPrimary,
|
274
|
+
}}
|
275
|
+
/>
|
276
|
+
)}
|
277
|
+
</Button>
|
278
|
+
}
|
279
|
+
>
|
280
|
+
<div
|
281
|
+
style={{
|
282
|
+
width: collapsed ? "80px" : "200px",
|
283
|
+
padding: collapsed ? "0" : "0 16px",
|
284
|
+
display: "flex",
|
285
|
+
justifyContent: collapsed ? "center" : "flex-start",
|
286
|
+
alignItems: "center",
|
287
|
+
height: "64px",
|
288
|
+
backgroundColor: token.colorBgElevated,
|
289
|
+
}}
|
290
|
+
>
|
291
|
+
<RenderToTitle collapsed={collapsed} />
|
292
|
+
</div>
|
293
|
+
{renderMenu()}
|
294
|
+
</Layout.Sider>
|
295
|
+
);
|
296
|
+
};
|
@@ -0,0 +1,81 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import { useRouterContext, useRouterType, useLink } from "@refinedev/core";
|
3
|
+
import { Typography, theme, Space } from "antd";
|
4
|
+
import { RefineLayoutThemedTitleProps } from "../types";
|
5
|
+
|
6
|
+
const { useToken } = theme;
|
7
|
+
|
8
|
+
const defaultText = "refine Project";
|
9
|
+
|
10
|
+
const defaultIcon = (
|
11
|
+
<svg
|
12
|
+
width="24"
|
13
|
+
height="24"
|
14
|
+
viewBox="0 0 24 24"
|
15
|
+
fill="none"
|
16
|
+
xmlns="http://www.w3.org/2000/svg"
|
17
|
+
data-testid="refine-logo"
|
18
|
+
>
|
19
|
+
<path
|
20
|
+
d="M12 9C13.6569 9 15 7.65685 15 6C15 4.34315 13.6569 3 12 3C10.3431 3 9 4.34315 9 6C9 7.65685 10.3431 9 12 9Z"
|
21
|
+
fill="currentColor"
|
22
|
+
/>
|
23
|
+
<path
|
24
|
+
fillRule="evenodd"
|
25
|
+
clipRule="evenodd"
|
26
|
+
d="M24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0C18.6274 0 24 5.37258 24 12ZM8 6C8 3.79086 9.79086 2 12 2C14.2091 2 16 3.79086 16 6V18C16 20.2091 14.2091 22 12 22C9.79086 22 8 20.2091 8 18V6Z"
|
27
|
+
fill="currentColor"
|
28
|
+
/>
|
29
|
+
</svg>
|
30
|
+
);
|
31
|
+
|
32
|
+
export const ThemedTitle: React.FC<RefineLayoutThemedTitleProps> = ({
|
33
|
+
collapsed,
|
34
|
+
icon = defaultIcon,
|
35
|
+
text = defaultText,
|
36
|
+
}) => {
|
37
|
+
const { token } = useToken();
|
38
|
+
const routerType = useRouterType();
|
39
|
+
const Link = useLink();
|
40
|
+
const { Link: LegacyLink } = useRouterContext();
|
41
|
+
|
42
|
+
const ActiveLink = routerType === "legacy" ? LegacyLink : Link;
|
43
|
+
|
44
|
+
return (
|
45
|
+
<ActiveLink
|
46
|
+
to="/"
|
47
|
+
style={{
|
48
|
+
display: "inline-block",
|
49
|
+
}}
|
50
|
+
>
|
51
|
+
<Space
|
52
|
+
style={{
|
53
|
+
display: "flex",
|
54
|
+
alignItems: "center",
|
55
|
+
}}
|
56
|
+
>
|
57
|
+
<div
|
58
|
+
style={{
|
59
|
+
height: "24px",
|
60
|
+
width: "24px",
|
61
|
+
color: token.colorPrimary,
|
62
|
+
}}
|
63
|
+
>
|
64
|
+
{icon}
|
65
|
+
</div>
|
66
|
+
|
67
|
+
{!collapsed && (
|
68
|
+
<Typography.Title
|
69
|
+
style={{
|
70
|
+
fontSize: "14px",
|
71
|
+
marginBottom: 0,
|
72
|
+
fontWeight: 700,
|
73
|
+
}}
|
74
|
+
>
|
75
|
+
{text}
|
76
|
+
</Typography.Title>
|
77
|
+
)}
|
78
|
+
</Space>
|
79
|
+
</ActiveLink>
|
80
|
+
);
|
81
|
+
};
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import type {
|
2
|
+
RefineThemedLayoutSiderProps,
|
3
|
+
RefineThemedLayoutHeaderProps,
|
4
|
+
RefineThemedLayoutProps,
|
5
|
+
RefineLayoutThemedTitleProps,
|
6
|
+
} from "@refinedev/ui-types";
|
7
|
+
|
8
|
+
export type {
|
9
|
+
RefineLayoutThemedTitleProps,
|
10
|
+
RefineThemedLayoutSiderProps,
|
11
|
+
RefineThemedLayoutHeaderProps,
|
12
|
+
RefineThemedLayoutProps,
|
13
|
+
};
|
package/src/definitions/index.ts
CHANGED
@@ -0,0 +1,50 @@
|
|
1
|
+
import { ThemeConfig } from "antd";
|
2
|
+
|
3
|
+
type ThemeNames =
|
4
|
+
| "Blue"
|
5
|
+
| "Purple"
|
6
|
+
| "Magenta"
|
7
|
+
| "Red"
|
8
|
+
| "Orange"
|
9
|
+
| "Yellow"
|
10
|
+
| "Green";
|
11
|
+
|
12
|
+
type RefineThemes = Record<ThemeNames, ThemeConfig>;
|
13
|
+
|
14
|
+
export const RefineThemes: RefineThemes = {
|
15
|
+
Blue: {
|
16
|
+
token: {
|
17
|
+
colorPrimary: "#1677FF",
|
18
|
+
},
|
19
|
+
},
|
20
|
+
Purple: {
|
21
|
+
token: {
|
22
|
+
colorPrimary: "#722ED1",
|
23
|
+
},
|
24
|
+
},
|
25
|
+
Magenta: {
|
26
|
+
token: {
|
27
|
+
colorPrimary: "#EB2F96",
|
28
|
+
},
|
29
|
+
},
|
30
|
+
Red: {
|
31
|
+
token: {
|
32
|
+
colorPrimary: "#F5222D",
|
33
|
+
},
|
34
|
+
},
|
35
|
+
Orange: {
|
36
|
+
token: {
|
37
|
+
colorPrimary: "#FA541C",
|
38
|
+
},
|
39
|
+
},
|
40
|
+
Yellow: {
|
41
|
+
token: {
|
42
|
+
colorPrimary: "#FAAD14",
|
43
|
+
},
|
44
|
+
},
|
45
|
+
Green: {
|
46
|
+
token: {
|
47
|
+
colorPrimary: "#52C41A",
|
48
|
+
},
|
49
|
+
},
|
50
|
+
};
|