Skip to content

Commit 14cbe39

Browse files
committed
feat: introduce light/dark theme mode
1 parent 376226e commit 14cbe39

11 files changed

Lines changed: 4052 additions & 290 deletions

File tree

packages/blog-starter-kit/themes/hashnode/.env.example

Lines changed: 0 additions & 3 deletions
This file was deleted.

packages/blog-starter-kit/themes/hashnode/components/common-header-icon-btn.tsx

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,58 +5,58 @@ import { twJoin } from 'tailwind-merge';
55
import HeaderTooltip from './header-tooltip';
66

77
const variants = {
8-
theme: {
9-
label: 'Toggle blog theme',
10-
buttonClassName: 'blog-theme-switcher',
11-
tooltipText: 'Toggle theme',
12-
tooltipClassName: 'blog-theme-tooltip',
13-
},
14-
search: {
15-
label: 'Open blog search',
16-
buttonClassName: 'blog-search-button',
17-
tooltipText: 'Search blog',
18-
tooltipClassName: 'blog-search-tooltip',
19-
},
20-
leftSidebar: {
21-
label: 'Open blog links',
22-
buttonClassName: 'blog-bars-button',
23-
tooltipText: 'Blog menu',
24-
tooltipClassName: 'blog-sidebar-tooltip',
25-
},
8+
theme: {
9+
label: 'Toggle blog theme',
10+
buttonClassName: 'blog-theme-switcher',
11+
tooltipText: 'Toggle theme',
12+
tooltipClassName: 'blog-theme-tooltip',
13+
},
14+
search: {
15+
label: 'Open blog search',
16+
buttonClassName: 'blog-search-button',
17+
tooltipText: 'Search blog',
18+
tooltipClassName: 'blog-search-tooltip',
19+
},
20+
leftSidebar: {
21+
label: 'Open blog links',
22+
buttonClassName: 'blog-bars-button',
23+
tooltipText: 'Blog menu',
24+
tooltipClassName: 'blog-sidebar-tooltip',
25+
},
2626
};
2727

2828
interface ICommonHeaderIconBtn {
29-
handleClick: () => void;
30-
children: React.ReactNode;
31-
variant: keyof typeof variants;
32-
btnRef?: RefObject<HTMLButtonElement>;
29+
handleClick: () => void;
30+
children: React.ReactNode;
31+
variant: keyof typeof variants;
32+
btnRef?: RefObject<HTMLButtonElement>;
3333
}
3434

3535
export const getCommonBtnStyles = () =>
36-
twJoin(
37-
'focus-ring-base flex flex-row items-center rounded-full font-medium transition duration-100 ease-in-out',
38-
'focus-ring-colors-base hover:bg-black/10 dark:hover:bg-white/20',
39-
);
36+
twJoin(
37+
'focus-ring-base flex flex-row items-center rounded-full font-medium transition duration-100 ease-in-out',
38+
'focus-ring-colors-base hover:bg-black/10 dark:hover:bg-white/20',
39+
);
4040

4141
const CommonHeaderIconBtn = (props: ICommonHeaderIconBtn) => {
42-
const { handleClick, variant, btnRef, children } = props;
43-
44-
const { label, buttonClassName, tooltipClassName, tooltipText } = variants[variant];
45-
const btnStyles = getCommonBtnStyles();
46-
47-
return (
48-
<HeaderTooltip tooltipClassName={tooltipClassName} tooltipText={tooltipText}>
49-
<button
50-
type="button"
51-
aria-label={label}
52-
className={twJoin(buttonClassName, btnStyles, 'mr-2 p-2')}
53-
onClick={handleClick}
54-
ref={btnRef}
55-
>
56-
{children}
57-
</button>
58-
</HeaderTooltip>
59-
);
42+
const { handleClick, variant, btnRef, children } = props;
43+
44+
const { label, buttonClassName, tooltipClassName, tooltipText } = variants[variant];
45+
const btnStyles = getCommonBtnStyles();
46+
47+
return (
48+
<HeaderTooltip tooltipClassName={tooltipClassName} tooltipText={tooltipText}>
49+
<button
50+
type="button"
51+
aria-label={label}
52+
className={twJoin(buttonClassName, btnStyles, 'mr-2 p-2')}
53+
onClick={handleClick}
54+
ref={btnRef}
55+
>
56+
{children}
57+
</button>
58+
</HeaderTooltip>
59+
);
6060
};
6161

6262
export default CommonHeaderIconBtn;

packages/blog-starter-kit/themes/hashnode/components/header.tsx

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { twJoin } from 'tailwind-merge';
2-
import { lightOrDark } from '../utils/commonUtils';
32
import { useAppContext } from './contexts/appContext';
43
import { Button } from './custom-button';
54
import HeaderBlogSearch from './header-blog-search';
65
import HeaderLeftSidebar from './header-left-sidebar';
76
import PublicationLogo from './publication-logo';
87
import PublicationNavLinks from './publication-nav-links';
98
import PublicationSocialLinks from './publication-social-links';
9+
import { ToggleTheme } from './toggle-theme';
1010

1111
type Props = {
1212
currentMenuId?: string | null;
@@ -18,30 +18,21 @@ export const Header = (props: Props) => {
1818
const { publication } = useAppContext();
1919

2020
return (
21-
<header
22-
className="blog-header relative z-50 w-full border-b border-black/10 bg-white bg-opacity-70 dark:border-white/10 dark:bg-slate-900 dark:bg-opacity-70"
23-
>
21+
<header className="blog-header relative z-50 w-full border-b border-black/10 bg-white bg-opacity-70 dark:border-white/10 dark:bg-slate-900 dark:bg-opacity-70">
2422
<div className="container mx-auto px-2 md:px-4 2xl:px-10">
2523
<div className="relative z-40 flex flex-row items-center justify-between pb-2 pt-8 md:mb-4">
2624
<div className="flex flex-row items-center py-1">
2725
{/* Navigation for mobile view */}
28-
<div
29-
className={twJoin(
30-
'md:hidden','dark:text-white',
31-
)}
32-
>
26+
<div className={twJoin('md:hidden', 'dark:text-white')}>
3327
<HeaderLeftSidebar publication={publication} />
3428
</div>
3529
<div className="hidden md:block">
3630
<PublicationLogo publication={publication} size="lg" withProfileImage />
3731
</div>
3832
</div>
3933

40-
<div
41-
className={twJoin(
42-
'flex flex-row items-center','dark:text-white',
43-
)}
44-
>
34+
<div className={twJoin('flex flex-row items-center', 'dark:text-white')}>
35+
<ToggleTheme />
4536
<HeaderBlogSearch publication={publication} />
4637
<Button as="a" href="#" type="primary" label="Sign up" />
4738
</div>
@@ -55,15 +46,11 @@ export const Header = (props: Props) => {
5546
<div className="blog-sub-header" data-testid="blog-sub-header">
5647
{/* Desktop */}
5748
<div className="justify-betweem mx-0 mb-2 hidden w-full flex-row items-center md:flex">
58-
<PublicationSocialLinks
59-
links={publication.links}
60-
/>
49+
<PublicationSocialLinks links={publication.links} />
6150
</div>
6251
{/* Mobile view */}
6352
<div className="mb-2 flex w-full flex-col items-center md:hidden">
64-
<PublicationSocialLinks
65-
links={publication.links}
66-
/>
53+
<PublicationSocialLinks links={publication.links} />
6754
</div>
6855
</div>
6956

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from 'react';
2+
3+
export default class Moon extends React.Component {
4+
render() {
5+
return (
6+
<svg
7+
className={this.props.className}
8+
xmlns="http://www.w3.org/2000/svg"
9+
viewBox="0 0 24 24"
10+
fill="none"
11+
stroke="currentColor"
12+
strokeWidth="2"
13+
strokeLinecap="round"
14+
strokeLinejoin="round"
15+
>
16+
<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" />
17+
</svg>
18+
);
19+
}
20+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
3+
export default class Sun extends React.Component {
4+
render() {
5+
return (
6+
<svg
7+
xmlns="http://www.w3.org/2000/svg"
8+
viewBox="0 0 24 24"
9+
fill="none"
10+
stroke="currentColor"
11+
strokeWidth="2"
12+
strokeLinecap="round"
13+
strokeLinejoin="round"
14+
className={this.props.className}
15+
>
16+
<circle cx="12" cy="12" r="4" />
17+
<path d="M12 2v2" />
18+
<path d="M12 20v2" />
19+
<path d="m4.93 4.93 1.41 1.41" />
20+
<path d="m17.66 17.66 1.41 1.41" />
21+
<path d="M2 12h2" />
22+
<path d="M20 12h2" />
23+
<path d="m6.34 17.66-1.41 1.41" />
24+
<path d="m19.07 4.93-1.41 1.41" />
25+
</svg>
26+
);
27+
}
28+
}

0 commit comments

Comments
 (0)