feat(header): better navbar

main
倏昱 2023-05-19 17:02:41 +08:00
parent 759ddc4f7d
commit 37e22308b7
9 changed files with 194 additions and 152 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
import { createStyles, css, cx } from 'antd-style'
const offset = 16
const offset = 17
const toggleLength = 40
const toggleShort = 16

View File

@ -0,0 +1,55 @@
import React, { useEffect, useState } from 'react'
import type { MenuProps } from 'antd'
import { Menu } from 'antd'
import styled from 'styled-components'
const NavBar = styled(Menu)`
flex: 1;
border: none;
line-height: 1;
.ant-menu-overflow-item {
padding: 8px 12px;
border-radius: 4px !important;
color: var(--color-text-secondary);
&:after {
display: none; !important;
}
&:hover {
color: var(--color-text);
background: var(--color-fill-tertiary);
}
&.ant-menu-item-selected {
font-weight: 600;
color: var(--color-text);
}
}
`
const Nav: React.FC = () => {
const [items, setItems] = useState<MenuProps['items']>([])
useEffect(() => {
onUiLoaded(() => {
const buttons = gradioApp().querySelectorAll('#tabs > .tab-nav:first-child button')
const list: MenuProps['items'] | any = []
buttons.forEach((button: HTMLButtonElement | any, index) => {
button.id = `kitchen-nav-${index}`
list.push({
label: button.textContent,
key: String(index),
})
})
setItems(list)
})
}, [])
const onClick: MenuProps['onClick'] = (e: any) => {
const buttons: HTMLButtonElement[] | any = gradioApp().querySelectorAll('#tabs > .tab-nav:first-child button')
buttons[Number(e.key)]?.click()
}
return <NavBar defaultActiveFirst defaultSelectedKeys={['0']} onClick={onClick} mode="horizontal" items={items} />
}
export default Nav

View File

@ -36,15 +36,15 @@ const SubTitle = styled.div`
******************************************************/
const Setting: React.FC = () => {
const [setting, setSetting] = useAppStore((st) => [st.setting, st.onSetSetting], shallow)
const [setting, onSetSetting] = useAppStore((st) => [st.setting, st.onSetSetting], shallow)
const onReset = useCallback(() => {
setSetting(defaultSetting)
onSetSetting(defaultSetting)
gradioApp().getElementById('settings_restart_gradio')?.click()
}, [])
const onFinish = useCallback((value: WebuiSetting) => {
setSetting(value)
onSetSetting(value)
gradioApp().getElementById('settings_restart_gradio')?.click()
}, [])
@ -53,7 +53,7 @@ const Setting: React.FC = () => {
title={<Title> Setting</Title>}
trigger="click"
content={
<Form size="small" initialValues={setting} layout="horizontal" onFinish={onFinish} style={{ maxWidth: 240 }}>
<Form size="small" initialValues={setting} layout="horizontal" onFinish={onFinish} style={{ maxWidth: 260 }}>
<Divider style={{ margin: '4px 0 8px' }} />
<SubTitle>Promot Textarea</SubTitle>
<FormItem label="Display mode" name="promotTextarea">

View File

@ -10,59 +10,29 @@ import { shallow } from 'zustand/shallow'
import Giscus from './Giscus'
import Logo from './Logo'
import Setting from './Setting'
import Nav from './Nav'
import { civitaiLogo, themeIcon } from './style'
/******************************************************
*********************** Style *************************
******************************************************/
const Center = styled.div`
display: flex;
align-items: center;
justify-content: center;
`
const HeaderView = styled.div`
display: flex;
flex-wrap: nowrap;
gap: 12px;
align-items: center;
align-items: stretch;
justify-content: space-between;
height: -webkit-fill-available;
height: -moz-available;
padding: 16px 24px;
#tabs.header {
.tab-nav {
margin: 0 !important;
border: none !important;
}
button {
cursor: pointer;
flex: none;
flex: 0 !important;
margin: 0 !important;
padding: 8px !important;
background: transparent !important;
border: none !important;
border-radius: 4px !important;
transition: all 0.2s ease-in-out;
&:hover {
flex: none;
color: var(--color-text) !important;
background: var(--color-fill-tertiary) !important;
border: none !important;
}
&.selected {
flex: none;
font-weight: 600;
color: var(--color-text) !important;
background: transparent !important;
border: none !important;
}
}
}
`
/******************************************************
@ -98,21 +68,28 @@ const Header: React.FC<HeaderProps> = ({ children }) => {
<>
<DraggablePanel placement="top" defaultSize={{ height: 'auto' }} expand={expand} onExpandChange={setExpand}>
<HeaderView id="header" style={{ flexDirection: mobile ? 'column' : 'row' }}>
<a href="https://github.com/canisminor1990/sd-webui-kitchen-theme" target="_blank" rel="noreferrer">
<Logo themeMode={themeMode} />
</a>
{children}
<Space.Compact>
<a href="https://civitai.com/" target="_blank" rel="noreferrer">
<Button title="Civitai" icon={civitaiLogo} />
<Center>
<a href="https://github.com/canisminor1990/sd-webui-kitchen-theme" target="_blank" rel="noreferrer">
<Logo themeMode={themeMode} />
</a>
<a href="https://www.birme.net/?target_width=512&target_height=512" target="_blank" rel="noreferrer">
<Button title="Birme" icon={<BoldOutlined />} />
</a>
<Button title="Feedback" icon={<GithubOutlined />} onClick={showModal} />
<Setting />
<Button title="Switch Theme" icon={themeIcon[themeMode]} onClick={handleSetTheme} />
</Space.Compact>
</Center>
<Center style={{ flex: 1, padding: '0 16px' }}>
<Nav />
{children}
</Center>
<Center>
<Space.Compact>
<a href="https://civitai.com/" target="_blank" rel="noreferrer">
<Button title="Civitai" icon={civitaiLogo} />
</a>
<a href="https://www.birme.net/?target_width=512&target_height=512" target="_blank" rel="noreferrer">
<Button title="Birme" icon={<BoldOutlined />} />
</a>
<Button title="Feedback" icon={<GithubOutlined />} onClick={showModal} />
<Setting />
<Button title="Switch Theme" icon={themeIcon[themeMode]} onClick={handleSetTheme} />
</Space.Compact>
</Center>
</HeaderView>
</DraggablePanel>
<Modal

View File

@ -49,18 +49,10 @@ const App: React.FC = () => {
const [extraLoading, setExtraLoading] = useState(true)
const sidebarRef: any = useRef<HTMLElement>()
const mainRef: any = useRef<HTMLElement>()
const headerRef: any = useRef<HTMLElement>()
const txt2imgExtraNetworkSidebarRef: any = useRef<HTMLElement>()
const img2imgExtraNetworkSidebarRef: any = useRef<HTMLElement>()
useEffect(() => {
onUiLoaded(() => {
// Header
const header = gradioApp().querySelector('#tabs > .tab-nav:first-child')
if (header) {
headerRef.current?.appendChild(header)
headerRef.current.id = 'tabs'
}
// Content
const main = gradioApp().querySelector('.app')
if (main) mainRef.current?.appendChild(main)
@ -122,7 +114,6 @@ const App: React.FC = () => {
<Spin size="small" />
</LoadingBox>
)}
<div style={loading ? { display: 'none' } : {}} ref={headerRef} className="header" />
</Header>
<View>
<Sidebar>

View File

@ -0,0 +1,3 @@
#tabs > .tab-nav:first-child {
display: none;
}

View File

@ -22,6 +22,7 @@
@import 'components/extra-network';
@import 'components/footer';
@import 'components/draggable-container';
@import 'components/header';
/* Tabs */
@import 'tabs/tabs';

File diff suppressed because one or more lines are too long