Skip to content

Commit fea984f

Browse files
committedDec 7, 2022
website: add themes home page.
1 parent 00c84f8 commit fea984f

File tree

12 files changed

+247
-118
lines changed

12 files changed

+247
-118
lines changed
 

‎www/src/components/Header.tsx

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import styled from 'styled-components';
2+
import { NavLink } from 'react-router-dom';
3+
import logo from '../logo.png';
4+
import { NavMenus } from './NavMenus';
5+
6+
export const Warpper = styled.div`
7+
display: flex;
8+
flex-direction: column;
9+
`;
10+
11+
const HeaderWarpper = styled.div`
12+
display: flex;
13+
justify-content: space-between;
14+
align-items: center;
15+
height: 42px;
16+
padding-left: 10px;
17+
padding-right: 10px;
18+
border-bottom: 1px solid var(--color-border-default);
19+
position: sticky;
20+
top: 0;
21+
z-index: 9999;
22+
background-color: var(--color-canvas-subtle);
23+
`;
24+
25+
const Title = styled(NavLink)`
26+
font-size: 14px;
27+
font-weight: bold;
28+
display: flex;
29+
align-items: center;
30+
gap: 10px;
31+
text-decoration: none;
32+
color: var(--color-fg-muted);
33+
> img {
34+
height: 21px;
35+
}
36+
`;
37+
38+
export const Header = () => {
39+
return (
40+
<HeaderWarpper>
41+
<Title to="/">
42+
<img src={logo} alt="Logo" />
43+
<span>CodeMirror Theme</span>
44+
</Title>
45+
<NavMenus />
46+
</HeaderWarpper>
47+
);
48+
};

‎www/src/components/NavMenus.tsx

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import styled, { css } from 'styled-components';
2+
import { NavLink } from 'react-router-dom';
3+
4+
export const Tools = styled.div`
5+
display: flex;
6+
justify-content: center;
7+
align-items: center;
8+
gap: 2px;
9+
& a {
10+
display: flex;
11+
align-items: center;
12+
}
13+
`;
14+
15+
const style = css`
16+
padding: 2px 5px;
17+
border-radius: 3px;
18+
text-decoration: none;
19+
color: var(--color-accent-emphasis);
20+
&.active {
21+
background-color: var(--color-neutral-muted);
22+
color: var(--color-fg-default);
23+
}
24+
`;
25+
26+
export const Link = styled(NavLink)`
27+
${style}
28+
`;
29+
30+
export const Hyperlink = styled.a`
31+
${style}
32+
`;
33+
34+
export const NavMenus = () => {
35+
return (
36+
<Tools>
37+
<Link to="/">Home</Link>
38+
<Link to="/extensions">Extensions</Link>
39+
<Link to="/theme/">Themes</Link>
40+
<Link to="/editor/theme">Themes Editor</Link>
41+
<Link to="/theme/doc">Theme Doc</Link>
42+
<Hyperlink href="https://github.com/uiwjs/react-codemirror" target="__blank">
43+
Github
44+
</Hyperlink>
45+
<dark-mode permanent />
46+
</Tools>
47+
);
48+
};

‎www/src/pages/theme/themes/Warpper.tsx ‎www/src/components/Warpper.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const Warpper: FC<PropsWithChildren<{}>> = (props) => {
1515
const [element, setElement] = useState<HTMLDivElement>();
1616
useEffect(() => setElement($dom.current!), []);
1717
return (
18-
<Container ref={$dom}>
18+
<Container ref={$dom} {...props}>
1919
{props.children}
2020
<BackToUp element={element} style={{ position: 'fixed' }}>
2121
Top

‎www/src/index.tsx

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { createGlobalStyle } from 'styled-components';
55
import Home from './pages/home';
66
import { ThemeEditor } from './pages/theme/editor';
77
import { ThemeLayout } from './pages/theme';
8+
import { ThemesHome } from './pages/theme/home';
89
import { ThemeDoc } from './pages/theme/docs';
910
import { ThemeOkaidia } from './pages/theme/themes';
1011
import { ExtensionsLayout } from './pages/extensions';
@@ -66,7 +67,12 @@ root.render(
6667
<Routes>
6768
<Route index element={<Home />} />
6869
<Route path="/" element={<Home />} />
70+
<Route path="/editor/theme/" element={<ThemeLayout />}>
71+
<Route index element={<Navigate to="single" replace />} />
72+
<Route path=":type" element={<ThemeEditor />} />
73+
</Route>
6974
<Route path="/theme/" element={<ThemeLayout />}>
75+
<Route index element={<ThemesHome />} />
7076
<Route path="data" element={<Navigate to="sublime" replace />} />
7177
<Route path="data/:name" element={<ThemeOkaidia />} />
7278
<Route path="data/:name/:lightOrDark" element={<ThemeOkaidia />} />

‎www/src/pages/extensions/Document.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { FC, PropsWithChildren } from 'react';
2-
import { Warpper } from '../theme/themes/Warpper';
2+
import { Warpper } from '../../components/Warpper';
33
import { Content } from '../theme/themes/Document';
44

55
interface DocumentProps {

‎www/src/pages/extensions/index.tsx

+3-15
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import { Outlet, useLocation } from 'react-router-dom';
22
import { useEffect } from 'react';
33
import styled from 'styled-components';
4-
import { Warpper, Header, Title, Tools, Link } from '../theme';
4+
import { Header, Warpper } from '../../components/Header';
55
import { Document } from './Document';
6-
import logo from '../../logo.png';
76
import { Sider } from '../theme/editor';
87
import { Content } from '../theme';
9-
import { MenuItem } from '../theme/themes';
8+
import { MenuItem } from '../theme/themes/SiderMenus';
109
import { mdSource } from './datas';
1110

1211
export const PageWarpper = styled.div`
@@ -26,18 +25,7 @@ export const ExtensionsLayout = () => {
2625

2726
return (
2827
<Warpper>
29-
<Header>
30-
<Title to="/">
31-
<img src={logo} alt="Logo" />
32-
<span>CodeMirror Extensions</span>
33-
</Title>
34-
<Tools>
35-
<Link to="/">Home</Link>
36-
<Link to="/extensions">Extensions</Link>
37-
<Link to="/theme/data">Themes</Link>
38-
<dark-mode permanent />
39-
</Tools>
40-
</Header>
28+
<Header />
4129
<Content>
4230
<Sider>
4331
{Object.keys(mdSource).map((name, key) => {

‎www/src/pages/home/index.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,10 @@ export default function App() {
141141
</AppTitle>
142142
<Describe>CodeMirror component for React. </Describe>
143143
<Buttons>
144-
<Link to="/theme/editor" className="special">
144+
<Link to="/editor/theme" className="special">
145145
Theme Editor
146146
</Link>
147-
<Link to="/theme/data" className="themes">
147+
<Link to="/theme/" className="themes">
148148
Themes
149149
</Link>
150150
<Link to="/extensions" className="extensions">

‎www/src/pages/theme/home/index.tsx

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { Fragment } from 'react';
2+
import styled from 'styled-components';
3+
import { Link } from 'react-router-dom';
4+
import CodeMirror from '@uiw/react-codemirror';
5+
import { color } from '@uiw/codemirror-extensions-color';
6+
import { langs } from '@uiw/codemirror-extensions-langs';
7+
import { SiderMenus } from '../themes/SiderMenus';
8+
import { Warpper } from '../../../components/Warpper';
9+
import { themeData } from '../themes/Datas';
10+
import { toSnakeCase } from '../themes/Document';
11+
12+
export const toTitleCase = (str: string = '') =>
13+
str
14+
.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
15+
?.map((x) => x.charAt(0).toUpperCase() + x.slice(1))
16+
.join(' ');
17+
18+
const ThemesWarpper = styled.div`
19+
grid-template-columns: repeat(3, minmax(0, 1fr));
20+
gap: 2.5rem;
21+
display: grid;
22+
padding: 2.6rem;
23+
a {
24+
text-decoration: none;
25+
}
26+
@media (max-width: 1280px) {
27+
grid-template-columns: repeat(3, minmax(0, 1fr));
28+
}
29+
@media (max-width: 1024px) {
30+
grid-template-columns: repeat(2, minmax(0, 1fr));
31+
}
32+
@media (max-width: 860px) {
33+
grid-template-columns: repeat(1, minmax(0, 1fr));
34+
}
35+
`;
36+
37+
const ThemeCard = styled.div`
38+
padding: 1rem;
39+
box-shadow: 0 0 #0000, 0 0 #0000, 0 0 #0000, 0 1px 2px 0 rgba(0, 0, 0, 0.05);
40+
border-radius: 0.5rem;
41+
border: 1px solid var(--color-neutral-muted);
42+
background-color: var(--color-canvas-subtle);
43+
transition-property: all;
44+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
45+
transition-duration: 0.2s;
46+
&:hover {
47+
transform: translate(0, -0.25rem) rotate(0) skewX(0) skewY(0) scaleX(1) scaleY(1);
48+
}
49+
`;
50+
51+
const Title = styled.div`
52+
font-weight: 600;
53+
padding-bottom: 0.68rem;
54+
`;
55+
56+
const codeString = `import React, {useState} from 'react';
57+
58+
// My favorite component
59+
const Counter = () => {
60+
const [value, setValue] = useState(0);
61+
62+
return <span>{value}</span>;
63+
};`;
64+
65+
export function ThemesHome() {
66+
return (
67+
<Fragment>
68+
<SiderMenus />
69+
<Warpper>
70+
<ThemesWarpper>
71+
{Object.keys(themeData).map((name, idx) => {
72+
const [_name, _theme] = toSnakeCase(name) || [];
73+
return (
74+
<Link key={idx} to={`/theme/data/${_name}${_theme ? `/${_theme}` : ''}`}>
75+
<ThemeCard>
76+
<Title>{toTitleCase(name)}</Title>
77+
<CodeMirror
78+
value={codeString}
79+
height="165px"
80+
theme={themeData[name as keyof typeof themeData]}
81+
extensions={[color, langs.jsx()]}
82+
/>
83+
</ThemeCard>
84+
</Link>
85+
);
86+
})}
87+
</ThemesWarpper>
88+
</Warpper>
89+
</Fragment>
90+
);
91+
}

‎www/src/pages/theme/index.tsx

+3-66
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,14 @@
11
import styled from 'styled-components';
22
import { useEffect } from 'react';
3-
import { NavLink, Outlet, useParams } from 'react-router-dom';
3+
import { Outlet, useParams } from 'react-router-dom';
44
import '@wcj/dark-mode';
5-
import logo from '../../logo.png';
6-
7-
export const Warpper = styled.div`
8-
display: flex;
9-
flex-direction: column;
10-
`;
11-
12-
export const Title = styled(NavLink)`
13-
font-size: 14px;
14-
font-weight: bold;
15-
display: flex;
16-
align-items: center;
17-
gap: 10px;
18-
text-decoration: none;
19-
color: var(--color-fg-muted);
20-
> img {
21-
height: 21px;
22-
}
23-
`;
24-
25-
export const Tools = styled.div`
26-
display: flex;
27-
justify-content: center;
28-
align-items: center;
29-
gap: 2px;
30-
& a {
31-
display: flex;
32-
align-items: center;
33-
}
34-
`;
5+
import { Header, Warpper } from '../../components/Header';
356

367
export const Content = styled.div`
378
display: flex;
389
flex: 1;
3910
`;
4011

41-
export const Header = styled.div`
42-
display: flex;
43-
justify-content: space-between;
44-
align-items: center;
45-
height: 42px;
46-
padding-left: 10px;
47-
padding-right: 10px;
48-
border-bottom: 1px solid var(--color-border-default);
49-
`;
50-
51-
export const Link = styled(NavLink)`
52-
padding: 2px 5px;
53-
border-radius: 3px;
54-
text-decoration: none;
55-
color: var(--color-accent-emphasis);
56-
&.active {
57-
background-color: var(--color-neutral-muted);
58-
color: var(--color-fg-default);
59-
}
60-
`;
61-
6212
export function ThemeLayout() {
6313
const { name = '', lightOrDark = '' } = useParams();
6414

@@ -72,20 +22,7 @@ export function ThemeLayout() {
7222

7323
return (
7424
<Warpper>
75-
<Header>
76-
<Title to="/">
77-
<img src={logo} alt="Logo" />
78-
<span>CodeMirror Theme</span>
79-
</Title>
80-
<Tools>
81-
<Link to="/">Home</Link>
82-
<Link to="/extensions">Extensions</Link>
83-
<Link to="/theme/data">Themes</Link>
84-
<Link to="/theme/editor">Editor</Link>
85-
<Link to="/theme/doc">Theme Doc</Link>
86-
<dark-mode permanent />
87-
</Tools>
88-
</Header>
25+
<Header />
8926
<Content>
9027
<Outlet />
9128
</Content>

‎www/src/pages/theme/themes/Document.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import MarkdownPreview from '@uiw/react-markdown-preview';
33
import styled from 'styled-components';
44
import { PreCode } from './PreCode';
55
import { mdSource } from './Datas';
6-
import { Warpper } from './Warpper';
6+
import { Warpper } from '../../../components/Warpper';
77

88
export const toSnakeCase = (str: string = '') =>
99
str
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import styled from 'styled-components';
2+
import { NavLink } from 'react-router-dom';
3+
import { toSnakeCase } from './Document';
4+
import { Sider } from '../editor';
5+
import { themeData } from './Datas';
6+
7+
export const MenuItem = styled(NavLink)`
8+
cursor: pointer;
9+
padding: 6px 8px;
10+
font-size: 16px;
11+
text-decoration: none;
12+
text-transform: capitalize;
13+
border-radius: 2px;
14+
transition: background-color 0.3s;
15+
color: var(--color-accent-emphasis);
16+
&.active {
17+
background-color: var(--color-neutral-muted);
18+
color: var(--color-theme-text);
19+
}
20+
&:hover {
21+
background-color: var(--color-neutral-muted);
22+
}
23+
`;
24+
25+
export function SiderMenus() {
26+
return (
27+
<Sider>
28+
<MenuItem to={`/theme/`}>Home</MenuItem>
29+
{Object.keys(themeData).map((name, key) => {
30+
const [_name, _theme] = toSnakeCase(name) || [];
31+
return (
32+
<MenuItem key={key} to={`/theme/data/${_name}${_theme ? `/${_theme}` : ''}`}>
33+
{_name} {_theme}
34+
</MenuItem>
35+
);
36+
})}
37+
</Sider>
38+
);
39+
}

‎www/src/pages/theme/themes/index.tsx

+4-32
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,17 @@
11
import { Fragment } from 'react';
2-
import styled from 'styled-components';
3-
import { useParams, NavLink } from 'react-router-dom';
4-
import { Document, toSnakeCase } from './Document';
2+
import { useParams } from 'react-router-dom';
3+
import { Document } from './Document';
54
import { Sample } from './Sample';
6-
import { Sider } from '../editor';
75
import { themeData } from './Datas';
8-
9-
export const MenuItem = styled(NavLink)`
10-
cursor: pointer;
11-
padding: 6px 8px;
12-
font-size: 16px;
13-
text-decoration: none;
14-
text-transform: capitalize;
15-
border-radius: 2px;
16-
transition: background-color 0.3s;
17-
color: var(--color-accent-emphasis);
18-
&.active {
19-
background-color: var(--color-neutral-muted);
20-
color: var(--color-theme-text);
21-
}
22-
&:hover {
23-
background-color: var(--color-neutral-muted);
24-
}
25-
`;
6+
import { SiderMenus } from './SiderMenus';
267

278
export const ThemeOkaidia = () => {
289
const { name = '', lightOrDark = '' } = useParams();
2910
const text = name + lightOrDark.replace(lightOrDark[0], (lightOrDark[0] || '').toLocaleUpperCase());
3011
const theme = themeData[text as keyof typeof themeData];
3112
return (
3213
<Fragment>
33-
<Sider>
34-
{Object.keys(themeData).map((name, key) => {
35-
const [_name, _theme] = toSnakeCase(name) || [];
36-
return (
37-
<MenuItem key={key} to={`/theme/data/${_name}${_theme ? `/${_theme}` : ''}`}>
38-
{_name} {_theme}
39-
</MenuItem>
40-
);
41-
})}
42-
</Sider>
14+
<SiderMenus />
4315
<Document themeName={text}>
4416
<Sample theme={theme} />
4517
</Document>

0 commit comments

Comments
 (0)
Please sign in to comment.