mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-10 02:54:15 +00:00
support custom renders inside sidebar
This commit is contained in:
parent
472050c8b0
commit
843ccd812a
@ -1,5 +1,5 @@
|
||||
import React from "react"
|
||||
import { Menu, Avatar } from "antd"
|
||||
import { Menu, Avatar, Button } from "antd"
|
||||
import { Translation } from "react-i18next"
|
||||
import classnames from "classnames"
|
||||
|
||||
@ -70,6 +70,8 @@ export default class Sidebar extends React.Component {
|
||||
toggleCollapse: this.toggleCollapse,
|
||||
isVisible: () => this.state.visible,
|
||||
isCollapsed: () => this.state.collapsed,
|
||||
setCustomRender: this.setRender,
|
||||
closeCustomRender: this.closeRender,
|
||||
}
|
||||
|
||||
this.state = {
|
||||
@ -78,6 +80,9 @@ export default class Sidebar extends React.Component {
|
||||
collapsed: window.app.settings.get("collapseOnLooseFocus") ?? false,
|
||||
pathResolvers: null,
|
||||
menus: null,
|
||||
|
||||
customRenderTitle: null,
|
||||
customRender: null,
|
||||
}
|
||||
|
||||
// handle sidedrawer open/close
|
||||
@ -99,6 +104,38 @@ export default class Sidebar extends React.Component {
|
||||
}, 100)
|
||||
}
|
||||
|
||||
setRender = (render, options = {}) => {
|
||||
if (!typeof render === "function") {
|
||||
throw new Error("Render is required to be a function")
|
||||
}
|
||||
|
||||
this.setState({
|
||||
customRenderTitle: <div className="render_content_header_title">
|
||||
{
|
||||
options.icon && createIconRender(options.icon)
|
||||
}
|
||||
{
|
||||
options.title && <h1>
|
||||
<Translation>
|
||||
{t => t(options.title)}
|
||||
</Translation>
|
||||
</h1>
|
||||
}
|
||||
</div>,
|
||||
customRender: React.createElement(render, {
|
||||
...options.props ?? {},
|
||||
close: this.closeRender,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
closeRender = () => {
|
||||
this.setState({
|
||||
customRenderTitle: null,
|
||||
customRender: null,
|
||||
})
|
||||
}
|
||||
|
||||
loadItems = async () => {
|
||||
const generation = generateItems()
|
||||
|
||||
@ -213,62 +250,87 @@ export default class Sidebar extends React.Component {
|
||||
classnames(
|
||||
"app_sidebar",
|
||||
{
|
||||
["customRender"]: this.state.customRender,
|
||||
["floating"]: window.app?.settings.get("sidebar.floating"),
|
||||
["collapsed"]: this.state.visible && this.state.collapsed,
|
||||
["elevated"]: this.state.visible && this.state.elevated,
|
||||
["collapsed"]: !this.state.customRender && this.state.visible && this.state.collapsed,
|
||||
["elevated"]: !this.state.visible && this.state.elevated,
|
||||
["hidden"]: !this.state.visible,
|
||||
}
|
||||
)
|
||||
}
|
||||
>
|
||||
<div className="app_sidebar_header">
|
||||
<div className={classnames("app_sidebar_header_logo", { ["collapsed"]: this.state.collapsed })}>
|
||||
<img src={this.state.collapsed ? config.logo?.alt : config.logo?.full} />
|
||||
|
||||
{
|
||||
this.state.customRender &&
|
||||
<div className="render_content_wrapper">
|
||||
<div className="render_content_header">
|
||||
{
|
||||
this.state.customRenderTitle ?? null
|
||||
}
|
||||
<Button
|
||||
onClick={this.closeRender}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</div>
|
||||
<div className="render_content">
|
||||
{this.state.customRender}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div key="menu" className="app_sidebar_menu_wrapper">
|
||||
<Menu selectable={true} mode="inline" onClick={this.handleClick}>
|
||||
{this.renderMenuItems(this.state.menus)}
|
||||
</Menu>
|
||||
</div>
|
||||
{
|
||||
!this.state.customRender && <>
|
||||
<div className="app_sidebar_header">
|
||||
<div className={classnames("app_sidebar_header_logo", { ["collapsed"]: this.state.collapsed })}>
|
||||
<img src={this.state.collapsed ? config.logo?.alt : config.logo?.full} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div key="bottom" className={classnames("app_sidebar_menu_wrapper", "bottom")}>
|
||||
<Menu selectable={false} mode="inline" onClick={this.handleClick}>
|
||||
<Menu.Item key="search" icon={<Icons.Search />} override_event="app.openSearcher" >
|
||||
<Translation>
|
||||
{(t) => t("Search")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="create" icon={<Icons.PlusCircle />} override_event="app.openCreator" >
|
||||
<Translation>
|
||||
{(t) => t("Create")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="notifications" icon={<Icons.Bell />} override_event="app.openNotifications">
|
||||
<Translation>
|
||||
{t => t("Notifications")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="settings" icon={<Icons.Settings />}>
|
||||
<Translation>
|
||||
{t => t("Settings")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
{
|
||||
app.userData && <Menu.Item key="account" className="user_avatar">
|
||||
<Avatar shape="square" src={app.userData?.avatar} />
|
||||
</Menu.Item>
|
||||
}
|
||||
{
|
||||
!app.userData && <Menu.Item key="login" icon={<Icons.LogIn />}>
|
||||
<Translation>
|
||||
{t => t("Login")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
}
|
||||
</Menu>
|
||||
</div>
|
||||
<div key="menu" className="app_sidebar_menu_wrapper">
|
||||
<Menu selectable={true} mode="inline" onClick={this.handleClick}>
|
||||
{this.renderMenuItems(this.state.menus)}
|
||||
</Menu>
|
||||
</div>
|
||||
|
||||
<div key="bottom" className={classnames("app_sidebar_menu_wrapper", "bottom")}>
|
||||
<Menu selectable={false} mode="inline" onClick={this.handleClick}>
|
||||
<Menu.Item key="search" icon={<Icons.Search />} override_event="app.openSearcher" >
|
||||
<Translation>
|
||||
{(t) => t("Search")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="create" icon={<Icons.PlusCircle />} override_event="app.openCreator" >
|
||||
<Translation>
|
||||
{(t) => t("Create")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="notifications" icon={<Icons.Bell />} override_event="app.openNotifications">
|
||||
<Translation>
|
||||
{t => t("Notifications")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="settings" icon={<Icons.Settings />}>
|
||||
<Translation>
|
||||
{t => t("Settings")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
{
|
||||
app.userData && <Menu.Item key="account" className="user_avatar">
|
||||
<Avatar shape="square" src={app.userData?.avatar} />
|
||||
</Menu.Item>
|
||||
}
|
||||
{
|
||||
!app.userData && <Menu.Item key="login" icon={<Icons.LogIn />}>
|
||||
<Translation>
|
||||
{t => t("Login")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
}
|
||||
</Menu>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -44,6 +44,25 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.customRender {
|
||||
display: flex;
|
||||
position: relative;
|
||||
|
||||
width: 100%;
|
||||
min-width: 34vw;
|
||||
|
||||
padding: 20px;
|
||||
max-width: 60vw;
|
||||
|
||||
.app_sidebar_menu_wrapper {
|
||||
animation: disappear 0.3s ease-out forwards;
|
||||
}
|
||||
|
||||
.render_content_wrapper {
|
||||
animation: appear 0.3s ease-out forwards;
|
||||
}
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
flex: 0 !important;
|
||||
min-width: 0 !important;
|
||||
@ -55,6 +74,52 @@
|
||||
box-shadow: 0 0 5px 4px rgba(0, 0, 0, 0.1) !important;
|
||||
}
|
||||
|
||||
.render_content_wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
opacity: 0;
|
||||
transition: all 150ms ease-in-out;
|
||||
|
||||
overflow-y: hidden;
|
||||
|
||||
.render_content_header {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.render_content_header_title {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
|
||||
align-items: center;
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
font-size: 1.8;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
svg {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.render_content {
|
||||
height: 100%;
|
||||
|
||||
padding: 20px;
|
||||
padding-left: 0;
|
||||
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
.app_sidebar_header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -178,4 +243,24 @@
|
||||
margin: 0;
|
||||
flex: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes appear {
|
||||
0% {
|
||||
opacity: 0;
|
||||
width: 0px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
5% {
|
||||
opacity: 0;
|
||||
width: 0px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user