Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
VisualDL
提交
ec6e76e4
V
VisualDL
项目概览
PaddlePaddle
/
VisualDL
1 年多 前同步成功
通知
88
Star
4655
Fork
642
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
5
Wiki
分析
仓库
DevOps
项目成员
Pages
V
VisualDL
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
5
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
ec6e76e4
编写于
9月 25, 2020
作者:
P
Peter Pan
提交者:
GitHub
9月 25, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: add theme toggle (#830)
上级
e50c15b0
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
201 addition
and
12 deletion
+201
-12
frontend/packages/core/public/icons/theme.svg
frontend/packages/core/public/icons/theme.svg
+10
-0
frontend/packages/core/public/locales/en/common.json
frontend/packages/core/public/locales/en/common.json
+5
-0
frontend/packages/core/public/locales/zh/common.json
frontend/packages/core/public/locales/zh/common.json
+5
-0
frontend/packages/core/src/components/Navbar.tsx
frontend/packages/core/src/components/Navbar.tsx
+19
-0
frontend/packages/core/src/components/ThemeToggle.tsx
frontend/packages/core/src/components/ThemeToggle.tsx
+109
-0
frontend/packages/core/src/store/theme/actions.ts
frontend/packages/core/src/store/theme/actions.ts
+7
-0
frontend/packages/core/src/store/theme/reducers.ts
frontend/packages/core/src/store/theme/reducers.ts
+20
-2
frontend/packages/core/src/store/theme/selectors.ts
frontend/packages/core/src/store/theme/selectors.ts
+2
-0
frontend/packages/core/src/store/theme/types.ts
frontend/packages/core/src/store/theme/types.ts
+9
-2
frontend/packages/core/src/utils/theme.ts
frontend/packages/core/src/utils/theme.ts
+15
-8
未找到文件。
frontend/packages/core/public/icons/theme.svg
0 → 100644
浏览文件 @
ec6e76e4
<svg
height=
"14"
viewBox=
"0 0 14 14"
width=
"14"
xmlns=
"http://www.w3.org/2000/svg"
>
<g
fill=
"none"
fill-rule=
"evenodd"
>
<g
fill=
"#fff"
>
<circle
cx=
"4"
cy=
"8"
r=
"1"
/>
<circle
cx=
"5"
cy=
"4"
r=
"1"
/>
<circle
cx=
"9"
cy=
"4"
r=
"1"
/>
</g>
<path
d=
"m3.27235335 1.6761119c1.47031684-1.02952694 3.21873715-1.365625 4.85695999-1.07676211s3.16624816 1.20268672 4.19577516 2.67300356c.7388055 1.05512367 1.1206639 2.2534373 1.1704891 3.45153172.0436106 1.04865781-.1668543 2.09710997-.6145934 3.04909362-.494968-.31183307-1.05803-.49207378-1.6336058-.53065417-.7684739-.05151019-1.55912562.14907212-2.23926069.62530782-.68005955.47618286-1.1389421 1.15045256-1.35350247 1.89019066-.16074735.5542075-.18410258 1.1451771-.06062147 1.7172293-1.04751749.0948995-2.1046345-.0660591-3.07509828-.4658128-1.1086379-.4566704-2.10401594-1.2253229-2.84278359-2.2803925-1.02952694-1.47031682-1.365625-3.21873713-1.07676211-4.85695997s1.20268672-3.1662482 2.67300356-4.19577513z"
stroke=
"#fff"
/>
</g>
</svg>
frontend/packages/core/public/locales/en/common.json
浏览文件 @
ec6e76e4
...
...
@@ -31,6 +31,11 @@
"stop"
:
"Stop"
,
"stop-realtime-refresh"
:
"Stop realtime refresh"
,
"stopped"
:
"Stopped"
,
"theme"
:
{
"auto"
:
"Auto"
,
"dark"
:
"Dark"
,
"light"
:
"Light"
},
"time-mode"
:
{
"relative"
:
"Relative"
,
"step"
:
"Step"
,
...
...
frontend/packages/core/public/locales/zh/common.json
浏览文件 @
ec6e76e4
...
...
@@ -31,6 +31,11 @@
"stop"
:
"停止"
,
"stop-realtime-refresh"
:
"停止实时数据刷新"
,
"stopped"
:
"已停止"
,
"theme"
:
{
"auto"
:
"自动"
,
"dark"
:
"深色"
,
"light"
:
"浅色"
},
"time-mode"
:
{
"relative"
:
"Relative"
,
"step"
:
"Step"
,
...
...
frontend/packages/core/src/components/Navbar.tsx
浏览文件 @
ec6e76e4
...
...
@@ -5,6 +5,7 @@ import {border, borderRadius, rem, size, transitionProps} from '~/utils/style';
import
Icon
from
'
~/components/Icon
'
;
import
Language
from
'
~/components/Language
'
;
import
type
{
Route
}
from
'
~/routes
'
;
import
ThemeToggle
from
'
~/components/ThemeToggle
'
;
import
Tippy
from
'
@tippyjs/react
'
;
import
ee
from
'
~/utils/event
'
;
import
{
getApiToken
}
from
'
~/utils/fetch
'
;
...
...
@@ -264,6 +265,24 @@ const Navbar: FunctionComponent = () => {
})
}
</
div
>
<
div
className
=
"right"
>
<
Tippy
placement
=
"bottom-end"
animation
=
"shift-away-subtle"
interactive
arrow
=
{
false
}
offset
=
{
[
18
,
0
]
}
hideOnClick
=
{
false
}
role
=
"menu"
content
=
{
<
SubNav
>
<
ThemeToggle
/>
</
SubNav
>
}
>
<
NavItem
className
=
"nav-item"
>
<
Icon
type
=
"theme"
/>
</
NavItem
>
</
Tippy
>
<
NavItem
className
=
"nav-item"
onClick
=
{
changeLanguage
}
>
<
Language
/>
</
NavItem
>
...
...
frontend/packages/core/src/components/ThemeToggle.tsx
0 → 100644
浏览文件 @
ec6e76e4
import
React
,
{
FunctionComponent
}
from
'
react
'
;
import
{
actions
,
selectors
}
from
'
~/store
'
;
import
{
colors
,
themes
}
from
'
~/utils/theme
'
;
import
{
rem
,
transitionProps
}
from
'
~/utils/style
'
;
import
{
useDispatch
,
useSelector
}
from
'
react-redux
'
;
import
styled
from
'
styled-components
'
;
import
{
useTranslation
}
from
'
react-i18next
'
;
const
Wrapper
=
styled
.
dl
`
display: flex;
align-items: center;
background-color: var(--background-color);
${
transitionProps
(
'
background-color
'
)}
margin:
${
rem
(
10
)}
;
`
;
const
Item
=
styled
.
div
<
{
color
:
string
;
border
:
string
;
active
?:
boolean
}
>
`
margin: 0
${
rem
(
10
)}
;
padding:
${
rem
(
6
)}
${
rem
(
10
)}
;
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
dd {
display: block;
width:
${
rem
(
18
)}
;
height:
${
rem
(
18
)}
;
margin: 0;
position: relative;
border-radius: 50%;
${
props
=>
props
.
color
}
;
&::before {
content: ' ';
display: block;
position: absolute;
top: 0;
left: 0;
width: calc(100% - 2px);
height: calc(100% - 2px);
border: 1px solid
${
props
=>
props
.
border
}
;
border-radius: 50%;
}
&::after {
content: ' ';
display:
${
props
=>
(
props
.
active
?
'
block
'
:
'
none
'
)}
;
position: absolute;
top: 50%;
left: 50%;
background-color: #fff;
width:
${
rem
(
8
)}
;
height:
${
rem
(
8
)}
;
transform: translate(-50%, -50%);
border-radius: 50%;
}
}
dt {
display: block;
margin-top:
${
rem
(
12
)}
;
}
`
;
const
items
=
[
{
color
:
`background-color:
${
colors
.
primary
.
default
}
`
,
border
:
'
rgba(255, 255, 255, 0.59)
'
,
label
:
'
light
'
},
{
color
:
`background-color:
${
themes
.
dark
.
backgroundColor
}
`
,
border
:
'
rgba(255, 255, 255, 0.3)
'
,
label
:
'
dark
'
},
{
color
:
'
background-image: linear-gradient(133deg, #e9e9e9 5%, #a3a3a3 97%);
'
,
border
:
'
rgba(255, 255, 255, 0.3)
'
,
label
:
'
auto
'
}
]
as
const
;
const
ThemeToggle
:
FunctionComponent
=
()
=>
{
const
{
t
}
=
useTranslation
(
'
common
'
);
const
dispatch
=
useDispatch
();
const
selected
=
useSelector
(
selectors
.
theme
.
selected
);
return
(
<
Wrapper
>
{
items
.
map
(
item
=>
(
<
Item
color
=
{
item
.
color
}
border
=
{
item
.
border
}
active
=
{
selected
===
item
.
label
}
key
=
{
item
.
label
}
onClick
=
{
()
=>
dispatch
(
actions
.
theme
.
selectTheme
(
item
.
label
))
}
>
<
dd
></
dd
>
<
dt
>
{
t
(
`common:theme.
${
item
.
label
}
`
)
}
</
dt
>
</
Item
>
))
}
</
Wrapper
>
);
};
export
default
ThemeToggle
;
frontend/packages/core/src/store/theme/actions.ts
浏览文件 @
ec6e76e4
...
...
@@ -7,3 +7,10 @@ export function setTheme(theme: Theme) {
theme
};
}
export
function
selectTheme
(
theme
:
Theme
|
'
auto
'
)
{
return
{
type
:
ActionTypes
.
SELECT_THEME
,
theme
};
}
frontend/packages/core/src/store/theme/reducers.ts
浏览文件 @
ec6e76e4
import
{
THEME
,
autoTheme
}
from
'
~/utils/theme
'
;
import
type
{
ThemeActionTypes
,
ThemeState
}
from
'
./types
'
;
import
{
ActionTypes
}
from
'
./types
'
;
import
{
theme
}
from
'
~/utils/theme
'
;
import
type
{
Theme
}
from
'
~/utils/theme
'
;
const
STORAGE_KEY
=
'
theme
'
;
const
theme
=
THEME
||
(
window
.
localStorage
.
getItem
(
STORAGE_KEY
)
as
Theme
|
undefined
)
||
'
auto
'
;
const
initState
:
ThemeState
=
{
theme
theme
:
theme
===
'
auto
'
?
autoTheme
:
theme
,
selected
:
theme
};
window
.
document
.
body
.
classList
.
remove
(
'
light
'
,
'
dark
'
,
'
auto
'
);
window
.
document
.
body
.
classList
.
add
(
initState
.
selected
);
function
themeReducer
(
state
=
initState
,
action
:
ThemeActionTypes
):
ThemeState
{
switch
(
action
.
type
)
{
case
ActionTypes
.
SET_THEME
:
...
...
@@ -14,6 +23,15 @@ function themeReducer(state = initState, action: ThemeActionTypes): ThemeState {
...
state
,
theme
:
action
.
theme
};
case
ActionTypes
.
SELECT_THEME
:
window
.
localStorage
.
setItem
(
STORAGE_KEY
,
action
.
theme
);
window
.
document
.
body
.
classList
.
remove
(
'
light
'
,
'
dark
'
,
'
auto
'
);
window
.
document
.
body
.
classList
.
add
(
action
.
theme
);
return
{
...
state
,
theme
:
action
.
theme
===
'
auto
'
?
autoTheme
:
action
.
theme
,
selected
:
action
.
theme
};
default
:
return
state
;
}
...
...
frontend/packages/core/src/store/theme/selectors.ts
浏览文件 @
ec6e76e4
import
type
{
RootState
}
from
'
../index
'
;
export
const
theme
=
(
state
:
RootState
)
=>
state
.
theme
.
theme
;
export
const
selected
=
(
state
:
RootState
)
=>
state
.
theme
.
selected
;
frontend/packages/core/src/store/theme/types.ts
浏览文件 @
ec6e76e4
...
...
@@ -3,11 +3,13 @@ import type {Theme} from '~/utils/theme';
export
type
{
Theme
}
from
'
~/utils/theme
'
;
export
enum
ActionTypes
{
SET_THEME
=
'
SET_THEME
'
SET_THEME
=
'
SET_THEME
'
,
SELECT_THEME
=
'
SELECT_THEME
'
}
export
interface
ThemeState
{
theme
:
Theme
;
selected
:
Theme
|
'
auto
'
;
}
interface
SetThemeAction
{
...
...
@@ -15,4 +17,9 @@ interface SetThemeAction {
theme
:
Theme
;
}
export
type
ThemeActionTypes
=
SetThemeAction
;
interface
SelectThemeAction
{
type
:
ActionTypes
.
SELECT_THEME
;
theme
:
Theme
|
'
auto
'
;
}
export
type
ThemeActionTypes
=
SetThemeAction
|
SelectThemeAction
;
frontend/packages/core/src/utils/theme.ts
浏览文件 @
ec6e76e4
...
...
@@ -9,7 +9,9 @@ export const THEME: Theme | undefined = import.meta.env.SNOWPACK_PUBLIC_THEME;
export
const
matchMedia
=
window
.
matchMedia
(
'
(prefers-color-scheme: dark)
'
);
export
const
theme
=
THEME
||
(
matchMedia
.
matches
?
'
dark
'
:
'
light
'
);
export
const
autoTheme
:
Theme
=
matchMedia
.
matches
?
'
dark
'
:
'
light
'
;
export
const
theme
=
THEME
||
autoTheme
;
export
const
colors
=
{
primary
:
{
...
...
@@ -134,18 +136,23 @@ function generateThemeVariables(theme: Record<string, string>) {
.
join
(
'
\n
'
);
}
const
mediaQuery
=
css
`
@media (prefers-color-scheme: dark) {
${
generateThemeVariables
(
themes
.
dark
)}
}
`
;
export
const
variables
=
css
`
:root {
${
generateColorVariables
(
colors
)}
${
generateThemeVariables
(
themes
[
THEME
||
'
light
'
])}
${(
!
THEME
&&
mediaQuery
)
||
''
}
body.auto {
${
generateThemeVariables
(
themes
.
light
)}
@media (prefers-color-scheme: dark) {
${
generateThemeVariables
(
themes
.
dark
)}
}
}
body.light {
${
generateThemeVariables
(
themes
.
light
)}
}
body.dark {
${
generateThemeVariables
(
themes
.
dark
)}
}
}
`
;
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录