Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding dark-to-light mode toggle #73

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Haimantika Could you please confirm whether the changes for this pull request have been completed?
Clicking on the toggle radio button in my local environment is not currently toggling the theme.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope it hasn’t. It is a WIP.

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React, { createContext, useContext, useState } from 'react';

export const ThemeContext:any = createContext({
theme: 'light',
toggleTheme: () => {},
});

export const useTheme = () => useContext(ThemeContext);

export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [theme, setTheme] = useState('light');

const toggleTheme = () => {
setTheme(currentTheme => currentTheme === 'light' ? 'dark' : 'light');
};

return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};


27 changes: 17 additions & 10 deletions packages/blog-starter-kit/themes/personal/components/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,28 @@ import { Analytics } from './analytics';
import { Integrations } from './integrations';
import { Meta } from './meta';
import { Scripts } from './scripts';
import { ThemeContext, ThemeProvider } from './contexts/themeContext';

type Props = {
children: React.ReactNode;
};

export const Layout = ({ children }: Props) => {
export const Layout = ({ children }: any) => {
return (
<>
<Meta />
<Scripts />
<div className="min-h-screen bg-white dark:bg-neutral-950">
<main>{children}</main>
</div>
<Analytics />
<Integrations />
</>
<ThemeProvider>
<ThemeContext.Consumer>
{()=>
<div>
<Meta />
<Scripts />
<div>
<main>{children}</main>
</div>
<Analytics />
<Integrations />
</div>}

</ThemeContext.Consumer>
</ThemeProvider>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { resizeImage } from '@starter-kit/utils/image';
import Link from 'next/link';
import { PublicationNavbarItem } from '../generated/graphql';
import { useAppContext } from './contexts/appContext';
import { useTheme } from './contexts/themeContext';
import { Layout } from './layout';

function hasUrl(
navbarItem: PublicationNavbarItem,
Expand All @@ -12,7 +14,7 @@ function hasUrl(

export const PersonalHeader = () => {
const { publication } = useAppContext();

const { theme, toggleTheme }:any = useTheme();
const navbarItems = publication.preferences.navbarItems.filter(hasUrl);
const visibleItems = navbarItems.slice(0, 2);
const hiddenItems = navbarItems.slice(2);
Expand Down Expand Up @@ -58,9 +60,10 @@ export const PersonalHeader = () => {
)}
</ul>
);

return (
<Layout>
<header className="grid grid-cols-2 items-center gap-5 ">
<div>
<div className="col-span-full md:col-span-1">
<h1>
<Link
Expand All @@ -85,13 +88,29 @@ export const PersonalHeader = () => {
</div>
<div className="col-span-full flex flex-row items-center justify-between gap-4 md:col-span-1 md:justify-end">
<nav>{navList}</nav>
<div className="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in">
<input
type="checkbox"
id="toggle"
className="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"
onChange={toggleTheme} // Change to onChange
checked={theme === 'dark'} // Reflects the current theme
/>
<label
htmlFor="toggle"
className="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"
></label>
</div>
{/* <Button
label=""
type="outline"
className="!p-2"
icon={<NewsletterPlusSVG className="w-5 h-5 fill-current" />}
/> */}
</div>
</div>
</header>
</Layout>

);
};
101 changes: 100 additions & 1 deletion packages/blog-starter-kit/themes/personal/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -537,10 +537,14 @@ export type IUser = {
dateJoined?: Maybe<Scalars['DateTime']['output']>;
/** Whether or not the user is deactivated. */
deactivated: Scalars['Boolean']['output'];
/** The users who are following this user */
followers: UserConnection;
/** The number of users that follow the requested user. Visible in the user's profile. */
followersCount: Scalars['Int']['output'];
/** The number of users that this user is following. Visible in the user's profile. */
followingsCount: Scalars['Int']['output'];
/** The users which this user is following */
follows: UserConnection;
/** The ID of the user. It can be used to identify the user. */
id: Scalars['ID']['output'];
/** The location of the user. */
Expand All @@ -564,6 +568,20 @@ export type IUser = {
};


/** Basic information about a user on Hashnode. */
export type IUserFollowersArgs = {
page: Scalars['Int']['input'];
pageSize: Scalars['Int']['input'];
};


/** Basic information about a user on Hashnode. */
export type IUserFollowsArgs = {
page: Scalars['Int']['input'];
pageSize: Scalars['Int']['input'];
};


/** Basic information about a user on Hashnode. */
export type IUserPostsArgs = {
filter?: InputMaybe<UserPostConnectionFilter>;
Expand Down Expand Up @@ -596,6 +614,8 @@ export type Mutation = {
addPostToSeries: AddPostToSeriesPayload;
/** Creates a new post. */
publishPost: PublishPostPayload;
/** Removes a post. */
removePost: RemovePostPayload;
/** Reschedule a post. */
reschedulePost?: Maybe<ScheduledPostPayload>;
subscribeToNewsletter: SubscribeToNewsletterPayload;
Expand All @@ -621,6 +641,11 @@ export type MutationPublishPostArgs = {
};


export type MutationRemovePostArgs = {
input: RemovePostInput;
};


export type MutationReschedulePostArgs = {
input: ReschedulePostInput;
};
Expand Down Expand Up @@ -671,10 +696,14 @@ export type MyUser = IUser & Node & {
deactivated: Scalars['Boolean']['output'];
/** Email address of the user. Only available to the authenticated user. */
email?: Maybe<Scalars['String']['output']>;
/** The users who are following this user */
followers: UserConnection;
/** The number of users that follow the requested user. Visible in the user's profile. */
followersCount: Scalars['Int']['output'];
/** The number of users that this user is following. Visible in the user's profile. */
followingsCount: Scalars['Int']['output'];
/** The users which this user is following */
follows: UserConnection;
/** The ID of the user. It can be used to identify the user. */
id: Scalars['ID']['output'];
/** The location of the user. */
Expand All @@ -701,6 +730,26 @@ export type MyUser = IUser & Node & {
};


/**
* Basic information about the authenticated user.
* User must be authenticated to use this type.
*/
export type MyUserFollowersArgs = {
page: Scalars['Int']['input'];
pageSize: Scalars['Int']['input'];
};


/**
* Basic information about the authenticated user.
* User must be authenticated to use this type.
*/
export type MyUserFollowsArgs = {
page: Scalars['Int']['input'];
pageSize: Scalars['Int']['input'];
};


/**
* Basic information about the authenticated user.
* User must be authenticated to use this type.
Expand Down Expand Up @@ -1180,7 +1229,7 @@ export type Publication = Node & {
author: User;
/** The canonical URL of the publication. */
canonicalURL: Scalars['String']['output'];
/** The description of the publication, used in og:description meta tag. */
/** The description of the publication, used in og:description meta tag. Fall backs to Publication.about.text if no SEO description is provided. */
descriptionSEO?: Maybe<Scalars['String']['output']>;
/** The title of the publication. Shown in blog home page. */
displayTitle?: Maybe<Scalars['String']['output']>;
Expand Down Expand Up @@ -1740,6 +1789,17 @@ export type RedirectionRule = {
type: HttpRedirectionType;
};

export type RemovePostInput = {
/** The ID of the post to remove. */
id: Scalars['ID']['input'];
};

export type RemovePostPayload = {
__typename?: 'RemovePostPayload';
/** The deleted post. */
post?: Maybe<Post>;
};

/**
* Contains basic information about the reply.
* A reply is a response to a comment.
Expand Down Expand Up @@ -1816,11 +1876,17 @@ export enum Scope {
CreatePro = 'create_pro',
ImportSubscribersToPublication = 'import_subscribers_to_publication',
PublicationAdmin = 'publication_admin',
PublishComment = 'publish_comment',
PublishDraft = 'publish_draft',
PublishPost = 'publish_post',
PublishReply = 'publish_reply',
RecommendPublications = 'recommend_publications',
RemoveComment = 'remove_comment',
RemoveReply = 'remove_reply',
Signup = 'signup',
UpdateComment = 'update_comment',
UpdatePost = 'update_post',
UpdateReply = 'update_reply',
WebhookAdmin = 'webhook_admin',
WritePost = 'write_post',
WriteSeries = 'write_series'
Expand Down Expand Up @@ -2211,6 +2277,8 @@ export type User = IUser & Node & {
dateJoined?: Maybe<Scalars['DateTime']['output']>;
/** Whether or not the user is deactivated. */
deactivated: Scalars['Boolean']['output'];
/** The users who are following this user */
followers: UserConnection;
/** The number of users that follow the requested user. Visible in the user's profile. */
followersCount: Scalars['Int']['output'];
/**
Expand All @@ -2220,6 +2288,8 @@ export type User = IUser & Node & {
following: Scalars['Boolean']['output'];
/** The number of users that this user is following. Visible in the user's profile. */
followingsCount: Scalars['Int']['output'];
/** The users which this user is following */
follows: UserConnection;
/**
* Wether or not this user follows the authenticated user.
* Returns false if the authenticated user this user.
Expand Down Expand Up @@ -2250,6 +2320,20 @@ export type User = IUser & Node & {
};


/** Basic information about a user on Hashnode. */
export type UserFollowersArgs = {
page: Scalars['Int']['input'];
pageSize: Scalars['Int']['input'];
};


/** Basic information about a user on Hashnode. */
export type UserFollowsArgs = {
page: Scalars['Int']['input'];
pageSize: Scalars['Int']['input'];
};


/** Basic information about a user on Hashnode. */
export type UserPostsArgs = {
filter?: InputMaybe<UserPostConnectionFilter>;
Expand All @@ -2266,6 +2350,21 @@ export type UserPublicationsArgs = {
first: Scalars['Int']['input'];
};

/**
* Connection for users to another user. Contains a list of nodes.
* Each node is a user.
* Page info contains information about pagination like hasNextPage and endCursor.
*/
export type UserConnection = PageConnection & {
__typename?: 'UserConnection';
/** A list of users */
nodes: Array<User>;
/** Information for page based pagination in users connection. */
pageInfo: OffsetPageInfo;
/** The total number of documents in the connection. */
totalDocuments: Scalars['Int']['output'];
};

/** Contains a node of type user and cursor for pagination. */
export type UserEdge = Edge & {
__typename?: 'UserEdge';
Expand Down