Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/react/src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export { default as useMentionsStore } from './mentionsStore';
export { default as usePinnedMessageStore } from './pinnedMessageStore';
export { default as useStarredMessageStore } from './starredMessageStore';
export { default as useSidebarStore } from './sidebarStore';
export { default as useThemeStore } from './themeStore';
9 changes: 9 additions & 0 deletions packages/react/src/store/themeStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { create } from 'zustand';

const useThemeStore = create((set) => ({
isDarkMode: false,
setIsDarkMode: (isDarkMode) => set(() => ({ isDarkMode })),
toggleTheme: () => set((state) => ({ isDarkMode: !state.isDarkMode })),
}));

export default useThemeStore;
16 changes: 15 additions & 1 deletion packages/react/src/views/ChatHeader/ChatHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
useStarredMessageStore,
useFileStore,
useSidebarStore,
useThemeStore,
} from '../../store';
import { DynamicHeader } from '../DynamicHeader';
import useFetchChatData from '../../hooks/useFetchChatData';
Expand All @@ -40,7 +41,7 @@ const ChatHeader = ({
className = '',
style = {},
optionConfig = {
surfaceItems: ['minmax', 'close'],
surfaceItems: ['minmax', 'theme', 'close'],
menuItems: [
'thread',
'mentions',
Expand Down Expand Up @@ -103,6 +104,10 @@ const ChatHeader = ({
const filtered = useMessageStore((state) => state.filtered);
const setFilter = useMessageStore((state) => state.setFilter);

// Theme toggle
const isDarkMode = useThemeStore((state) => state.isDarkMode);
const toggleTheme = useThemeStore((state) => state.toggleTheme);

const isThreadOpen = useMessageStore((state) => state.isThreadOpen);
const threadMainMessage = useMessageStore((state) => state.threadMainMessage);

Expand Down Expand Up @@ -244,6 +249,13 @@ const ChatHeader = ({
iconName: 'cross',
visible: isClosable,
},
theme: {
label: isDarkMode ? 'Light Mode' : 'Dark Mode',
id: 'theme',
onClick: toggleTheme,
iconName: isDarkMode ? 'sun' : 'moon',
visible: true,
},
thread: {
label: 'Threads',
id: 'thread',
Expand Down Expand Up @@ -312,6 +324,8 @@ const ChatHeader = ({
fullScreen,
isClosable,
isUserAuthenticated,
isDarkMode,
toggleTheme,
handleLogout,
setFullScreen,
setClosableState,
Expand Down
23 changes: 20 additions & 3 deletions packages/react/src/views/EmbeddedChat.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ import {
import { ChatLayout } from './ChatLayout';
import { ChatHeader } from './ChatHeader';
import { RCInstanceProvider } from '../context/RCInstance';
import { useUserStore, useLoginStore, useMessageStore } from '../store';
import {
useUserStore,
useLoginStore,
useMessageStore,
useThemeStore,
} from '../store';
import DefaultTheme from '../theme/DefaultTheme';
import { getTokenStorage } from '../lib/auth';
import { styles } from './EmbeddedChat.styles';
Expand Down Expand Up @@ -64,6 +69,15 @@ const EmbeddedChat = (props) => {
const { classNames, styleOverrides } = useComponentOverrides('EmbeddedChat');
const [fullScreen, setFullScreen] = useState(false);
const [isSynced, setIsSynced] = useState(!remoteOpt);

// Theme store for runtime theme toggle
const isDarkMode = useThemeStore((state) => state.isDarkMode);
const setIsDarkMode = useThemeStore((state) => state.setIsDarkMode);

// Initialize theme store from prop on mount
useEffect(() => {
setIsDarkMode(dark);
}, [dark, setIsDarkMode]);
const { getToken, saveToken, deleteToken } = getTokenStorage(secure);
const {
setIsUserAuthenticated,
Expand Down Expand Up @@ -225,11 +239,14 @@ const EmbeddedChat = (props) => {
if (!isSynced) return null;

return (
<ThemeProvider theme={theme || DefaultTheme} mode={dark ? 'dark' : 'light'}>
<ThemeProvider
theme={theme || DefaultTheme}
mode={isDarkMode ? 'dark' : 'light'}
>
<RCInstanceProvider value={RCContextValue}>
<Box
css={[
styles.embeddedchat(theme || DefaultTheme, dark),
styles.embeddedchat(theme || DefaultTheme, isDarkMode),
css`
width: ${width};
height: ${height};
Expand Down
14 changes: 14 additions & 0 deletions packages/ui-elements/src/components/Icon/icons/Moon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';

const Moon = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 32 32"
fill="currentColor"
{...props}
>
<path d="M16.1 4.04a1 1 0 0 0-1.02 1.52 9 9 0 0 1 1.44 4.9c0 5-4.03 9.04-9 9.04-.57 0-1.12-.05-1.66-.15a1 1 0 0 0-1.06 1.44 12 12 0 1 0 11.3-16.75zm-2.54 2.18a11 11 0 0 1 7.9 4.24 11 11 0 0 1-8.9 17.5 10 10 0 0 0 6.48-9.42c0-4.9-3.51-8.98-8.14-9.85a10.9 10.9 0 0 0 2.66-2.47z" />
</svg>
);

export default Moon;
14 changes: 14 additions & 0 deletions packages/ui-elements/src/components/Icon/icons/Sun.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';

const Sun = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 32 32"
fill="currentColor"
{...props}
>
<path d="M16 4a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0V5a1 1 0 0 1 1-1zm0 18a6 6 0 1 0 0-12 6 6 0 0 0 0 12zm0-2a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm10-4a1 1 0 0 1-1 1h-2a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1zM8 16a1 1 0 0 1-1 1H5a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1zm16.95-7.78a1 1 0 0 1 0 1.42l-1.41 1.41a1 1 0 0 1-1.42-1.42l1.42-1.41a1 1 0 0 1 1.41 0zM9.88 22.12a1 1 0 0 1 0 1.41l-1.41 1.42a1 1 0 0 1-1.42-1.42l1.42-1.41a1 1 0 0 1 1.41 0zm14.17 2.83a1 1 0 0 1-1.42 0l-1.41-1.41a1 1 0 0 1 1.41-1.42l1.42 1.42a1 1 0 0 1 0 1.41zM9.88 9.88a1 1 0 0 1-1.42 0L7.05 8.46a1 1 0 0 1 1.41-1.41l1.42 1.41a1 1 0 0 1 0 1.42zM16 24a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1z" />
</svg>
);

export default Sun;
4 changes: 4 additions & 0 deletions packages/ui-elements/src/components/Icon/icons/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ import Avatar from './Avatar';
import FormatText from './FormatText';
import Cog from './Cog';
import Team from './Team';
import Sun from './Sun';
import Moon from './Moon';

const icons = {
file: File,
Expand Down Expand Up @@ -132,6 +134,8 @@ const icons = {
avatar: Avatar,
'format-text': FormatText,
cog: Cog,
sun: Sun,
moon: Moon,
};

export default icons;