From 511ff253a68657780583769f5453fcc76134ccf1 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Fri, 12 Jul 2024 00:09:26 +0530
Subject: [PATCH 001/104] added layout editor vite project with base EC files
---
packages/layout_editor/.eslintrc.cjs | 23 +++
packages/layout_editor/.gitignore | 24 +++
packages/layout_editor/README.md | 1 +
packages/layout_editor/index.html | 13 ++
packages/layout_editor/package.json | 32 +++
packages/layout_editor/public/vite.svg | 1 +
packages/layout_editor/src/App.jsx | 8 +
packages/layout_editor/src/lib/textFormat.js | 7 +
packages/layout_editor/src/main.jsx | 9 +
packages/layout_editor/src/main.tsx | 9 +
.../layout_editor/src/theme/DefaultTheme.js | 120 +++++++++++
.../src/views/ChatHeader/ChatHeader.jsx | 193 ++++++++++++++++++
.../src/views/ChatHeader/ChatHeader.styles.js | 56 +++++
.../src/views/ChatInput/ChatInput.jsx | 67 ++++++
.../src/views/ChatInput/ChatInput.styles.js | 73 +++++++
.../ChatInput/ChatInputFormattingToolbar.jsx | 59 ++++++
.../src/views/ChatLayout/ChatLayout.jsx | 22 ++
.../src/views/ChatLayout/ChatLayout.styles.js | 18 ++
.../src/views/Chatbody/ChatBody.jsx | 22 ++
.../src/views/Chatbody/ChatBody.styles.js | 18 ++
.../layout_editor/src/views/GlobalStyles.jsx | 48 +++++
.../layout_editor/src/views/LayoutEditor.jsx | 23 +++
.../src/views/LayoutEditor.style.js | 16 ++
.../src/views/MessageList/MessageList.jsx | 22 ++
packages/layout_editor/src/vite-env.d.ts | 1 +
packages/layout_editor/tests/example.spec.ts | 18 ++
packages/layout_editor/tsconfig.json | 26 +++
packages/layout_editor/tsconfig.node.json | 11 +
packages/layout_editor/vite.config.ts | 10 +
29 files changed, 950 insertions(+)
create mode 100644 packages/layout_editor/.eslintrc.cjs
create mode 100644 packages/layout_editor/.gitignore
create mode 100644 packages/layout_editor/README.md
create mode 100644 packages/layout_editor/index.html
create mode 100644 packages/layout_editor/package.json
create mode 100644 packages/layout_editor/public/vite.svg
create mode 100644 packages/layout_editor/src/App.jsx
create mode 100644 packages/layout_editor/src/lib/textFormat.js
create mode 100644 packages/layout_editor/src/main.jsx
create mode 100644 packages/layout_editor/src/main.tsx
create mode 100644 packages/layout_editor/src/theme/DefaultTheme.js
create mode 100644 packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
create mode 100644 packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
create mode 100644 packages/layout_editor/src/views/ChatInput/ChatInput.jsx
create mode 100644 packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
create mode 100644 packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
create mode 100644 packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
create mode 100644 packages/layout_editor/src/views/ChatLayout/ChatLayout.styles.js
create mode 100644 packages/layout_editor/src/views/Chatbody/ChatBody.jsx
create mode 100644 packages/layout_editor/src/views/Chatbody/ChatBody.styles.js
create mode 100644 packages/layout_editor/src/views/GlobalStyles.jsx
create mode 100644 packages/layout_editor/src/views/LayoutEditor.jsx
create mode 100644 packages/layout_editor/src/views/LayoutEditor.style.js
create mode 100644 packages/layout_editor/src/views/MessageList/MessageList.jsx
create mode 100644 packages/layout_editor/src/vite-env.d.ts
create mode 100644 packages/layout_editor/tests/example.spec.ts
create mode 100644 packages/layout_editor/tsconfig.json
create mode 100644 packages/layout_editor/tsconfig.node.json
create mode 100644 packages/layout_editor/vite.config.ts
diff --git a/packages/layout_editor/.eslintrc.cjs b/packages/layout_editor/.eslintrc.cjs
new file mode 100644
index 000000000..7c50310c9
--- /dev/null
+++ b/packages/layout_editor/.eslintrc.cjs
@@ -0,0 +1,23 @@
+module.exports = {
+ root: true,
+ env: { browser: true, es2020: true },
+ extends: [
+ "eslint:recommended",
+ "plugin:react/jsx-runtime",
+ "plugin:react-hooks/recommended",
+ "plugin:react/recommended",
+ ],
+ ignorePatterns: ["dist", ".eslintrc.cjs"],
+ parserOptions: { ecmaVersion: "latest", sourceType: "module" },
+ settings: { react: { version: "18.2" } },
+ plugins: ["react-refresh"],
+ rules: {
+ "react/jsx-no-target-blank": "off",
+ "react-refresh/only-export-components": [
+ "warn",
+ { allowConstantExport: true },
+ ],
+ "react/prop-types": "off",
+ "react/no-unknown-property": ["error", { ignore: ["css"] }],
+ },
+};
diff --git a/packages/layout_editor/.gitignore b/packages/layout_editor/.gitignore
new file mode 100644
index 000000000..a547bf36d
--- /dev/null
+++ b/packages/layout_editor/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/packages/layout_editor/README.md b/packages/layout_editor/README.md
new file mode 100644
index 000000000..181d94ad9
--- /dev/null
+++ b/packages/layout_editor/README.md
@@ -0,0 +1 @@
+# E2E EmbeddedChat setup
diff --git a/packages/layout_editor/index.html b/packages/layout_editor/index.html
new file mode 100644
index 000000000..e4b78eae1
--- /dev/null
+++ b/packages/layout_editor/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite + React + TS
+
+
+
+
+
+
diff --git a/packages/layout_editor/package.json b/packages/layout_editor/package.json
new file mode 100644
index 000000000..bc9b512ff
--- /dev/null
+++ b/packages/layout_editor/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "layout_editor",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
+ "preview": "vite preview",
+ "test": "playwright test",
+ "format": "prettier --write 'src/' ",
+ "format:check": "prettier --check 'src/' "
+ },
+ "dependencies": {
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@types/node": "^20.11.19",
+ "@types/react": "^18.2.55",
+ "@types/react-dom": "^18.2.19",
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
+ "@typescript-eslint/parser": "^6.21.0",
+ "@vitejs/plugin-react": "^4.2.1",
+ "eslint": "^8.56.0",
+ "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-refresh": "^0.4.5",
+ "typescript": "^5.2.2",
+ "vite": "^5.1.0"
+ }
+}
diff --git a/packages/layout_editor/public/vite.svg b/packages/layout_editor/public/vite.svg
new file mode 100644
index 000000000..e7b8dfb1b
--- /dev/null
+++ b/packages/layout_editor/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/layout_editor/src/App.jsx b/packages/layout_editor/src/App.jsx
new file mode 100644
index 000000000..33a8002f1
--- /dev/null
+++ b/packages/layout_editor/src/App.jsx
@@ -0,0 +1,8 @@
+import React from "react";
+import LayoutEditor from "./views/LayoutEditor";
+
+const App = () => {
+ return ;
+};
+
+export default App;
diff --git a/packages/layout_editor/src/lib/textFormat.js b/packages/layout_editor/src/lib/textFormat.js
new file mode 100644
index 000000000..10ceb7f33
--- /dev/null
+++ b/packages/layout_editor/src/lib/textFormat.js
@@ -0,0 +1,7 @@
+export const formatter = [
+ { name: 'bold', pattern: '*{{text}}*' },
+ { name: 'italic', pattern: '_{{text}}_' },
+ { name: 'strike', pattern: '~{{text}}~' },
+ { name: 'code', pattern: '`{{text}}`' },
+ { name: 'multiline', pattern: '```\n{{text}}\n``` ' },
+];
diff --git a/packages/layout_editor/src/main.jsx b/packages/layout_editor/src/main.jsx
new file mode 100644
index 000000000..569fdf2fd
--- /dev/null
+++ b/packages/layout_editor/src/main.jsx
@@ -0,0 +1,9 @@
+import React from "react";
+import ReactDOM from "react-dom/client";
+import App from "./App.jsx";
+
+ReactDOM.createRoot(document.getElementById("root")).render(
+
+
+
+);
diff --git a/packages/layout_editor/src/main.tsx b/packages/layout_editor/src/main.tsx
new file mode 100644
index 000000000..577372105
--- /dev/null
+++ b/packages/layout_editor/src/main.tsx
@@ -0,0 +1,9 @@
+import React from "react";
+import ReactDOM from "react-dom/client";
+import App from "./App.jsx";
+
+ReactDOM.createRoot(document.getElementById("root")!).render(
+
+
+
+);
diff --git a/packages/layout_editor/src/theme/DefaultTheme.js b/packages/layout_editor/src/theme/DefaultTheme.js
new file mode 100644
index 000000000..bcf1ac888
--- /dev/null
+++ b/packages/layout_editor/src/theme/DefaultTheme.js
@@ -0,0 +1,120 @@
+const DefaultTheme = {
+ schemes: {
+ radius: '0.2rem',
+ common: {
+ black: 'hsl(0, 100%, 0%)',
+ white: 'hsl(0, 100%, 100%)',
+ },
+ light: {
+ background: 'hsl(0, 0%, 100%)',
+ foreground: 'hsl(240, 10%, 3.9%)',
+ card: 'hsl(0, 0%, 100%)',
+ cardForeground: 'hsl(240, 10%, 3.9%)',
+ popover: 'hsl(0, 0%, 100%)',
+ popoverForeground: 'hsl(240, 10%, 3.9%)',
+ primary: 'hsl(240, 5.9%, 10%)',
+ primaryForeground: 'hsl(0, 0%, 98%)',
+ secondary: 'hsl(240, 4.8%, 95.9%)',
+ secondaryForeground: 'hsl(240, 5.9%, 10%)',
+ muted: 'hsl(240, 4.8%, 95.9%)',
+ mutedForeground: 'hsl(240, 3.8%, 46.1%)',
+ accent: 'hsl(240, 4.8%, 95.9%)',
+ accentForeground: 'hsl(240, 5.9%, 10%)',
+ destructive: 'hsl(0, 84.2%, 60.2%)',
+ destructiveForeground: 'hsl(0, 0%, 98%)',
+ border: 'hsl(240, 5.9%, 90%)',
+ input: 'hsl(240, 5.9%, 90%)',
+ ring: 'hsl(240, 5.9%, 10%)',
+ warning: 'hsl(38, 92%, 50%)',
+ warningForeground: 'hsl(48, 96%, 89%)',
+ success: 'hsl(91, 60.4%, 81.2%)',
+ successForeground: 'hsl(90, 61.1%, 14.1%)',
+ info: 'hsl(214, 76.4%, 50.2%)',
+ infoForeground: 'hsl(214.3, 77.8%, 92.9%)',
+ },
+ dark: {
+ background: 'hsl(240, 10%, 3.9%)',
+ foreground: 'hsl(0, 0%, 98%)',
+ card: 'hsl(240, 10%, 3.9%)',
+ cardForeground: 'hsl(0, 0%, 98%)',
+ popover: 'hsl(240, 10%, 3.9%)',
+ popoverForeground: 'hsl(0, 0%, 98%)',
+ primary: 'hsl(0, 0%, 98%)',
+ primaryForeground: 'hsl(240, 5.9%, 10%)',
+ secondary: 'hsl(240, 3.7%, 15.9%)',
+ secondaryForeground: 'hsl(0, 0%, 98%)',
+ muted: 'hsl(240, 3.7%, 15.9%)',
+ mutedForeground: 'hsl(240, 5%, 64.9%)',
+ accent: 'hsl(240, 3.7%, 15.9%)',
+ accentForeground: 'hsl(0, 0%, 98%)',
+ destructive: 'hsl(0, 62.8%, 30.6%)',
+ destructiveForeground: 'hsl(0, 0%, 98%)',
+ border: 'hsl(240, 3.7%, 15.9%)',
+ input: 'hsl(240, 3.7%, 15.9%)',
+ ring: 'hsl(240, 4.9%, 83.9%)',
+ warning: 'hsl(48, 96%, 89%)',
+ warningForeground: 'hsl(38, 92%, 50%)',
+ success: 'hsl(90, 61.1%, 14.1%)',
+ successForeground: 'hsl(90, 60%, 90.2%)',
+ info: 'hsl(214.3, 77.8%, 92.9%)',
+ infoForeground: 'hsl(214.4, 75.8%, 19.4%)',
+ },
+ },
+
+ breakpoints: {
+ xs: 0,
+ sm: 600,
+ md: 900,
+ lg: 1200,
+ xl: 1536,
+ },
+ components: {},
+
+ typography: {
+ default: {
+ fontFamily: "'Times New Roman', serif",
+ fontSize: 16,
+ fontWeightRegular: 400,
+ },
+ h1: {
+ fontSize: '2rem',
+ fontWeight: 800,
+ },
+ h2: {
+ fontSize: '1.5rem',
+ fontWeight: 800,
+ },
+ h3: {
+ fontSize: '1.3rem',
+ fontWeight: 400,
+ },
+ h4: {
+ fontSize: '1rem',
+ fontWeight: 400,
+ },
+ h5: {
+ fontSize: '0.83rem',
+ fontWeight: 400,
+ },
+ h6: {
+ fontSize: '0.67rem',
+ fontWeight: 500,
+ },
+ },
+ shadows: [
+ 'none',
+ 'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
+ 'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
+ ],
+ zIndex: {
+ divider: 1000,
+ body: 1100,
+ general: 1200,
+ menu: 1300,
+ tooltip: 1400,
+ modal: 1500,
+ toastbar: 1600,
+ },
+};
+
+export default DefaultTheme;
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
new file mode 100644
index 000000000..c60f20614
--- /dev/null
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -0,0 +1,193 @@
+import React from "react";
+import {
+ Heading,
+ Tooltip,
+ Box,
+ Icon,
+ ActionButton,
+ Menu,
+} from "@embeddedchat/ui-elements";
+import useChatHeaderStyles from "./ChatHeader.styles";
+
+const ChatHeader = ({
+ optionConfig = {
+ chatOptions: [
+ "minmax",
+ "thread",
+ "mentions",
+ "starred",
+ "pinned",
+ "files",
+ "close",
+ "members",
+ "search",
+ "rInfo",
+ "logout",
+ ],
+
+ threshold: 7,
+ },
+}) => {
+ const { chatOptions, threshold } = optionConfig;
+
+ const styles = useChatHeaderStyles();
+ const menuMap = {
+ minmax: (
+
+ {}}
+ ghost
+ display="inline"
+ square
+ size="medium"
+ >
+
+
+
+ ),
+
+ close: (
+
+ {}}
+ ghost
+ display="inline"
+ square
+ size="medium"
+ >
+
+
+
+ ),
+ thread: (
+
+ {}}>
+
+
+
+ ),
+
+ mentions: (
+
+ {}}>
+
+
+
+ ),
+
+ starred: (
+
+ {}}>
+
+
+
+ ),
+
+ pinned: (
+
+ {}}>
+
+
+
+ ),
+
+ members: (
+
+ {}}>
+
+
+
+ ),
+
+ files: (
+
+ {}}>
+
+
+
+ ),
+
+ search: (
+
+ {}}>
+
+
+
+ ),
+
+ rInfo: (
+
+ {}}>
+
+
+
+ ),
+
+ logout: (
+
+ {}}>
+
+
+
+ ),
+ };
+
+ const menuOptions = chatOptions
+ .slice(threshold)
+ .map((key) => {
+ const tool = menuMap[key];
+
+ if (!tool) {
+ return null;
+ }
+
+ const { onClick } = tool.props.children.props;
+ const { name: icon } = tool.props.children.props.children.props;
+ const { text } = tool.props;
+
+ if (onClick && icon && text) {
+ return {
+ id: key,
+ action: onClick,
+ label: text,
+ icon,
+ };
+ }
+
+ return null;
+ })
+ .filter((option) => option !== null);
+
+ return (
+
+
+
+
+
+
+ general
+
+
+
+ Channel description
+
+
+
+
+ {chatOptions.slice(0, threshold).map((key) => menuMap[key])}
+ {menuOptions.length > 0 && }
+
+
+
+ );
+};
+
+export default ChatHeader;
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js b/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
new file mode 100644
index 000000000..0e5b04c98
--- /dev/null
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
@@ -0,0 +1,56 @@
+import { css } from '@emotion/react';
+import { darken, useTheme } from '@embeddedchat/ui-elements';
+
+const rowCentreAlign = css`
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+`;
+
+const useChatHeaderStyles = () => {
+ const { theme, mode, colors } = useTheme();
+ const clearSpacing = css`
+ margin: 0;
+ padding: 0;
+ `;
+
+ const chatHeaderChild = css`
+ ${rowCentreAlign}
+ padding: 0 0.75rem;
+ justify-content: space-between;
+ width: 100%;
+ `;
+
+ const chatHeaderParent = css`
+ background-color: ${mode === 'light'
+ ? darken(colors.background, 0.03)
+ : colors.secondary};
+ width: 100%;
+ z-index: ${theme.zIndex.general};
+ display: flex;
+ flex-direction: column;
+ padding: 0.75rem;
+ box-shadow: ${theme.shadows[1]};
+ `;
+
+ const channelDescription = css`
+ ${rowCentreAlign}
+ gap: 0.5rem;
+ `;
+
+ const chatHeaderIconRow = css`
+ ${rowCentreAlign}
+ position:relative;
+ gap: 0.5rem;
+ `;
+
+ return {
+ clearSpacing,
+ chatHeaderChild,
+ chatHeaderParent,
+ channelDescription,
+ chatHeaderIconRow,
+ };
+};
+
+export default useChatHeaderStyles;
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInput.jsx b/packages/layout_editor/src/views/ChatInput/ChatInput.jsx
new file mode 100644
index 000000000..24532162b
--- /dev/null
+++ b/packages/layout_editor/src/views/ChatInput/ChatInput.jsx
@@ -0,0 +1,67 @@
+import React, { useRef } from "react";
+import { css } from "@emotion/react";
+import { Box, Input, ActionButton } from "@embeddedchat/ui-elements";
+import { useChatInputStyles } from "./ChatInput.styles";
+import ChatInputFormattingToolbar from "./ChatInputFormattingToolbar";
+
+const ChatInput = () => {
+ const styles = useChatInputStyles();
+
+ const inputRef = useRef(null);
+ const messageRef = useRef(null);
+ const chatInputContainer = useRef(null);
+
+ const handleBlur = () => {
+ if (chatInputContainer.current) {
+ chatInputContainer.current.classList.remove("focused");
+ }
+ };
+
+ const handleFocus = () => {
+ if (chatInputContainer.current) {
+ chatInputContainer.current.classList.add("focused");
+ }
+ };
+
+ return (
+
+
+
+
+
+
+ {}}
+ type="primary"
+ icon="send"
+ />
+
+
+
+
+
+ );
+};
+
+export default ChatInput;
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js b/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
new file mode 100644
index 000000000..f9be35ba0
--- /dev/null
+++ b/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
@@ -0,0 +1,73 @@
+import { css } from "@emotion/react";
+import { darken, useTheme } from "@embeddedchat/ui-elements";
+
+export const useChatInputStyles = () => {
+ const { theme, colors } = useTheme();
+
+ const inputWithFormattingBox = css`
+ border: 1px solid ${colors.border};
+ border-radius: ${theme.schemes.radius};
+ margin: 0.5rem 2rem 1rem 2rem;
+ &.focused {
+ border: ${`1.5px solid ${colors.ring}`};
+ }
+ `;
+
+ const inputBox = css`
+ display: flex;
+ align-items: center;
+ flex-direction: row;
+ padding: 0.5rem;
+ `;
+
+ const textInput = css`
+ flex: 1;
+ word-wrap: break-word;
+ white-space: pre-wrap;
+ overflow: auto;
+ overflow-x: hidden;
+ resize: none;
+ border: none;
+ outline: none;
+ font-size: 14px;
+
+ &:focus {
+ border: none;
+ outline: none;
+ }
+
+ &:disabled {
+ cursor: not-allowed;
+ }
+
+ &::placeholder {
+ padding-left: 5px;
+ }
+ `;
+
+ return {
+ inputWithFormattingBox,
+ inputBox,
+ textInput,
+ };
+};
+
+export const useChatInputFormattingToolbarStyles = () => {
+ const { theme, mode, colors } = useTheme();
+
+ const chatFormat = css`
+ bottom: 0;
+ padding: 0.2rem;
+ align-items: center;
+ background-color: ${mode === "light"
+ ? darken(colors.background, 0.03)
+ : colors.secondary};
+ display: flex;
+ position: relative;
+ flex-direction: row;
+ gap: 0.375rem;
+ border-radius: 0 0 ${theme.schemes.radius} ${theme.schemes.radius};
+ `;
+
+ return { chatFormat };
+};
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx b/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
new file mode 100644
index 000000000..26dc55083
--- /dev/null
+++ b/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
@@ -0,0 +1,59 @@
+import React from "react";
+import { Box, Icon, ActionButton, Tooltip } from "@embeddedchat/ui-elements";
+import { formatter } from "../../lib/textFormat";
+import { useChatInputFormattingToolbarStyles } from "./ChatInput.styles";
+
+const ChatInputFormattingToolbar = ({
+ toolConfig = ["emoji", "formatter", "audio", "video", "file"],
+}) => {
+ const styles = useChatInputFormattingToolbarStyles();
+ const toolOptions = toolConfig;
+
+ const chatToolMap = {
+ emoji: (
+
+
+
+
+
+
+
+ ),
+ audio: (
+
+
+
+
+
+ ),
+ video: (
+
+
+
+
+
+ ),
+ file: (
+
+
+
+
+
+ ),
+ formatter: formatter.map((item) => (
+
+
+
+
+
+ )),
+ };
+
+ return (
+
+ {toolOptions.map((key) => chatToolMap[key])}
+
+ );
+};
+
+export default ChatInputFormattingToolbar;
diff --git a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
new file mode 100644
index 000000000..6e37d26e5
--- /dev/null
+++ b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
@@ -0,0 +1,22 @@
+import React from 'react';
+import { Box } from '@embeddedchat/ui-elements';
+import ChatBody from '../Chatbody/ChatBody';
+import ChatInput from '../ChatInput/ChatInput';
+import styles from './ChatLayout.styles';
+
+const ChatLayout = () => (
+
+
+
+
+
+
+
+
+ {/* {showMembers && }
+ )} */}
+
+
+);
+
+export default ChatLayout;
diff --git a/packages/layout_editor/src/views/ChatLayout/ChatLayout.styles.js b/packages/layout_editor/src/views/ChatLayout/ChatLayout.styles.js
new file mode 100644
index 000000000..12a45957b
--- /dev/null
+++ b/packages/layout_editor/src/views/ChatLayout/ChatLayout.styles.js
@@ -0,0 +1,18 @@
+import { css } from '@emotion/react';
+
+const styles = {
+ layout: css`
+ flex-basis: 100%;
+ display: flex;
+ overflow: hidden;
+ `,
+
+ chatMain: css`
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+ position: relative;
+ `,
+};
+
+export default styles;
diff --git a/packages/layout_editor/src/views/Chatbody/ChatBody.jsx b/packages/layout_editor/src/views/Chatbody/ChatBody.jsx
new file mode 100644
index 000000000..ccc8790f0
--- /dev/null
+++ b/packages/layout_editor/src/views/Chatbody/ChatBody.jsx
@@ -0,0 +1,22 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { Box } from '@embeddedchat/ui-elements';
+import { useChatbodyStyles } from './ChatBody.styles';
+import MessageList from '../MessageList/MessageList';
+
+const ChatBody = () => {
+ const styles = useChatbodyStyles();
+
+ return (
+
+
+
+ );
+};
+
+export default ChatBody;
+
+ChatBody.propTypes = {
+ anonymousMode: PropTypes.bool,
+ showRoles: PropTypes.bool,
+};
diff --git a/packages/layout_editor/src/views/Chatbody/ChatBody.styles.js b/packages/layout_editor/src/views/Chatbody/ChatBody.styles.js
new file mode 100644
index 000000000..5ada0d0ca
--- /dev/null
+++ b/packages/layout_editor/src/views/Chatbody/ChatBody.styles.js
@@ -0,0 +1,18 @@
+import { css } from '@emotion/react';
+
+export const useChatbodyStyles = () => {
+ const chatbodyContainer = css`
+ flex: 1;
+ word-break: break-all;
+ overflow: auto;
+ overflow-x: hidden;
+ display: flex;
+ flex-direction: column-reverse;
+ max-height: 600px;
+ position: relative;
+ padding-top: 70px;
+ margin-top: 0.25rem;
+ `;
+
+ return { chatbodyContainer };
+};
diff --git a/packages/layout_editor/src/views/GlobalStyles.jsx b/packages/layout_editor/src/views/GlobalStyles.jsx
new file mode 100644
index 000000000..d17c40143
--- /dev/null
+++ b/packages/layout_editor/src/views/GlobalStyles.jsx
@@ -0,0 +1,48 @@
+import React from 'react';
+import { css, Global } from '@emotion/react';
+import { useTheme, alpha } from '@embeddedchat/ui-elements';
+
+const useStyles = (colors, theme) => css`
+ .ec-embedded-chat * {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ }
+
+ .ec-embedded-chat body {
+ font-family: ${theme.typography.default.fontFamily};
+ font-size: ${theme.typography.default.fontSize}px;
+ font-weight: ${theme.typography.default.fontWeightRegular};
+ }
+
+ .ec-embedded-chat a {
+ color: ${colors.foreground};
+ }
+
+ .ec-embedded-chat ::-webkit-scrollbar {
+ width: 4px;
+ height: 7.7px;
+ }
+
+ .ec-embedded-chat ::-webkit-scrollbar-thumb {
+ background: ${alpha(colors.primary, 0.5)};
+ border-radius: 4px;
+ }
+
+ .ec-embedded-chat ::-webkit-scrollbar-thumb:hover {
+ background: ${colors.primary};
+ }
+
+ .ec-embedded-chat ::-webkit-scrollbar-button {
+ display: none;
+ }
+`;
+
+const GlobalStyles = () => {
+ const { theme, colors } = useTheme();
+ const styles = useStyles(colors, theme);
+
+ return ;
+};
+
+export default GlobalStyles;
diff --git a/packages/layout_editor/src/views/LayoutEditor.jsx b/packages/layout_editor/src/views/LayoutEditor.jsx
new file mode 100644
index 000000000..0807a3293
--- /dev/null
+++ b/packages/layout_editor/src/views/LayoutEditor.jsx
@@ -0,0 +1,23 @@
+import React from "react";
+import DefaultTheme from "../theme/DefaultTheme";
+import { Box, ThemeProvider } from "@embeddedchat/ui-elements";
+import { styles } from "./LayoutEditor.style";
+import ChatLayout from "./ChatLayout/ChatLayout";
+import ChatHeader from "./ChatHeader/ChatHeader";
+import GlobalStyles from "./GlobalStyles";
+
+const LayoutEditor = () => (
+
+
+
+
+
+
+
+
+);
+
+export default LayoutEditor;
diff --git a/packages/layout_editor/src/views/LayoutEditor.style.js b/packages/layout_editor/src/views/LayoutEditor.style.js
new file mode 100644
index 000000000..7a03f61ca
--- /dev/null
+++ b/packages/layout_editor/src/views/LayoutEditor.style.js
@@ -0,0 +1,16 @@
+import { css } from '@emotion/react';
+
+export const styles = {
+ embeddedchat: (theme, dark) => css`
+ width: 100%;
+ height: 95vh;
+ position: relative;
+ background: ${theme.schemes[dark ? 'dark' : 'light'].background};
+ color: ${theme.schemes[dark ? 'dark' : 'light'].foreground};
+ display: flex;
+ flex-direction: column;
+ border: ${`1.5px solid ${theme.schemes[dark ? 'dark' : 'light'].border}`};
+ border-radius: ${theme.schemes.radius};
+ overflow: hidden;
+ `,
+};
diff --git a/packages/layout_editor/src/views/MessageList/MessageList.jsx b/packages/layout_editor/src/views/MessageList/MessageList.jsx
new file mode 100644
index 000000000..26248259d
--- /dev/null
+++ b/packages/layout_editor/src/views/MessageList/MessageList.jsx
@@ -0,0 +1,22 @@
+import React from "react";
+import PropTypes from "prop-types";
+import { css } from "@emotion/react";
+import { Box, Icon } from "@embeddedchat/ui-elements";
+
+const MessageList = () => (
+
+
+ Ready to chat? Login now to join the fun
+
+);
+
+MessageList.propTypes = {
+ messages: PropTypes.arrayOf(PropTypes.shape),
+};
+
+export default MessageList;
diff --git a/packages/layout_editor/src/vite-env.d.ts b/packages/layout_editor/src/vite-env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/packages/layout_editor/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/packages/layout_editor/tests/example.spec.ts b/packages/layout_editor/tests/example.spec.ts
new file mode 100644
index 000000000..e309eeb4e
--- /dev/null
+++ b/packages/layout_editor/tests/example.spec.ts
@@ -0,0 +1,18 @@
+import { test, expect } from '@playwright/test';
+
+test('EmbeddedChat should render', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('.ec-embedded-chat')).toBeVisible();
+});
+
+test('EmbeddedChat has a title', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('.ec-chat-header--channelName')).toHaveText('Login to chat');
+});
+
+test('EmbeddedChat has messages', async ({ page }) => {
+ await page.goto('/');
+
+ await page.waitForSelector('.ec-message');
+ expect(await page.locator('.ec-message').count()).toBeGreaterThan(0);
+});
diff --git a/packages/layout_editor/tsconfig.json b/packages/layout_editor/tsconfig.json
new file mode 100644
index 000000000..1ae247aeb
--- /dev/null
+++ b/packages/layout_editor/tsconfig.json
@@ -0,0 +1,26 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+ "allowJs": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src"],
+ "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/packages/layout_editor/tsconfig.node.json b/packages/layout_editor/tsconfig.node.json
new file mode 100644
index 000000000..97ede7ee6
--- /dev/null
+++ b/packages/layout_editor/tsconfig.node.json
@@ -0,0 +1,11 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true,
+ "strict": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/packages/layout_editor/vite.config.ts b/packages/layout_editor/vite.config.ts
new file mode 100644
index 000000000..028287cd5
--- /dev/null
+++ b/packages/layout_editor/vite.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react()],
+ define: {
+ 'process.env': {}
+ }
+})
From bed4f5512becd0923be3185afa2471fdbb238275 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Fri, 12 Jul 2024 17:12:47 +0530
Subject: [PATCH 002/104] setup basic drag drop
---
packages/layout_editor/package.json | 2 +
.../src/views/ChatHeader/ChatHeader.jsx | 191 +++++-------------
.../ChatHeader/SortableHeaderOptions.jsx | 123 +++++++++++
3 files changed, 176 insertions(+), 140 deletions(-)
create mode 100644 packages/layout_editor/src/views/ChatHeader/SortableHeaderOptions.jsx
diff --git a/packages/layout_editor/package.json b/packages/layout_editor/package.json
index bc9b512ff..c7b1c506f 100644
--- a/packages/layout_editor/package.json
+++ b/packages/layout_editor/package.json
@@ -13,6 +13,8 @@
"format:check": "prettier --check 'src/' "
},
"dependencies": {
+ "@dnd-kit/core": "^6.1.0",
+ "@dnd-kit/sortable": "^8.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
index c60f20614..e620e59d0 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -1,17 +1,25 @@
-import React from "react";
-import {
- Heading,
- Tooltip,
- Box,
- Icon,
- ActionButton,
- Menu,
-} from "@embeddedchat/ui-elements";
+import React, { useState } from "react";
+import { Heading, Box, Icon } from "@embeddedchat/ui-elements";
import useChatHeaderStyles from "./ChatHeader.styles";
+import SortableHeaderOptions from "./SortableHeaderOptions";
+import {
+ DndContext,
+ closestCenter,
+ KeyboardSensor,
+ PointerSensor,
+ useSensor,
+ useSensors,
+} from "@dnd-kit/core";
+import {
+ SortableContext,
+ sortableKeyboardCoordinates,
+ horizontalListSortingStrategy,
+ arrayMove,
+} from "@dnd-kit/sortable";
const ChatHeader = ({
optionConfig = {
- chatOptions: [
+ menuOptions: [
"minmax",
"thread",
"mentions",
@@ -24,140 +32,31 @@ const ChatHeader = ({
"rInfo",
"logout",
],
-
- threshold: 7,
},
}) => {
- const { chatOptions, threshold } = optionConfig;
-
- const styles = useChatHeaderStyles();
- const menuMap = {
- minmax: (
-
- {}}
- ghost
- display="inline"
- square
- size="medium"
- >
-
-
-
- ),
-
- close: (
-
- {}}
- ghost
- display="inline"
- square
- size="medium"
- >
-
-
-
- ),
- thread: (
-
- {}}>
-
-
-
- ),
-
- mentions: (
-
- {}}>
-
-
-
- ),
-
- starred: (
-
- {}}>
-
-
-
- ),
-
- pinned: (
-
- {}}>
-
-
-
- ),
+ const [menuOptions, setMenuOptions] = useState(optionConfig.menuOptions);
- members: (
-
- {}}>
-
-
-
- ),
-
- files: (
-
- {}}>
-
-
-
- ),
+ const sensors = useSensors(
+ useSensor(PointerSensor),
+ useSensor(KeyboardSensor, {
+ coordinateGetter: sortableKeyboardCoordinates,
+ })
+ );
- search: (
-
- {}}>
-
-
-
- ),
+ const handleDragEnd = (event) => {
+ const { active, over } = event;
- rInfo: (
-
- {}}>
-
-
-
- ),
+ if (active.id !== over.id) {
+ setMenuOptions((items) => {
+ const oldIndex = items.indexOf(active.id);
+ const newIndex = items.indexOf(over.id);
- logout: (
-
- {}}>
-
-
-
- ),
+ return arrayMove(items, oldIndex, newIndex);
+ });
+ }
};
- const menuOptions = chatOptions
- .slice(threshold)
- .map((key) => {
- const tool = menuMap[key];
-
- if (!tool) {
- return null;
- }
-
- const { onClick } = tool.props.children.props;
- const { name: icon } = tool.props.children.props.children.props;
- const { text } = tool.props;
-
- if (onClick && icon && text) {
- return {
- id: key,
- action: onClick,
- label: text,
- icon,
- };
- }
-
- return null;
- })
- .filter((option) => option !== null);
+ const styles = useChatHeaderStyles();
return (
@@ -181,10 +80,22 @@ const ChatHeader = ({
-
- {chatOptions.slice(0, threshold).map((key) => menuMap[key])}
- {menuOptions.length > 0 && }
-
+
+
+
+ {menuOptions.map((key) => (
+
+ ))}
+
+
+
);
diff --git a/packages/layout_editor/src/views/ChatHeader/SortableHeaderOptions.jsx b/packages/layout_editor/src/views/ChatHeader/SortableHeaderOptions.jsx
new file mode 100644
index 000000000..d3a35effc
--- /dev/null
+++ b/packages/layout_editor/src/views/ChatHeader/SortableHeaderOptions.jsx
@@ -0,0 +1,123 @@
+import React from "react";
+import { useSortable } from "@dnd-kit/sortable";
+import { Box, Tooltip, ActionButton, Icon } from "@embeddedchat/ui-elements";
+import { CSS } from "@dnd-kit/utilities";
+
+const SortableHeaderOptions = (props) => {
+ const menuMap = {
+ minmax: (
+
+ {}}
+ ghost
+ display="inline"
+ square
+ size="medium"
+ >
+
+
+
+ ),
+
+ close: (
+
+ {}}
+ ghost
+ display="inline"
+ square
+ size="medium"
+ >
+
+
+
+ ),
+ thread: (
+
+ {}}>
+
+
+
+ ),
+
+ mentions: (
+
+ {}}>
+
+
+
+ ),
+
+ starred: (
+
+ {}}>
+
+
+
+ ),
+
+ pinned: (
+
+ {}}>
+
+
+
+ ),
+
+ members: (
+
+ {}}>
+
+
+
+ ),
+
+ files: (
+
+ {}}>
+
+
+
+ ),
+
+ search: (
+
+ {}}>
+
+
+
+ ),
+
+ rInfo: (
+
+ {}}>
+
+
+
+ ),
+
+ logout: (
+
+ {}}>
+
+
+
+ ),
+ };
+ const { attributes, listeners, setNodeRef, transform, transition } =
+ useSortable({ id: props.id });
+
+ const style = {
+ transform: CSS.Transform.toString(transform),
+ transition,
+ };
+
+ return (
+
+ {menuMap[props.id]}
+
+ );
+};
+
+export default SortableHeaderOptions;
From 6153ba1e9e454c83fc93a23cf2900a8dd7bffad7 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Fri, 12 Jul 2024 23:27:28 +0530
Subject: [PATCH 003/104] added sortable menu
---
.../src/components/SortableMenu/Menu.jsx | 47 +++++
.../components/SortableMenu/Menu.styles.js | 59 +++++++
.../src/components/SortableMenu/MenuItem.jsx | 36 ++++
.../src/components/SortableMenu/index.js | 1 +
.../src/views/ChatHeader/ChatHeader.jsx | 164 ++++++++++++++++--
.../src/views/ChatHeader/ChatHeader.styles.js | 89 +++++-----
.../src/views/ChatHeader/HeaderOptions.jsx | 22 +++
.../ChatHeader/SortableHeaderOptions.jsx | 123 -------------
8 files changed, 359 insertions(+), 182 deletions(-)
create mode 100644 packages/layout_editor/src/components/SortableMenu/Menu.jsx
create mode 100644 packages/layout_editor/src/components/SortableMenu/Menu.styles.js
create mode 100644 packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
create mode 100644 packages/layout_editor/src/components/SortableMenu/index.js
create mode 100644 packages/layout_editor/src/views/ChatHeader/HeaderOptions.jsx
delete mode 100644 packages/layout_editor/src/views/ChatHeader/SortableHeaderOptions.jsx
diff --git a/packages/layout_editor/src/components/SortableMenu/Menu.jsx b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
new file mode 100644
index 000000000..41ac15518
--- /dev/null
+++ b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
@@ -0,0 +1,47 @@
+import React from "react";
+import { css } from "@emotion/react";
+import {
+ Box,
+ ActionButton,
+ Tooltip,
+ useTheme,
+} from "@embeddedchat/ui-elements";
+import MenuItem from "./MenuItem";
+import { getMenuStyles } from "./Menu.styles";
+import {
+ SortableContext,
+ verticalListSortingStrategy,
+} from "@dnd-kit/sortable";
+
+const Menu = ({
+ options = [],
+ tooltip = { isToolTip: true, position: "bottom", text: "Options" },
+ size = "medium",
+}) => {
+ const theme = useTheme();
+ const styles = getMenuStyles(theme);
+
+ return (
+
+
+
+
+
+
+ {options.map((option, idx) => (
+
+ ))}
+
+
+
+ );
+};
+
+export default Menu;
diff --git a/packages/layout_editor/src/components/SortableMenu/Menu.styles.js b/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
new file mode 100644
index 000000000..275476956
--- /dev/null
+++ b/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
@@ -0,0 +1,59 @@
+import { css } from "@emotion/react";
+import { lighten, darken } from "@embeddedchat/ui-elements";
+
+export const getMenuStyles = (customTheme) => {
+ const { theme, colors } = customTheme;
+
+ const styles = {
+ wrapper: css`
+ position: relative;
+ `,
+
+ container: css`
+ position: absolute;
+ top: 100%;
+ right: 0;
+ display: flex;
+ flex-direction: column;
+ width: fit-content;
+ height: fit-content;
+ z-index: ${theme.zIndex.menu};
+ border-radius: 0.2em;
+ padding: 0.5rem 0;
+ box-shadow: ${theme.shadows[1]};
+ background-color: ${colors.background};
+ `,
+ };
+
+ return styles;
+};
+
+export const getMenuItemStyles = (customTheme) => {
+ const { mode, colors } = customTheme;
+
+ const styles = {
+ item: css`
+ font-size: 14px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: flex-start;
+ padding: 0.25em 0.75em;
+ white-space: nowrap;
+ gap: 0.2rem;
+ color: ${colors.foreground};
+ &:hover {
+ background-color: ${mode === "light"
+ ? darken(colors.background, 0.05)
+ : lighten(colors.background, 2)};
+ cursor: pointer;
+ }
+ `,
+ disabled: css`
+ cursor: not-allowed !important;
+ color: ${colors.mutedForeground};
+ `,
+ };
+
+ return styles;
+};
diff --git a/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx b/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
new file mode 100644
index 000000000..3c90be787
--- /dev/null
+++ b/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
@@ -0,0 +1,36 @@
+import React from "react";
+import { Box, Icon, useTheme } from "@embeddedchat/ui-elements";
+
+import { getMenuItemStyles } from "./Menu.styles";
+import { useSortable } from "@dnd-kit/sortable";
+import { CSS } from "@dnd-kit/utilities";
+
+
+const MenuItem = ({ id, icon, label, action, disabled }) => {
+ const theme = useTheme();
+ const styles = getMenuItemStyles(theme);
+
+ const { attributes, listeners, setNodeRef, transform, transition } =
+ useSortable({ id });
+
+ const style = {
+ transform: CSS.Transform.toString(transform),
+ transition,
+ };
+
+ return (
+
+
+ {label}
+
+ );
+};
+
+export default MenuItem;
diff --git a/packages/layout_editor/src/components/SortableMenu/index.js b/packages/layout_editor/src/components/SortableMenu/index.js
new file mode 100644
index 000000000..a2620aa05
--- /dev/null
+++ b/packages/layout_editor/src/components/SortableMenu/index.js
@@ -0,0 +1 @@
+export { default as Menu } from "./Menu";
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
index e620e59d0..228cde7b9 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -1,7 +1,15 @@
import React, { useState } from "react";
-import { Heading, Box, Icon } from "@embeddedchat/ui-elements";
-import useChatHeaderStyles from "./ChatHeader.styles";
-import SortableHeaderOptions from "./SortableHeaderOptions";
+import {
+ Heading,
+ Box,
+ Icon,
+ ActionButton,
+ Tooltip,
+ useTheme,
+} from "@embeddedchat/ui-elements";
+import { getChatHeaderStyles } from "./ChatHeader.styles";
+import HeaderOptions from "./HeaderOptions";
+import { Menu } from "../../components/SortableMenu";
import {
DndContext,
closestCenter,
@@ -19,22 +27,155 @@ import {
const ChatHeader = ({
optionConfig = {
- menuOptions: [
+ toolOptions: [
"minmax",
"thread",
"mentions",
"starred",
"pinned",
"files",
- "close",
"members",
"search",
"rInfo",
"logout",
+ "close",
],
+
+ threshold: 4,
},
}) => {
- const [menuOptions, setMenuOptions] = useState(optionConfig.menuOptions);
+ const theme = useTheme();
+ const styles = getChatHeaderStyles(theme);
+ const [toolOptions, setToolOptions] = useState(optionConfig.toolOptions);
+ const [threshold] = useState(optionConfig.threshold);
+
+ const menuMap = {
+ minmax: (
+
+ {}}
+ ghost
+ display="inline"
+ square
+ size="medium"
+ >
+
+
+
+ ),
+
+ close: (
+
+ {}}
+ ghost
+ display="inline"
+ square
+ size="medium"
+ >
+
+
+
+ ),
+ thread: (
+
+ {}}>
+
+
+
+ ),
+
+ mentions: (
+
+ {}}>
+
+
+
+ ),
+
+ starred: (
+
+ {}}>
+
+
+
+ ),
+
+ pinned: (
+
+ {}}>
+
+
+
+ ),
+
+ members: (
+
+ {}}>
+
+
+
+ ),
+
+ files: (
+
+ {}}>
+
+
+
+ ),
+
+ search: (
+
+ {}}>
+
+
+
+ ),
+
+ rInfo: (
+
+ {}}>
+
+
+
+ ),
+
+ logout: (
+
+ {}}>
+
+
+
+ ),
+ };
+
+ const menuOptions = toolOptions
+ .slice(threshold)
+ .map((key) => {
+ const tool = menuMap[key];
+
+ if (!tool) {
+ return null;
+ }
+
+ const { onClick } = tool.props.children.props;
+ const { name: icon } = tool.props.children.props.children.props;
+ const { text } = tool.props;
+
+ if (onClick && icon && text) {
+ return {
+ id: key,
+ action: onClick,
+ label: text,
+ icon,
+ };
+ }
+
+ return null;
+ })
+ .filter((option) => option !== null);
const sensors = useSensors(
useSensor(PointerSensor),
@@ -47,7 +188,7 @@ const ChatHeader = ({
const { active, over } = event;
if (active.id !== over.id) {
- setMenuOptions((items) => {
+ setToolOptions((items) => {
const oldIndex = items.indexOf(active.id);
const newIndex = items.indexOf(over.id);
@@ -56,8 +197,6 @@ const ChatHeader = ({
}
};
- const styles = useChatHeaderStyles();
-
return (
@@ -86,13 +225,14 @@ const ChatHeader = ({
onDragEnd={handleDragEnd}
>
- {menuOptions.map((key) => (
-
+ {toolOptions.slice(0, threshold).map((key) => (
+
))}
+ {menuOptions.length > 0 && }
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js b/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
index 0e5b04c98..ffb6860c7 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
@@ -1,5 +1,5 @@
-import { css } from '@emotion/react';
-import { darken, useTheme } from '@embeddedchat/ui-elements';
+import { css } from "@emotion/react";
+import { darken } from "@embeddedchat/ui-elements";
const rowCentreAlign = css`
display: flex;
@@ -7,50 +7,45 @@ const rowCentreAlign = css`
align-items: center;
`;
-const useChatHeaderStyles = () => {
- const { theme, mode, colors } = useTheme();
- const clearSpacing = css`
- margin: 0;
- padding: 0;
- `;
-
- const chatHeaderChild = css`
- ${rowCentreAlign}
- padding: 0 0.75rem;
- justify-content: space-between;
- width: 100%;
- `;
-
- const chatHeaderParent = css`
- background-color: ${mode === 'light'
- ? darken(colors.background, 0.03)
- : colors.secondary};
- width: 100%;
- z-index: ${theme.zIndex.general};
- display: flex;
- flex-direction: column;
- padding: 0.75rem;
- box-shadow: ${theme.shadows[1]};
- `;
-
- const channelDescription = css`
- ${rowCentreAlign}
- gap: 0.5rem;
- `;
-
- const chatHeaderIconRow = css`
- ${rowCentreAlign}
- position:relative;
- gap: 0.5rem;
- `;
-
- return {
- clearSpacing,
- chatHeaderChild,
- chatHeaderParent,
- channelDescription,
- chatHeaderIconRow,
+export const getChatHeaderStyles = (customTheme) => {
+ const { theme, mode, colors } = customTheme;
+
+ const styles = {
+ clearSpacing: css`
+ margin: 0;
+ padding: 0;
+ `,
+
+ chatHeaderChild: css`
+ ${rowCentreAlign}
+ padding: 0 0.75rem;
+ justify-content: space-between;
+ width: 100%;
+ `,
+
+ chatHeaderParent: css`
+ background-color: ${mode === "light"
+ ? darken(colors.background, 0.03)
+ : colors.secondary};
+ width: 100%;
+ z-index: ${theme.zIndex.general};
+ display: flex;
+ flex-direction: column;
+ padding: 0.75rem;
+ box-shadow: ${theme.shadows[1]};
+ `,
+
+ channelDescription: css`
+ ${rowCentreAlign}
+ gap: 0.5rem;
+ `,
+
+ chatHeaderIconRow: css`
+ ${rowCentreAlign}
+ position:relative;
+ gap: 0.5rem;
+ `,
};
-};
-export default useChatHeaderStyles;
+ return styles;
+};
diff --git a/packages/layout_editor/src/views/ChatHeader/HeaderOptions.jsx b/packages/layout_editor/src/views/ChatHeader/HeaderOptions.jsx
new file mode 100644
index 000000000..fce4dbbcf
--- /dev/null
+++ b/packages/layout_editor/src/views/ChatHeader/HeaderOptions.jsx
@@ -0,0 +1,22 @@
+import React from "react";
+import { useSortable } from "@dnd-kit/sortable";
+import { Box } from "@embeddedchat/ui-elements";
+import { CSS } from "@dnd-kit/utilities";
+
+const HeaderOptions = ({ id, menuMap }) => {
+ const { attributes, listeners, setNodeRef, transform, transition } =
+ useSortable({ id });
+
+ const style = {
+ transform: CSS.Transform.toString(transform),
+ transition,
+ };
+
+ return (
+
+ {menuMap[id]}
+
+ );
+};
+
+export default HeaderOptions;
diff --git a/packages/layout_editor/src/views/ChatHeader/SortableHeaderOptions.jsx b/packages/layout_editor/src/views/ChatHeader/SortableHeaderOptions.jsx
deleted file mode 100644
index d3a35effc..000000000
--- a/packages/layout_editor/src/views/ChatHeader/SortableHeaderOptions.jsx
+++ /dev/null
@@ -1,123 +0,0 @@
-import React from "react";
-import { useSortable } from "@dnd-kit/sortable";
-import { Box, Tooltip, ActionButton, Icon } from "@embeddedchat/ui-elements";
-import { CSS } from "@dnd-kit/utilities";
-
-const SortableHeaderOptions = (props) => {
- const menuMap = {
- minmax: (
-
- {}}
- ghost
- display="inline"
- square
- size="medium"
- >
-
-
-
- ),
-
- close: (
-
- {}}
- ghost
- display="inline"
- square
- size="medium"
- >
-
-
-
- ),
- thread: (
-
- {}}>
-
-
-
- ),
-
- mentions: (
-
- {}}>
-
-
-
- ),
-
- starred: (
-
- {}}>
-
-
-
- ),
-
- pinned: (
-
- {}}>
-
-
-
- ),
-
- members: (
-
- {}}>
-
-
-
- ),
-
- files: (
-
- {}}>
-
-
-
- ),
-
- search: (
-
- {}}>
-
-
-
- ),
-
- rInfo: (
-
- {}}>
-
-
-
- ),
-
- logout: (
-
- {}}>
-
-
-
- ),
- };
- const { attributes, listeners, setNodeRef, transform, transition } =
- useSortable({ id: props.id });
-
- const style = {
- transform: CSS.Transform.toString(transform),
- transition,
- };
-
- return (
-
- {menuMap[props.id]}
-
- );
-};
-
-export default SortableHeaderOptions;
From 3bab72d62d04ebe6c632f6a68527287205649f74 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 13 Jul 2024 10:46:44 +0530
Subject: [PATCH 004/104] implemented drag overlay
---
.../src/components/SortableMenu/Menu.jsx | 23 +++++-----
.../components/SortableMenu/Menu.styles.js | 7 +++
.../src/components/SortableMenu/MenuItem.jsx | 22 ++++++++--
.../src/views/ChatHeader/ChatHeader.jsx | 43 ++++++++++++++-----
.../src/views/ChatHeader/ChatHeader.styles.js | 7 +++
.../src/views/ChatHeader/HeaderOptions.jsx | 24 +++++++++--
6 files changed, 99 insertions(+), 27 deletions(-)
diff --git a/packages/layout_editor/src/components/SortableMenu/Menu.jsx b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
index 41ac15518..31b1d0921 100644
--- a/packages/layout_editor/src/components/SortableMenu/Menu.jsx
+++ b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
@@ -26,20 +26,21 @@ const Menu = ({
-
-
+
+
+
{options.map((option, idx) => (
))}
-
-
+
+
);
};
diff --git a/packages/layout_editor/src/components/SortableMenu/Menu.styles.js b/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
index 275476956..eb629e7e5 100644
--- a/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
+++ b/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
@@ -53,6 +53,13 @@ export const getMenuItemStyles = (customTheme) => {
cursor: not-allowed !important;
color: ${colors.mutedForeground};
`,
+
+ dragOverlay: css`
+ padding: 0.5rem 0.75em;
+ border: 1px solid ${colors.border};
+ border-right: none;
+ border-left: none;
+ `,
};
return styles;
diff --git a/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx b/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
index 3c90be787..65a17b147 100644
--- a/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
+++ b/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
@@ -5,19 +5,35 @@ import { getMenuItemStyles } from "./Menu.styles";
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
-
const MenuItem = ({ id, icon, label, action, disabled }) => {
const theme = useTheme();
const styles = getMenuItemStyles(theme);
- const { attributes, listeners, setNodeRef, transform, transition } =
- useSortable({ id });
+ const {
+ attributes,
+ listeners,
+ setNodeRef,
+ transform,
+ transition,
+ isDragging,
+ } = useSortable({
+ id,
+ data: {
+ type: "ColumnOptions",
+ icon,
+ label,
+ },
+ });
const style = {
transform: CSS.Transform.toString(transform),
transition,
};
+ if (isDragging) {
+ return ;
+ }
+
return (
{
+ if (event.active.data.current?.type === "RowOptions") {
+ setActiveRowOption(event.active.id);
+ } else if (event.active.data.current?.type === "ColumnOptions") {
+ setActiveColumnOption({
+ id: event.active.id,
+ icon: event.active.data.current.icon,
+ label: event.active.data.current.label,
+ });
+ }
+ };
const handleDragEnd = (event) => {
+ setActiveRowOption(null);
+ setActiveColumnOption(null);
const { active, over } = event;
if (active.id !== over.id) {
@@ -223,18 +239,25 @@ const ChatHeader = ({
sensors={sensors}
collisionDetection={closestCenter}
onDragEnd={handleDragEnd}
+ onDragStart={handleDragStart}
>
-
-
+
+
{toolOptions.slice(0, threshold).map((key) => (
))}
- {menuOptions.length > 0 && }
-
-
+
+ {menuOptions.length > 0 && }
+
+ {createPortal(
+
+ {activeRowOption && (
+
+ )}
+ {activeColumnOption && }
+ ,
+ document.body
+ )}
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js b/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
index ffb6860c7..0cbe97930 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
@@ -45,6 +45,13 @@ export const getChatHeaderStyles = (customTheme) => {
position:relative;
gap: 0.5rem;
`,
+
+ overlayBox: css`
+ width: 24px;
+ height: 24px;
+ border: 1px solid ${colors.border};
+ border-radius: ${theme.schemes.radius};
+ `,
};
return styles;
diff --git a/packages/layout_editor/src/views/ChatHeader/HeaderOptions.jsx b/packages/layout_editor/src/views/ChatHeader/HeaderOptions.jsx
index fce4dbbcf..a8b054795 100644
--- a/packages/layout_editor/src/views/ChatHeader/HeaderOptions.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/HeaderOptions.jsx
@@ -1,17 +1,35 @@
import React from "react";
import { useSortable } from "@dnd-kit/sortable";
-import { Box } from "@embeddedchat/ui-elements";
+import { Box, useTheme } from "@embeddedchat/ui-elements";
import { CSS } from "@dnd-kit/utilities";
+import { getChatHeaderStyles } from "./ChatHeader.styles";
const HeaderOptions = ({ id, menuMap }) => {
- const { attributes, listeners, setNodeRef, transform, transition } =
- useSortable({ id });
+ const theme = useTheme();
+ const styles = getChatHeaderStyles(theme);
+ const {
+ attributes,
+ listeners,
+ setNodeRef,
+ transform,
+ transition,
+ isDragging,
+ } = useSortable({
+ id,
+ data: {
+ type: "RowOptions",
+ },
+ });
const style = {
transform: CSS.Transform.toString(transform),
transition,
};
+ if (isDragging) {
+ return ;
+ }
+
return (
{menuMap[id]}
From 08acf621fc80940dad225c2a9953f74c63e9acf4 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 13 Jul 2024 12:34:36 +0530
Subject: [PATCH 005/104] added dragover event
---
.../src/views/ChatHeader/ChatHeader.jsx | 20 ++++++++++++++++++-
.../src/views/ChatHeader/ChatHeader.styles.js | 2 +-
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
index e8880f527..21faf10d3 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -51,7 +51,7 @@ const ChatHeader = ({
const [toolOptions, setToolOptions] = useState(optionConfig.toolOptions);
const [activeRowOption, setActiveRowOption] = useState(null);
const [activeColumnOption, setActiveColumnOption] = useState(null);
- const [threshold] = useState(optionConfig.threshold);
+ const [threshold, setThreshold] = useState(optionConfig.threshold);
const menuMap = {
minmax: (
@@ -213,6 +213,23 @@ const ChatHeader = ({
}
};
+ const handleDragOver = (event) => {
+ const isARowOption = event.active.data.current?.type === "RowOptions";
+ const isAColumnOption = event.active.data.current?.type === "ColumnOptions";
+ const isOverAColumnOption =
+ event.over.data.current?.type === "ColumnOptions";
+
+ const isOverARowOption = event.over.data.current?.type === "RowOptions";
+
+ if (isARowOption && isOverAColumnOption) {
+ setThreshold((threshold) => threshold - 1);
+ } else if (isAColumnOption && isOverARowOption) {
+ setThreshold((threshold) => threshold + 1);
+ }
+
+ console.log(event);
+ };
+
return (
@@ -240,6 +257,7 @@ const ChatHeader = ({
collisionDetection={closestCenter}
onDragEnd={handleDragEnd}
onDragStart={handleDragStart}
+ onDragOver={handleDragOver}
>
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js b/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
index 0cbe97930..cf06e9685 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
@@ -3,7 +3,7 @@ import { darken } from "@embeddedchat/ui-elements";
const rowCentreAlign = css`
display: flex;
- flex-direction: row;
+ flex-direction: ;
align-items: center;
`;
From 500e43772f619c48d41a3ede186526d2ffea734e Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 13 Jul 2024 13:50:29 +0530
Subject: [PATCH 006/104] changed jsx to normal options
---
.../react/src/views/ChatHeader/ChatHeader.js | 319 +++++++-----------
.../src/views/ChatInput/ChatInput.styles.js | 3 +-
.../src/views/SurfaceMenu/SurfaceItem.js | 12 +
.../src/views/SurfaceMenu/SurfaceMenu.js | 12 +
4 files changed, 154 insertions(+), 192 deletions(-)
create mode 100644 packages/react/src/views/SurfaceMenu/SurfaceItem.js
create mode 100644 packages/react/src/views/SurfaceMenu/SurfaceMenu.js
diff --git a/packages/react/src/views/ChatHeader/ChatHeader.js b/packages/react/src/views/ChatHeader/ChatHeader.js
index 5a57a32b2..f9079c688 100644
--- a/packages/react/src/views/ChatHeader/ChatHeader.js
+++ b/packages/react/src/views/ChatHeader/ChatHeader.js
@@ -1,12 +1,10 @@
-import React, { useCallback, useEffect } from 'react';
+import React, { useCallback, useEffect, useMemo } from 'react';
import PropTypes from 'prop-types';
import {
Box,
Heading,
Icon,
Menu,
- ActionButton,
- Tooltip,
useToastBarDispatch,
useComponentOverrides,
} from '@embeddedchat/ui-elements';
@@ -28,6 +26,7 @@ import useFetchChatData from '../../hooks/useFetchChatData';
import useSettingsStore from '../../store/settingsStore';
import useChatHeaderStyles from './ChatHeader.styles';
import useSetExclusiveState from '../../hooks/useSetExclusiveState';
+import SurfaceMenu from '../SurfaceMenu/SurfaceMenu';
const ChatHeader = ({
isClosable,
@@ -37,9 +36,8 @@ const ChatHeader = ({
className = '',
style = {},
optionConfig = {
- toolOptions: [
- 'minmax',
- 'close',
+ surfaceItems: ['minmax', 'close'],
+ menuItems: [
'thread',
'mentions',
'starred',
@@ -50,17 +48,15 @@ const ChatHeader = ({
'rInfo',
'logout',
],
-
- threshold: 2,
},
}) => {
const { classNames, styleOverrides, configOverrides } =
useComponentOverrides('ChatHeader');
- const toolOptions =
- configOverrides.optionConfig?.toolOptions || optionConfig.toolOptions;
- const threshold =
- configOverrides.optionConfig?.threshold || optionConfig.threshold;
+ const surfaceItems =
+ configOverrides.optionConfig?.surfaceItems || optionConfig.surfaceItems;
+ const menuItems =
+ configOverrides.optionConfig?.menuItems || optionConfig.menuItems;
const styles = useChatHeaderStyles();
const setExclusiveState = useSetExclusiveState();
@@ -204,190 +200,129 @@ const ChatHeader = ({
setIsChannelReadOnly,
]);
- const menuMap = {
- minmax: (
-
- {
- setFullScreen((prev) => !prev);
- }}
- ghost
- display="inline"
- square
- size="medium"
- >
-
-
-
- ),
-
- close: isClosable && (
- {
- setClosableState((prev) => !prev);
- }}
- ghost
- display="inline"
- square
- size="medium"
- >
-
-
- ),
- thread: (
-
- {
- setExclusiveState(setShowAllThreads);
- }}
- >
-
-
-
- ),
-
- mentions: (
-
- {
- setExclusiveState(setShowMentions);
- }}
- >
-
-
-
- ),
-
- starred: (
-
- {
- setExclusiveState(setShowStarred);
- }}
- >
-
-
-
- ),
-
- pinned: (
-
- {
- setExclusiveState(setShowPinned);
- }}
- >
-
-
-
- ),
-
- members: isUserAuthenticated && (
-
- {
- setExclusiveState(setShowMembers);
- }}
- >
-
-
-
- ),
-
- files: isUserAuthenticated && (
-
- {
- setExclusiveState(setShowAllFiles);
- }}
- >
-
-
-
- ),
-
- search: isUserAuthenticated && (
-
- {
- setExclusiveState(setShowSearch);
- }}
- >
-
-
-
- ),
-
- rInfo: isUserAuthenticated && (
-
- {
- setExclusiveState(setShowChannelinfo);
- }}
- >
-
-
-
- ),
-
- logout: isUserAuthenticated && (
-
- {
- handleLogout();
- }}
- >
-
-
-
- ),
- };
-
- const menuOptions = toolOptions
- .slice(threshold)
- .map((key) => {
- const tool = menuMap[key];
+ const options = useMemo(
+ () => ({
+ minmax: {
+ label: `${fullScreen ? 'Minimize' : 'Maximize'}`,
+ id: 'minmax',
+ onClick: () => setFullScreen((prev) => !prev),
+ iconName: `${fullScreen ? 'collapse' : 'expand'}`,
+ visible: true,
+ },
+ close: {
+ label: 'Close',
+ id: 'close',
+ onClick: () => setClosableState((prev) => !prev),
+ iconName: 'cross',
+ visible: isClosable,
+ },
+ thread: {
+ label: 'Threads',
+ id: 'thread',
+ onClick: () => setExclusiveState(setShowAllThreads),
+ iconName: 'thread',
+ visible: true,
+ },
+ mentions: {
+ label: 'Mentions',
+ id: 'mention',
+ onClick: () => setExclusiveState(setShowMentions),
+ iconName: 'at',
+ visible: true,
+ },
+ starred: {
+ label: 'Starred Messages',
+ id: 'starred',
+ onClick: () => setExclusiveState(setShowStarred),
+ iconName: 'star',
+ visible: true,
+ },
+ pinned: {
+ label: 'Pinned Messages',
+ id: 'pinned',
+ onClick: () => setExclusiveState(setShowPinned),
+ iconName: 'pin',
+ visible: true,
+ },
+ members: {
+ label: 'Members',
+ id: 'members',
+ onClick: () => setExclusiveState(setShowMembers),
+ iconName: 'members',
+ visible: isUserAuthenticated,
+ },
+ files: {
+ label: 'Files',
+ id: 'files',
+ onClick: () => setExclusiveState(setShowAllFiles),
+ iconName: 'clip',
+ visible: isUserAuthenticated,
+ },
+ search: {
+ label: 'Search Messages',
+ id: 'search',
+ onClick: () => setExclusiveState(setShowSearch),
+ iconName: 'magnifier',
+ visible: isUserAuthenticated,
+ },
+ rInfo: {
+ label: 'Room Information',
+ id: 'rInfo',
+ onClick: () => setExclusiveState(setShowChannelinfo),
+ iconName: 'info',
+ visible: isUserAuthenticated,
+ },
+ logout: {
+ label: 'Logout',
+ id: 'logout',
+ onClick: handleLogout,
+ iconName: 'reply-directly',
+ visible: isUserAuthenticated,
+ },
+ }),
+ [
+ fullScreen,
+ isClosable,
+ isUserAuthenticated,
+ handleLogout,
+ setFullScreen,
+ setClosableState,
+ setExclusiveState,
+ setShowAllThreads,
+ setShowMentions,
+ setShowStarred,
+ setShowPinned,
+ setShowMembers,
+ setShowAllFiles,
+ setShowSearch,
+ setShowChannelinfo,
+ ]
+ );
- if (!tool) {
- return null;
+ const menuOptions = menuItems
+ ?.map((item) => {
+ if (item in options && options[item].visible) {
+ return {
+ id: options[item].id,
+ action: options[item].onClick,
+ label: options[item].label,
+ icon: options[item].iconName,
+ };
}
+ return null;
+ })
+ .filter((option) => option !== null);
- const { onClick } = tool.props.children.props;
- const { name: icon } = tool.props.children.props.children.props;
- const { text } = tool.props;
-
- if (onClick && icon && text) {
+ const surfaceOptions = surfaceItems
+ ?.map((item) => {
+ if (item in options && options[item].visible) {
return {
- id: key,
- action: onClick,
- label: text,
- icon,
+ id: options[item].id,
+ onClick: options[item].onClick,
+ label: options[item].label,
+ iconName: options[item].iconName,
};
}
-
return null;
})
.filter((option) => option !== null);
@@ -436,7 +371,9 @@ const ChatHeader = ({
)}
- {toolOptions.slice(0, threshold).map((key) => menuMap[key])}
+ {surfaceOptions.length > 0 && (
+
+ )}
{menuOptions.length > 0 && }
diff --git a/packages/react/src/views/ChatInput/ChatInput.styles.js b/packages/react/src/views/ChatInput/ChatInput.styles.js
index 12e102081..fe6176b42 100644
--- a/packages/react/src/views/ChatInput/ChatInput.styles.js
+++ b/packages/react/src/views/ChatInput/ChatInput.styles.js
@@ -21,7 +21,7 @@ export const useChatInputStyles = () => {
align-items: center;
justify-content: center;
flex-direction: row;
- padding: 0.25rem;
+ padding: 0.5rem;
`;
const iconCursor = css`
@@ -29,6 +29,7 @@ export const useChatInputStyles = () => {
`;
const textInput = css`
+ flex: 1;
word-wrap: break-word;
white-space: pre-wrap;
overflow: auto;
diff --git a/packages/react/src/views/SurfaceMenu/SurfaceItem.js b/packages/react/src/views/SurfaceMenu/SurfaceItem.js
new file mode 100644
index 000000000..f23dfb94f
--- /dev/null
+++ b/packages/react/src/views/SurfaceMenu/SurfaceItem.js
@@ -0,0 +1,12 @@
+import React from 'react';
+import { Tooltip, ActionButton, Icon } from '@embeddedchat/ui-elements';
+
+const SurfaceItem = ({ item }) => (
+
+
+
+
+
+);
+
+export default SurfaceItem;
diff --git a/packages/react/src/views/SurfaceMenu/SurfaceMenu.js b/packages/react/src/views/SurfaceMenu/SurfaceMenu.js
new file mode 100644
index 000000000..dfb6e38f7
--- /dev/null
+++ b/packages/react/src/views/SurfaceMenu/SurfaceMenu.js
@@ -0,0 +1,12 @@
+import React from 'react';
+import SurfaceItem from './SurfaceItem';
+
+const SurfaceMenu = ({ options }) => (
+ <>
+ {options?.map((item, idx) => (
+
+ ))}
+ >
+);
+
+export default SurfaceMenu;
From f48fdb0f6c926eaec0fe02550583a2498414b886 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 13 Jul 2024 14:58:01 +0530
Subject: [PATCH 007/104] structure change in layout editor
---
.../src/components/SortableMenu/Menu.jsx | 3 +-
.../src/components/SortableMenu/MenuItem.jsx | 2 +-
.../SurfaceMenu/SurfaceItem.jsx} | 30 +-
.../components/SurfaceMenu/SurfaceMenu.jsx | 15 +
.../SurfaceMenu/SurfaceMenu.styles.js | 16 +
.../src/views/ChatHeader/ChatHeader.jsx | 330 ++++++++----------
6 files changed, 197 insertions(+), 199 deletions(-)
rename packages/layout_editor/src/{views/ChatHeader/HeaderOptions.jsx => components/SurfaceMenu/SurfaceItem.jsx} (50%)
create mode 100644 packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
create mode 100644 packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.styles.js
diff --git a/packages/layout_editor/src/components/SortableMenu/Menu.jsx b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
index 31b1d0921..a6ab1d12c 100644
--- a/packages/layout_editor/src/components/SortableMenu/Menu.jsx
+++ b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
@@ -10,7 +10,6 @@ import MenuItem from "./MenuItem";
import { getMenuStyles } from "./Menu.styles";
import {
SortableContext,
- verticalListSortingStrategy,
} from "@dnd-kit/sortable";
const Menu = ({
@@ -35,7 +34,7 @@ const Menu = ({
`,
]}
>
-
+
{options.map((option, idx) => (
))}
diff --git a/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx b/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
index 65a17b147..90dc91d68 100644
--- a/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
+++ b/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
@@ -19,7 +19,7 @@ const MenuItem = ({ id, icon, label, action, disabled }) => {
} = useSortable({
id,
data: {
- type: "ColumnOptions",
+ type: "MenuOptions",
icon,
label,
},
diff --git a/packages/layout_editor/src/views/ChatHeader/HeaderOptions.jsx b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
similarity index 50%
rename from packages/layout_editor/src/views/ChatHeader/HeaderOptions.jsx
rename to packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
index a8b054795..f293f060f 100644
--- a/packages/layout_editor/src/views/ChatHeader/HeaderOptions.jsx
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
@@ -1,29 +1,35 @@
import React from "react";
+import {
+ Tooltip,
+ ActionButton,
+ Icon,
+ Box,
+ useTheme,
+} from "@embeddedchat/ui-elements";
import { useSortable } from "@dnd-kit/sortable";
-import { Box, useTheme } from "@embeddedchat/ui-elements";
import { CSS } from "@dnd-kit/utilities";
-import { getChatHeaderStyles } from "./ChatHeader.styles";
+import { getSurfaceItemStyles } from "./SurfaceMenu.styles";
-const HeaderOptions = ({ id, menuMap }) => {
- const theme = useTheme();
- const styles = getChatHeaderStyles(theme);
+const SurfaceItem = ({ id, label, iconName, onClick }) => {
const {
attributes,
listeners,
setNodeRef,
transform,
- transition,
isDragging,
} = useSortable({
id,
data: {
- type: "RowOptions",
+ type: "SurfaceOptions",
+ icon: iconName,
+ label,
},
});
+ const theme = useTheme();
+ const styles = getSurfaceItemStyles(theme);
const style = {
transform: CSS.Transform.toString(transform),
- transition,
};
if (isDragging) {
@@ -32,9 +38,13 @@ const HeaderOptions = ({ id, menuMap }) => {
return (
- {menuMap[id]}
+
+
+
+
+
);
};
-export default HeaderOptions;
+export default SurfaceItem;
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
new file mode 100644
index 000000000..d15f3337a
--- /dev/null
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
@@ -0,0 +1,15 @@
+import React from "react";
+import SurfaceItem from "./SurfaceItem";
+import { SortableContext } from "@dnd-kit/sortable";
+
+const SurfaceMenu = ({ options }) => {
+ return (
+
+ {options?.map((item, idx) => (
+
+ ))}
+
+ );
+};
+
+export default SurfaceMenu;
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.styles.js b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.styles.js
new file mode 100644
index 000000000..87984171e
--- /dev/null
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.styles.js
@@ -0,0 +1,16 @@
+import { css } from "@emotion/react";
+
+export const getSurfaceItemStyles = (customTheme) => {
+ const { theme, colors } = customTheme;
+
+ const styles = {
+ overlayBox: css`
+ width: 24px;
+ height: 24px;
+ border: 1px solid ${colors.border};
+ border-radius: ${theme.schemes.radius};
+ `,
+ };
+
+ return styles;
+};
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
index 21faf10d3..cbe5a093a 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -1,15 +1,8 @@
-import React, { useState } from "react";
-import {
- Heading,
- Box,
- Icon,
- ActionButton,
- Tooltip,
- useTheme,
-} from "@embeddedchat/ui-elements";
+import React, { useState, useMemo } from "react";
+import { Heading, Box, Icon, useTheme } from "@embeddedchat/ui-elements";
import { getChatHeaderStyles } from "./ChatHeader.styles";
-import HeaderOptions from "./HeaderOptions";
import { Menu } from "../../components/SortableMenu";
+import SurfaceItem from "../../components/SurfaceMenu/SurfaceItem";
import {
DndContext,
closestCenter,
@@ -19,164 +12,138 @@ import {
useSensors,
DragOverlay,
} from "@dnd-kit/core";
-import {
- SortableContext,
- sortableKeyboardCoordinates,
- arrayMove,
-} from "@dnd-kit/sortable";
+import { sortableKeyboardCoordinates, arrayMove } from "@dnd-kit/sortable";
import { createPortal } from "react-dom";
import MenuItem from "../../components/SortableMenu/MenuItem";
+import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
const ChatHeader = ({
optionConfig = {
- toolOptions: [
+ surfaceItems: [
"minmax",
+ "close",
"thread",
"mentions",
"starred",
"pinned",
- "files",
- "members",
- "search",
- "rInfo",
- "logout",
- "close",
],
-
- threshold: 4,
+ menuItems: ["files", "members", "search", "rInfo", "logout"],
},
}) => {
const theme = useTheme();
const styles = getChatHeaderStyles(theme);
- const [toolOptions, setToolOptions] = useState(optionConfig.toolOptions);
- const [activeRowOption, setActiveRowOption] = useState(null);
- const [activeColumnOption, setActiveColumnOption] = useState(null);
- const [threshold, setThreshold] = useState(optionConfig.threshold);
-
- const menuMap = {
- minmax: (
-
- {}}
- ghost
- display="inline"
- square
- size="medium"
- >
-
-
-
- ),
-
- close: (
-
- {}}
- ghost
- display="inline"
- square
- size="medium"
- >
-
-
-
- ),
- thread: (
-
- {}}>
-
-
-
- ),
-
- mentions: (
-
- {}}>
-
-
-
- ),
-
- starred: (
-
- {}}>
-
-
-
- ),
-
- pinned: (
-
- {}}>
-
-
-
- ),
-
- members: (
-
- {}}>
-
-
-
- ),
-
- files: (
-
- {}}>
-
-
-
- ),
-
- search: (
-
- {}}>
-
-
-
- ),
-
- rInfo: (
-
- {}}>
-
-
-
- ),
-
- logout: (
-
- {}}>
-
-
-
- ),
- };
-
- const menuOptions = toolOptions
- .slice(threshold)
- .map((key) => {
- const tool = menuMap[key];
+ const [surfaceItems, setSurfaceItems] = useState(optionConfig.surfaceItems);
+ const [menuItems, setMenuItems] = useState(optionConfig.menuItems);
+ const [activeSurfaceItem, setActiveSurfaceItem] = useState(null);
+ const [activeMenuItem, setActiveMenuItem] = useState(null);
+
+ const options = useMemo(
+ () => ({
+ minmax: {
+ label: "Maximize",
+ id: "minmax",
+ onClick: () => {},
+ iconName: "expand",
+ visible: true,
+ },
+ close: {
+ label: "Close",
+ id: "close",
+ onClick: () => {},
+ iconName: "cross",
+ visible: true,
+ },
+ thread: {
+ label: "Threads",
+ id: "thread",
+ onClick: () => {},
+ iconName: "thread",
+ visible: true,
+ },
+ mentions: {
+ label: "Mentions",
+ id: "mentions",
+ onClick: () => {},
+ iconName: "at",
+ visible: true,
+ },
+ starred: {
+ label: "Starred Messages",
+ id: "starred",
+ onClick: () => {},
+ iconName: "star",
+ visible: true,
+ },
+ pinned: {
+ label: "Pinned Messages",
+ id: "pinned",
+ onClick: () => {},
+ iconName: "pin",
+ visible: true,
+ },
+ members: {
+ label: "Members",
+ id: "members",
+ onClick: () => {},
+ iconName: "members",
+ visible: true,
+ },
+ files: {
+ label: "Files",
+ id: "files",
+ onClick: () => {},
+ iconName: "clip",
+ visible: true,
+ },
+ search: {
+ label: "Search Messages",
+ id: "search",
+ onClick: () => {},
+ iconName: "magnifier",
+ visible: true,
+ },
+ rInfo: {
+ label: "Room Information",
+ id: "rInfo",
+ onClick: () => {},
+ iconName: "info",
+ visible: true,
+ },
+ logout: {
+ label: "Logout",
+ id: "logout",
+ onClick: () => {},
+ iconName: "reply-directly",
+ visible: true,
+ },
+ }),
+ []
+ );
- if (!tool) {
- return null;
+ const menuOptions = menuItems
+ ?.map((item) => {
+ if (item in options && options[item].visible) {
+ return {
+ id: options[item].id,
+ action: options[item].onClick,
+ label: options[item].label,
+ icon: options[item].iconName,
+ };
}
+ return null;
+ })
+ .filter((option) => option !== null);
- const { onClick } = tool.props.children.props;
- const { name: icon } = tool.props.children.props.children.props;
- const { text } = tool.props;
-
- if (onClick && icon && text) {
+ const surfaceOptions = surfaceItems
+ ?.map((item) => {
+ if (item in options && options[item].visible) {
return {
- id: key,
- action: onClick,
- label: text,
- icon,
+ id: options[item].id,
+ onClick: options[item].onClick,
+ label: options[item].label,
+ iconName: options[item].iconName,
};
}
-
return null;
})
.filter((option) => option !== null);
@@ -188,10 +155,14 @@ const ChatHeader = ({
})
);
const handleDragStart = (event) => {
- if (event.active.data.current?.type === "RowOptions") {
- setActiveRowOption(event.active.id);
- } else if (event.active.data.current?.type === "ColumnOptions") {
- setActiveColumnOption({
+ if (event.active.data.current?.type === "SurfaceOptions") {
+ setActiveSurfaceItem({
+ id: event.active.id,
+ iconName: event.active.data.current.icon,
+ label: event.active.data.current.label,
+ });
+ } else if (event.active.data.current?.type === "MenuOptions") {
+ setActiveMenuItem({
id: event.active.id,
icon: event.active.data.current.icon,
label: event.active.data.current.label,
@@ -199,35 +170,27 @@ const ChatHeader = ({
}
};
const handleDragEnd = (event) => {
- setActiveRowOption(null);
- setActiveColumnOption(null);
+ setActiveSurfaceItem(null);
+ setActiveMenuItem(null);
const { active, over } = event;
if (active.id !== over.id) {
- setToolOptions((items) => {
- const oldIndex = items.indexOf(active.id);
- const newIndex = items.indexOf(over.id);
-
- return arrayMove(items, oldIndex, newIndex);
- });
- }
- };
-
- const handleDragOver = (event) => {
- const isARowOption = event.active.data.current?.type === "RowOptions";
- const isAColumnOption = event.active.data.current?.type === "ColumnOptions";
- const isOverAColumnOption =
- event.over.data.current?.type === "ColumnOptions";
-
- const isOverARowOption = event.over.data.current?.type === "RowOptions";
-
- if (isARowOption && isOverAColumnOption) {
- setThreshold((threshold) => threshold - 1);
- } else if (isAColumnOption && isOverARowOption) {
- setThreshold((threshold) => threshold + 1);
+ if (event.active.data.current?.type === "SurfaceOptions") {
+ setSurfaceItems((items) => {
+ const oldIndex = items.indexOf(active.id);
+ const newIndex = items.indexOf(over.id);
+
+ return arrayMove(items, oldIndex, newIndex);
+ });
+ } else if (event.active.data.current?.type === "MenuOptions") {
+ setMenuItems((items) => {
+ const oldIndex = items.indexOf(active.id);
+ const newIndex = items.indexOf(over.id);
+
+ return arrayMove(items, oldIndex, newIndex);
+ });
+ }
}
-
- console.log(event);
};
return (
@@ -257,22 +220,17 @@ const ChatHeader = ({
collisionDetection={closestCenter}
onDragEnd={handleDragEnd}
onDragStart={handleDragStart}
- onDragOver={handleDragOver}
>
-
- {toolOptions.slice(0, threshold).map((key) => (
-
- ))}
-
+ {surfaceOptions.length > 0 && (
+
+ )}
{menuOptions.length > 0 && }
{createPortal(
- {activeRowOption && (
-
- )}
- {activeColumnOption && }
+ {activeSurfaceItem && }
+ {activeMenuItem && }
,
document.body
)}
From 68632c5d36a180e72710ec96c5dbedd130defab0 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 13 Jul 2024 15:27:35 +0530
Subject: [PATCH 008/104] enabled transfer between two sortable context
---
.../src/views/ChatHeader/ChatHeader.jsx | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
index cbe5a093a..4ffb21d60 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -175,20 +175,24 @@ const ChatHeader = ({
const { active, over } = event;
if (active.id !== over.id) {
- if (event.active.data.current?.type === "SurfaceOptions") {
+ if (event.active.data.current?.type === "SurfaceOptions" && event.over.data.current?.type === "SurfaceOptions") {
setSurfaceItems((items) => {
const oldIndex = items.indexOf(active.id);
const newIndex = items.indexOf(over.id);
-
return arrayMove(items, oldIndex, newIndex);
});
- } else if (event.active.data.current?.type === "MenuOptions") {
+ } else if (event.active.data.current?.type === "MenuOptions" && event.over.data.current?.type === "MenuOptions") {
setMenuItems((items) => {
const oldIndex = items.indexOf(active.id);
const newIndex = items.indexOf(over.id);
-
return arrayMove(items, oldIndex, newIndex);
});
+ } else if (event.active.data.current?.type === "SurfaceOptions" && event.over.data.current?.type === "MenuOptions") {
+ setSurfaceItems((items) => items.filter((item) => item !== active.id));
+ setMenuItems((items) => [...items, active.id]);
+ } else if (event.active.data.current?.type === "MenuOptions" && event.over.data.current?.type === "SurfaceOptions") {
+ setMenuItems((items) => items.filter((item) => item !== active.id));
+ setSurfaceItems((items) => [...items, active.id]);
}
}
};
From 48fd98a5d079a85145a6506dde077b777acdf921 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 13 Jul 2024 23:41:45 +0530
Subject: [PATCH 009/104] enable no items
---
.../src/views/ChatHeader/ChatHeader.jsx | 71 +++++++++++--------
1 file changed, 43 insertions(+), 28 deletions(-)
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
index 4ffb21d60..3018c0aba 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -37,6 +37,9 @@ const ChatHeader = ({
const [activeSurfaceItem, setActiveSurfaceItem] = useState(null);
const [activeMenuItem, setActiveMenuItem] = useState(null);
+ const placeholderSurfaceItem = "placeholder-surface";
+ const placeholderMenuItem = "placeholder-menu";
+
const options = useMemo(
() => ({
minmax: {
@@ -120,33 +123,37 @@ const ChatHeader = ({
[]
);
- const menuOptions = menuItems
- ?.map((item) => {
- if (item in options && options[item].visible) {
- return {
- id: options[item].id,
- action: options[item].onClick,
- label: options[item].label,
- icon: options[item].iconName,
- };
- }
- return null;
- })
- .filter((option) => option !== null);
+ const menuOptions = menuItems.length > 0
+ ? menuItems
+ .map((item) => {
+ if (item in options && options[item].visible) {
+ return {
+ id: options[item].id,
+ action: options[item].onClick,
+ label: options[item].label,
+ icon: options[item].iconName,
+ };
+ }
+ return null;
+ })
+ .filter((option) => option !== null)
+ : [{ id: placeholderMenuItem, label: "No items", icon: "plus" }];
- const surfaceOptions = surfaceItems
- ?.map((item) => {
- if (item in options && options[item].visible) {
- return {
- id: options[item].id,
- onClick: options[item].onClick,
- label: options[item].label,
- iconName: options[item].iconName,
- };
- }
- return null;
- })
- .filter((option) => option !== null);
+ const surfaceOptions = surfaceItems.length > 0
+ ? surfaceItems
+ .map((item) => {
+ if (item in options && options[item].visible) {
+ return {
+ id: options[item].id,
+ onClick: options[item].onClick,
+ label: options[item].label,
+ iconName: options[item].iconName,
+ };
+ }
+ return null;
+ })
+ .filter((option) => option !== null)
+ : [{ id: placeholderSurfaceItem, label: "No items", iconName: "plus" }];
const sensors = useSensors(
useSensor(PointerSensor),
@@ -154,6 +161,7 @@ const ChatHeader = ({
coordinateGetter: sortableKeyboardCoordinates,
})
);
+
const handleDragStart = (event) => {
if (event.active.data.current?.type === "SurfaceOptions") {
setActiveSurfaceItem({
@@ -169,6 +177,7 @@ const ChatHeader = ({
});
}
};
+
const handleDragEnd = (event) => {
setActiveSurfaceItem(null);
setActiveMenuItem(null);
@@ -189,10 +198,16 @@ const ChatHeader = ({
});
} else if (event.active.data.current?.type === "SurfaceOptions" && event.over.data.current?.type === "MenuOptions") {
setSurfaceItems((items) => items.filter((item) => item !== active.id));
- setMenuItems((items) => [...items, active.id]);
+ setMenuItems((items) => {
+ const newItems = [...items.filter((item) => item !== placeholderMenuItem), active.id];
+ return newItems;
+ });
} else if (event.active.data.current?.type === "MenuOptions" && event.over.data.current?.type === "SurfaceOptions") {
setMenuItems((items) => items.filter((item) => item !== active.id));
- setSurfaceItems((items) => [...items, active.id]);
+ setSurfaceItems((items) => {
+ const newItems = [...items.filter((item) => item !== placeholderSurfaceItem), active.id];
+ return newItems;
+ });
}
}
};
From 65a446a93453d9e898eb8c0e97b50af71651d8fe Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 00:50:26 +0530
Subject: [PATCH 010/104] enabled icon size
---
.../components/ActionButton/ActionButton.js | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/packages/ui-elements/src/components/ActionButton/ActionButton.js b/packages/ui-elements/src/components/ActionButton/ActionButton.js
index ed38e2c46..f6dfb25f7 100644
--- a/packages/ui-elements/src/components/ActionButton/ActionButton.js
+++ b/packages/ui-elements/src/components/ActionButton/ActionButton.js
@@ -3,21 +3,31 @@ import PropTypes from 'prop-types';
import { Button } from '../Button';
import { Icon } from '../Icon';
-const getSize = ({ small, large }) => {
+const getSize = ({ small, large, size }) => {
if (small) {
return '1.25rem';
}
if (large) {
return '1.75rem';
}
- return '1.5rem';
+ return size || '1.5rem';
};
const ActionButton = forwardRef(
- ({ icon, size = 'medium', color = 'default', children, ...props }, ref) => (
+ (
+ {
+ icon,
+ size = 'medium',
+ color = 'default',
+ children,
+ iconSize = {},
+ ...props
+ },
+ ref
+ ) => (
)
);
From 64a948850873f9f464ec9718862370ac6ac2a212 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 00:50:41 +0530
Subject: [PATCH 011/104] changed jsx to option menus
---
.../ChatInput/ChatInputFormattingToolbar.js | 8 +-
.../react/src/views/Message/MessageToolbox.js | 239 +++++++++---------
.../src/views/SurfaceMenu/SurfaceItem.js | 16 +-
.../src/views/SurfaceMenu/SurfaceMenu.js | 4 +-
4 files changed, 131 insertions(+), 136 deletions(-)
diff --git a/packages/react/src/views/ChatInput/ChatInputFormattingToolbar.js b/packages/react/src/views/ChatInput/ChatInputFormattingToolbar.js
index 47fb4e489..e293567b4 100644
--- a/packages/react/src/views/ChatInput/ChatInputFormattingToolbar.js
+++ b/packages/react/src/views/ChatInput/ChatInputFormattingToolbar.js
@@ -19,7 +19,7 @@ const ChatInputFormattingToolbar = ({
messageRef,
inputRef,
optionConfig = {
- toolOptions: ['emoji', 'formatter', 'audio', 'video', 'file'],
+ surfaceItems: ['emoji', 'formatter', 'audio', 'video', 'file'],
},
}) => {
const { classNames, styleOverrides, configOverrides } = useComponentOverrides(
@@ -27,8 +27,8 @@ const ChatInputFormattingToolbar = ({
);
const styles = useChatInputFormattingToolbarStyles();
- const toolOptions =
- configOverrides.optionConfig?.toolOptions || optionConfig.toolOptions;
+ const surfaceItems =
+ configOverrides.optionConfig?.surfaceItems || optionConfig.surfaceItems;
const isRecordingMessage = useMessageStore(
(state) => state.isRecordingMessage
@@ -122,7 +122,7 @@ const ChatInputFormattingToolbar = ({
className={`ec-chat-input-formatting-toolbar ${classNames}`}
style={styleOverrides}
>
- {toolOptions.map((key) => chatToolMap[key])}
+ {surfaceItems.map((key) => chatToolMap[key])}
);
};
diff --git a/packages/react/src/views/Message/MessageToolbox.js b/packages/react/src/views/Message/MessageToolbox.js
index 0d911526c..a11b38fd6 100644
--- a/packages/react/src/views/Message/MessageToolbox.js
+++ b/packages/react/src/views/Message/MessageToolbox.js
@@ -1,11 +1,9 @@
-import React, { useState } from 'react';
+import React, { useState, useMemo } from 'react';
import {
Box,
- ActionButton,
Modal,
Icon,
Button,
- Tooltip,
Menu,
useComponentOverrides,
appendClassNames,
@@ -13,6 +11,7 @@ import {
import { EmojiPicker } from '../EmojiPicker';
import { parseEmoji } from '../../lib/emoji';
import { useMessageToolboxStyles } from './Message.styles';
+import SurfaceMenu from '../SurfaceMenu/SurfaceMenu';
export const MessageToolbox = ({
className = '',
@@ -31,7 +30,7 @@ export const MessageToolbox = ({
handleQuoteMessage,
isEditing = false,
optionConfig = {
- toolOptions: [
+ surfaceItems: [
'reaction',
'reply',
'quote',
@@ -41,7 +40,8 @@ export const MessageToolbox = ({
'delete',
'report',
],
- threshold: 8,
+
+ menuItems: [],
},
...props
@@ -53,10 +53,10 @@ export const MessageToolbox = ({
);
const styles = useMessageToolboxStyles();
- const toolOptions =
- configOverrides.optionConfig?.toolOptions || optionConfig.toolOptions;
- const threshold =
- configOverrides.optionConfig?.threshold || optionConfig.threshold;
+ const surfaceItems =
+ configOverrides.optionConfig?.surfaceItems || optionConfig.surfaceItems;
+ const menuItems =
+ configOverrides.optionConfig?.menuItems || optionConfig.menuItems;
const [isEmojiOpen, setEmojiOpen] = useState(false);
@@ -66,128 +66,116 @@ export const MessageToolbox = ({
setShowDeleteModal(false);
};
- const toolMap = {
- reply: !isThreadMessage && (
-
-
-
- ),
- quote: (
-
- handleQuoteMessage(message)}
- />
-
- ),
- star: (
- ({
+ reply: {
+ label: 'Reply in thread',
+ id: 'reply',
+ onClick: handleOpenThread(message),
+ iconName: 'thread',
+ visible: !isThreadMessage,
+ },
+ quote: {
+ label: 'Quote',
+ id: 'quote',
+ onClick: () => handleQuoteMessage(message),
+ iconName: 'quote',
+ visible: true,
+ },
+ star: {
+ label:
message.starred &&
message.starred.find((u) => u._id === authenticatedUserId)
? 'Unstar'
- : 'Star'
- }
- position="top"
- key="star"
- >
- u._id === authenticatedUserId)
- ? 'star-filled'
- : 'star'
- }`}
- onClick={() => handleStarMessage(message)}
- />
-
- ),
- reaction: (
-
- setEmojiOpen(true)}
- />
-
- ),
- pin: !isThreadMessage && (
-
- handlePinMessage(message)}
- />
-
- ),
- edit: message.u._id === authenticatedUserId && (
-
- handleEditMessage(message)}
- />
-
- ),
- delete: message.u._id === authenticatedUserId && (
-
- setShowDeleteModal(true)}
- />
-
- ),
- report: (
-
- handlerReportMessage(message)}
- />
-
- ),
- };
-
- const menuOptions = toolOptions
- .slice(threshold)
- .map((key) => {
- const tool = toolMap[key];
+ : 'Star',
+ id: 'star',
+ onClick: () => handleStarMessage(message),
+ iconName:
+ message.starred &&
+ message.starred.find((u) => u._id === authenticatedUserId)
+ ? 'star-filled'
+ : 'star',
+ visible: true,
+ },
+ reaction: {
+ label: 'Add reaction',
+ id: 'reaction',
+ onClick: () => setEmojiOpen(true),
+ iconName: 'emoji',
+ visible: true,
+ },
+ pin: {
+ label: message.pinned ? 'Unpin' : 'Pin',
+ id: 'pin',
+ onClick: () => handlePinMessage(message),
+ iconName: message.pinned ? 'pin-filled' : 'pin',
+ visible: !isThreadMessage,
+ },
+ edit: {
+ label: 'Edit',
+ id: 'edit',
+ onClick: () => handleEditMessage(message),
+ iconName: 'edit',
+ visible: message.u._id === authenticatedUserId,
+ color: isEditing ? 'secondary' : 'default',
+ ghost: !isEditing,
+ },
+ delete: {
+ label: 'Delete',
+ id: 'delete',
+ onClick: () => setShowDeleteModal(true),
+ iconName: 'trash',
+ visible: message.u._id === authenticatedUserId,
+ type: 'destructive',
+ },
+ report: {
+ label: 'Report',
+ id: 'report',
+ onClick: () => handlerReportMessage(message),
+ iconName: 'report',
+ visible: true,
+ type: 'destructive',
+ },
+ }),
+ [
+ handleOpenThread,
+ message,
+ isThreadMessage,
+ authenticatedUserId,
+ isEditing,
+ handleQuoteMessage,
+ handleStarMessage,
+ handlePinMessage,
+ handleEditMessage,
+ handlerReportMessage,
+ ]
+ );
- if (!tool) {
- return null;
+ const menuOptions = menuItems
+ ?.map((item) => {
+ if (item in options && options[item].visible) {
+ return {
+ id: options[item].id,
+ action: options[item].onClick,
+ label: options[item].label,
+ icon: options[item].iconName,
+ };
}
+ return null;
+ })
+ .filter((option) => option !== null);
- const { onClick } = tool.props.children.props;
- const { icon } = tool.props.children.props;
- const { text } = tool.props;
-
- if (onClick && icon && text) {
+ const surfaceOptions = surfaceItems
+ ?.map((item) => {
+ if (item in options && options[item].visible) {
return {
- id: key,
- action: onClick,
- label: text,
- icon,
+ id: options[item].id,
+ onClick: options[item].onClick,
+ label: options[item].label,
+ iconName: options[item].iconName,
+ type: options[item].type,
};
}
-
return null;
})
.filter((option) => option !== null);
@@ -201,9 +189,10 @@ export const MessageToolbox = ({
style={styleOverrides}
{...props}
>
- {toolOptions.slice(0, threshold).map((key) => toolMap[key])}
-
- {menuOptions.length > 0 && (
+ {surfaceOptions?.length > 0 && (
+
+ )}
+ {menuOptions?.length > 0 && (
);
};
From 348a05ec4fcd5e1ecdc905b2151b5f24186f840c Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 12:55:57 +0530
Subject: [PATCH 017/104] changed render way of chatformat in layout editor
---
.../components/SurfaceMenu/SurfaceItem.jsx | 27 ++---
.../components/SurfaceMenu/SurfaceMenu.jsx | 4 +-
.../ChatInput/ChatInputFormattingToolbar.jsx | 113 +++++++++++-------
3 files changed, 83 insertions(+), 61 deletions(-)
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
index f293f060f..28890b26f 100644
--- a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
@@ -10,21 +10,16 @@ import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { getSurfaceItemStyles } from "./SurfaceMenu.styles";
-const SurfaceItem = ({ id, label, iconName, onClick }) => {
- const {
- attributes,
- listeners,
- setNodeRef,
- transform,
- isDragging,
- } = useSortable({
- id,
- data: {
- type: "SurfaceOptions",
- icon: iconName,
- label,
- },
- });
+const SurfaceItem = ({ id, label, iconName, onClick, position = "bottom" }) => {
+ const { attributes, listeners, setNodeRef, transform, isDragging } =
+ useSortable({
+ id,
+ data: {
+ type: "SurfaceOptions",
+ icon: iconName,
+ label,
+ },
+ });
const theme = useTheme();
const styles = getSurfaceItemStyles(theme);
@@ -38,7 +33,7 @@ const SurfaceItem = ({ id, label, iconName, onClick }) => {
return (
-
+
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
index d15f3337a..84ce15692 100644
--- a/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
@@ -2,11 +2,11 @@ import React from "react";
import SurfaceItem from "./SurfaceItem";
import { SortableContext } from "@dnd-kit/sortable";
-const SurfaceMenu = ({ options }) => {
+const SurfaceMenu = ({ options, tooltipPosition }) => {
return (
{options?.map((item, idx) => (
-
+
))}
);
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx b/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
index 855bf1acb..ed4faa82c 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
+++ b/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
@@ -1,7 +1,8 @@
-import React from "react";
-import { Box, Icon, ActionButton, Tooltip } from "@embeddedchat/ui-elements";
+import React, { useMemo } from "react";
+import { Box } from "@embeddedchat/ui-elements";
import { formatter } from "../../lib/textFormat";
import { useChatInputFormattingToolbarStyles } from "./ChatInput.styles";
+import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
const ChatInputFormattingToolbar = ({
optionConfig = {
@@ -9,51 +10,77 @@ const ChatInputFormattingToolbar = ({
},
}) => {
const styles = useChatInputFormattingToolbarStyles();
- const surfaceItems = optionConfig.surfaceItems;
+ const { surfaceItems } = optionConfig;
+ const placeholderSurfaceItem = "placeholder-surface";
- const chatToolMap = {
- emoji: (
-
-
-
-
-
-
-
- ),
- audio: (
-
-
-
-
-
- ),
- video: (
-
-
-
-
-
- ),
- file: (
-
-
-
-
-
- ),
- formatter: formatter.map((item) => (
-
-
-
-
-
- )),
- };
+ const options = useMemo(() => {
+ const formatterOptions = formatter.map((item) => ({
+ label: item.name,
+ id: `formatter-${item.name}`,
+ onClick: item.onClick || (() => {}),
+ iconName: item.name,
+ visible: true,
+ }));
+ return {
+ emoji: {
+ label: "Emoji",
+ id: "emoji",
+ onClick: () => {},
+ iconName: "emoji",
+ visible: true,
+ },
+ audio: {
+ label: "Audio Message",
+ id: "audio",
+ onClick: () => {},
+ iconName: "mic",
+ visible: true,
+ },
+ video: {
+ label: "Video Message",
+ id: "video",
+ onClick: () => {},
+ iconName: "video-recorder",
+ visible: true,
+ },
+ file: {
+ label: "Upload File",
+ id: "file",
+ onClick: () => {},
+ iconName: "attachment",
+ visible: true,
+ },
+ formatter: formatterOptions,
+ };
+ }, []);
+
+ const surfaceOptions = useMemo(() => {
+ return surfaceItems.length > 0
+ ? surfaceItems
+ .map((item) => {
+ if (item === "formatter") {
+ return options.formatter;
+ }
+ if (options[item] && options[item].visible) {
+ return {
+ id: options[item].id,
+ onClick: options[item].onClick,
+ label: options[item].label,
+ iconName: options[item].iconName,
+ };
+ }
+ return null;
+ })
+ .flat()
+ .filter((option) => option !== null)
+ : [{ id: placeholderSurfaceItem, label: "No items", iconName: "plus" }];
+ }, [surfaceItems, options]);
return (
- {surfaceItems.map((key) => chatToolMap[key])}
+ {surfaceOptions.length > 0 && (
+
+ )}
);
};
From 910500d0305a461729f5f49ebade1805044b8fde Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 13:30:50 +0530
Subject: [PATCH 018/104] added formatter config
---
.../ChatInput/ChatInputFormattingToolbar.jsx | 25 ++++++++++---------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx b/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
index ed4faa82c..f29dcea3f 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
+++ b/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
@@ -7,21 +7,14 @@ import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
const ChatInputFormattingToolbar = ({
optionConfig = {
surfaceItems: ["emoji", "formatter", "audio", "video", "file"],
+ formatters: ["bold", "italic", "strike", "code", "multiline"],
},
}) => {
const styles = useChatInputFormattingToolbarStyles();
- const { surfaceItems } = optionConfig;
+ const { surfaceItems, formatters } = optionConfig;
const placeholderSurfaceItem = "placeholder-surface";
const options = useMemo(() => {
- const formatterOptions = formatter.map((item) => ({
- label: item.name,
- id: `formatter-${item.name}`,
- onClick: item.onClick || (() => {}),
- iconName: item.name,
- visible: true,
- }));
-
return {
emoji: {
label: "Emoji",
@@ -51,9 +44,17 @@ const ChatInputFormattingToolbar = ({
iconName: "attachment",
visible: true,
},
- formatter: formatterOptions,
+ formatter: formatter
+ .filter((item) => formatters.includes(item.name))
+ .map((item) => ({
+ label: item.name,
+ id: `formatter-${item.name}`,
+ onClick: item.onClick || (() => {}),
+ iconName: item.name,
+ visible: true,
+ })),
};
- }, []);
+ }, [formatters]);
const surfaceOptions = useMemo(() => {
return surfaceItems.length > 0
@@ -72,10 +73,10 @@ const ChatInputFormattingToolbar = ({
}
return null;
})
- .flat()
.filter((option) => option !== null)
: [{ id: placeholderSurfaceItem, label: "No items", iconName: "plus" }];
}, [surfaceItems, options]);
+
return (
{surfaceOptions.length > 0 && (
From 82b4d5fb33a28cd73c27370f834e4fa8e3edbca9 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 13:31:11 +0530
Subject: [PATCH 019/104] changed icon generator location
---
packages/react/package.json | 1 -
packages/ui-elements/package.json | 1 +
packages/{react => ui-elements}/tools/icons-generator.js | 1 +
yarn.lock | 2 +-
4 files changed, 3 insertions(+), 2 deletions(-)
rename packages/{react => ui-elements}/tools/icons-generator.js (99%)
diff --git a/packages/react/package.json b/packages/react/package.json
index 26dd7d84b..476cbf026 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -90,7 +90,6 @@
"@emotion/react": "11.7.1",
"@rocket.chat/emitter": "^0.31.25",
"@rocket.chat/fuselage-hooks": "^0.33.1",
- "@rocket.chat/icons": "^0.31.23",
"@rocket.chat/ui-kit": "^0.31.25",
"@rollup/plugin-json": "^6.0.0",
"date-fns": "^2.30.0",
diff --git a/packages/ui-elements/package.json b/packages/ui-elements/package.json
index 5e418bf2b..ed205907f 100644
--- a/packages/ui-elements/package.json
+++ b/packages/ui-elements/package.json
@@ -33,6 +33,7 @@
"@babel/preset-react": "^7.16.7",
"@emotion/babel-plugin": "^11.11.0",
"@open-wc/building-rollup": "^3.0.2",
+ "@rocket.chat/icons": "^0.31.23",
"@rollup/plugin-babel": "^5.3.1",
"@rollup/plugin-commonjs": "^21.0.2",
"@rollup/plugin-node-resolve": "^13.1.3",
diff --git a/packages/react/tools/icons-generator.js b/packages/ui-elements/tools/icons-generator.js
similarity index 99%
rename from packages/react/tools/icons-generator.js
rename to packages/ui-elements/tools/icons-generator.js
index 228b4ca27..4f5173298 100644
--- a/packages/react/tools/icons-generator.js
+++ b/packages/ui-elements/tools/icons-generator.js
@@ -48,6 +48,7 @@ const iconsList = [
'arrow-collapse',
'arrow-expand',
];
+
const svgDirPath = path.join(
__dirname,
'../../../node_modules/@rocket.chat/icons/dist/svg'
diff --git a/yarn.lock b/yarn.lock
index 6c48db18d..8c81f2c8b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2448,7 +2448,6 @@ __metadata:
"@open-wc/building-rollup": ^3.0.2
"@rocket.chat/emitter": ^0.31.25
"@rocket.chat/fuselage-hooks": ^0.33.1
- "@rocket.chat/icons": ^0.31.23
"@rocket.chat/ui-kit": ^0.31.25
"@rollup/plugin-babel": ^5.3.1
"@rollup/plugin-commonjs": ^21.0.2
@@ -2520,6 +2519,7 @@ __metadata:
"@emotion/babel-preset-css-prop": ^11.11.0
"@emotion/react": 11.7.1
"@open-wc/building-rollup": ^3.0.2
+ "@rocket.chat/icons": ^0.31.23
"@rollup/plugin-babel": ^5.3.1
"@rollup/plugin-commonjs": ^21.0.2
"@rollup/plugin-json": ^6.0.0
From 53784f7640602b86504418cb26d9138261c0af22 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 14:03:46 +0530
Subject: [PATCH 020/104] icon generator to not edit index file
---
packages/ui-elements/tools/icons-generator.js | 21 -------------------
1 file changed, 21 deletions(-)
diff --git a/packages/ui-elements/tools/icons-generator.js b/packages/ui-elements/tools/icons-generator.js
index 4f5173298..238cbae34 100644
--- a/packages/ui-elements/tools/icons-generator.js
+++ b/packages/ui-elements/tools/icons-generator.js
@@ -6,7 +6,6 @@ const iconsList = [
'file',
'mobile',
'star',
- 'pin',
'reply-directly',
'hash',
'computer',
@@ -42,7 +41,6 @@ const iconsList = [
'chevron-down',
'chevron-left',
'key',
- 'attachment',
'quote',
'at',
'arrow-collapse',
@@ -80,24 +78,6 @@ const getComponentCode = (name, svgData) => `
export default ${camelCase(name)};
`;
-const getIndexFileCode = () => {
- const importCodes = iconsList
- .map((icon) => `import ${camelCase(icon)} from './${camelCase(icon)}';`)
- .join('\n');
- const exportCodes = iconsList
- .map((icon) => `"${icon}": ${camelCase(icon)}`)
- .join(',\n');
- return `
- ${importCodes}
-
- const icons = {
- ${exportCodes}
- };
-
- export default icons;
- `;
-};
-
if (!fs.existsSync(svgIconOutputDir)) {
fs.mkdirSync(svgIconOutputDir, { recursive: true });
}
@@ -112,5 +92,4 @@ iconsList.forEach((icon) => {
fs.writeFileSync(svgIconOutputPath, componentCode);
});
-fs.writeFileSync(path.join(svgIconOutputDir, 'index.js'), getIndexFileCode());
execSync(`npx prettier --write '${svgIconOutputDir}' `);
From 833e3e1cc87c30aa6c6a03ebc20a412fdf8d4dbd Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 14:17:30 +0530
Subject: [PATCH 021/104] added text formatter icon
---
.../src/components/Icon/icons/FormatText.js | 17 +++++++++++++++++
.../src/components/Icon/icons/index.js | 2 ++
2 files changed, 19 insertions(+)
create mode 100644 packages/ui-elements/src/components/Icon/icons/FormatText.js
diff --git a/packages/ui-elements/src/components/Icon/icons/FormatText.js b/packages/ui-elements/src/components/Icon/icons/FormatText.js
new file mode 100644
index 000000000..8ff48e2cf
--- /dev/null
+++ b/packages/ui-elements/src/components/Icon/icons/FormatText.js
@@ -0,0 +1,17 @@
+import React from 'react';
+
+function FormatText(props) {
+ return (
+
+ );
+}
+
+export default FormatText;
diff --git a/packages/ui-elements/src/components/Icon/icons/index.js b/packages/ui-elements/src/components/Icon/icons/index.js
index a58cba2f8..8f0a26de2 100644
--- a/packages/ui-elements/src/components/Icon/icons/index.js
+++ b/packages/ui-elements/src/components/Icon/icons/index.js
@@ -59,6 +59,7 @@ import Expand from './ArrowExpand';
import Collapse from './ArrowCollapse';
import Arc from './Arc';
import Avatar from './Avatar';
+import FormatText from './FormatText';
const icons = {
file: File,
@@ -122,6 +123,7 @@ const icons = {
collapse: Collapse,
arc: Arc,
avatar: Avatar,
+ 'format-text': FormatText,
};
export default icons;
From f0794f10ae24a9990f1e8a38fab45d8c83480210 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 14:17:53 +0530
Subject: [PATCH 022/104] render text format icon
---
packages/layout_editor/src/lib/textFormat.js | 7 -------
.../ChatInput/ChatInputFormattingToolbar.jsx | 19 ++++++++-----------
2 files changed, 8 insertions(+), 18 deletions(-)
delete mode 100644 packages/layout_editor/src/lib/textFormat.js
diff --git a/packages/layout_editor/src/lib/textFormat.js b/packages/layout_editor/src/lib/textFormat.js
deleted file mode 100644
index 10ceb7f33..000000000
--- a/packages/layout_editor/src/lib/textFormat.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export const formatter = [
- { name: 'bold', pattern: '*{{text}}*' },
- { name: 'italic', pattern: '_{{text}}_' },
- { name: 'strike', pattern: '~{{text}}~' },
- { name: 'code', pattern: '`{{text}}`' },
- { name: 'multiline', pattern: '```\n{{text}}\n``` ' },
-];
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx b/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
index f29dcea3f..191569e52 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
+++ b/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
@@ -1,6 +1,5 @@
import React, { useMemo } from "react";
import { Box } from "@embeddedchat/ui-elements";
-import { formatter } from "../../lib/textFormat";
import { useChatInputFormattingToolbarStyles } from "./ChatInput.styles";
import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
@@ -44,17 +43,15 @@ const ChatInputFormattingToolbar = ({
iconName: "attachment",
visible: true,
},
- formatter: formatter
- .filter((item) => formatters.includes(item.name))
- .map((item) => ({
- label: item.name,
- id: `formatter-${item.name}`,
- onClick: item.onClick || (() => {}),
- iconName: item.name,
- visible: true,
- })),
+ formatter: {
+ label: "Formatter",
+ id: "formatter",
+ onClick: () => {},
+ iconName: "format-text",
+ visible: true,
+ },
};
- }, [formatters]);
+ }, []);
const surfaceOptions = useMemo(() => {
return surfaceItems.length > 0
From 9db94568fc8eeb1e61b71e0915ed8272c6c1caf6 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 14:21:24 +0530
Subject: [PATCH 023/104] changed linting rules
---
packages/layout_editor/.eslintrc.cjs | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/layout_editor/.eslintrc.cjs b/packages/layout_editor/.eslintrc.cjs
index aced9b503..8153c0c9e 100644
--- a/packages/layout_editor/.eslintrc.cjs
+++ b/packages/layout_editor/.eslintrc.cjs
@@ -21,5 +21,6 @@ module.exports = {
],
"react/prop-types": "off",
"react/no-unknown-property": ["error", { ignore: ["css"] }],
+ "@typescript-eslint/no-unused-vars": ["warn"],
},
};
From fa848e0e7142582e54fde640092820693ba51558 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 14:37:25 +0530
Subject: [PATCH 024/104] add drag drop in chatInputFormattingToolbar
---
.../ChatInput/ChatInputFormattingToolbar.jsx | 76 +++++++++++++++++--
1 file changed, 69 insertions(+), 7 deletions(-)
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx b/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
index 191569e52..0b2ef4bb6 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
+++ b/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
@@ -1,7 +1,19 @@
-import React, { useMemo } from "react";
+import React, { useMemo, useState } from "react";
import { Box } from "@embeddedchat/ui-elements";
import { useChatInputFormattingToolbarStyles } from "./ChatInput.styles";
import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
+import SurfaceItem from "../../components/SurfaceMenu/SurfaceItem";
+import {
+ DndContext,
+ closestCenter,
+ KeyboardSensor,
+ PointerSensor,
+ useSensor,
+ useSensors,
+ DragOverlay,
+} from "@dnd-kit/core";
+import { sortableKeyboardCoordinates, arrayMove } from "@dnd-kit/sortable";
+import { createPortal } from "react-dom";
const ChatInputFormattingToolbar = ({
optionConfig = {
@@ -10,7 +22,8 @@ const ChatInputFormattingToolbar = ({
},
}) => {
const styles = useChatInputFormattingToolbarStyles();
- const { surfaceItems, formatters } = optionConfig;
+ const [surfaceItems, setSurfaceItems] = useState(optionConfig.surfaceItems);
+ const [activeSurfaceItem, setActiveSurfaceItem] = useState(null);
const placeholderSurfaceItem = "placeholder-surface";
const options = useMemo(() => {
@@ -43,7 +56,7 @@ const ChatInputFormattingToolbar = ({
iconName: "attachment",
visible: true,
},
- formatter: {
+ formatter: {
label: "Formatter",
id: "formatter",
onClick: () => {},
@@ -53,6 +66,41 @@ const ChatInputFormattingToolbar = ({
};
}, []);
+ const sensors = useSensors(
+ useSensor(PointerSensor),
+ useSensor(KeyboardSensor, {
+ coordinateGetter: sortableKeyboardCoordinates,
+ })
+ );
+
+ const handleDragStart = (event) => {
+ if (event.active.data.current?.type === "SurfaceOptions") {
+ setActiveSurfaceItem({
+ id: event.active.id,
+ iconName: event.active.data.current.icon,
+ label: event.active.data.current.label,
+ });
+ }
+ };
+
+ const handleDragEnd = (event) => {
+ setActiveSurfaceItem(null);
+ const { active, over } = event;
+
+ if (active.id !== over.id) {
+ if (
+ event.active.data.current?.type === "SurfaceOptions" &&
+ event.over.data.current?.type === "SurfaceOptions"
+ ) {
+ setSurfaceItems((items) => {
+ const oldIndex = items.indexOf(active.id);
+ const newIndex = items.indexOf(over.id);
+ return arrayMove(items, oldIndex, newIndex);
+ });
+ }
+ }
+ };
+
const surfaceOptions = useMemo(() => {
return surfaceItems.length > 0
? surfaceItems
@@ -75,11 +123,25 @@ const ChatInputFormattingToolbar = ({
}, [surfaceItems, options]);
return (
-
- {surfaceOptions.length > 0 && (
-
+
+
+ {surfaceOptions.length > 0 && (
+
+ )}
+
+
+ {createPortal(
+
+ {activeSurfaceItem && }
+ ,
+ document.body
)}
-
+
);
};
From 7f5a33c11734072fcda47100165449e6cc0b41e0 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 16:05:51 +0530
Subject: [PATCH 025/104] added dummy messages
---
packages/layout_editor/.eslintrc.cjs | 6 +-
.../components/SurfaceMenu/SurfaceItem.jsx | 25 +-
.../components/SurfaceMenu/SurfaceMenu.jsx | 9 +-
packages/layout_editor/src/data/messages.json | 132 ++++++++
.../src/hooks/useDisplayNameColor.js | 27 ++
.../src/lib/isMessageLastSequential.js | 19 ++
.../src/lib/isMessageSequential.js | 34 ++
.../layout_editor/src/theme/DefaultTheme.js | 134 ++++----
.../src/views/Markdown/Markdown.jsx | 29 ++
.../layout_editor/src/views/Markdown/index.js | 1 +
.../Message/BubbleVariant/Bubble.styles.js | 200 ++++++++++++
.../Message/BubbleVariant/BubbleThreadBtn.js | 31 ++
.../Message/BubbleVariant/useBubbleStyles.js | 20 ++
.../src/views/Message/Message.jsx | 88 +++++
.../src/views/Message/Message.styles.js | 300 ++++++++++++++++++
.../views/Message/MessageAvatarContainer.jsx | 21 ++
.../src/views/Message/MessageBody.jsx | 30 ++
.../views/Message/MessageBodyContainer.jsx | 19 ++
.../src/views/Message/MessageDivider.jsx | 34 ++
.../src/views/Message/MessageHeader.jsx | 62 ++++
.../src/views/Message/MessageToolbox.jsx | 142 +++++++++
.../layout_editor/src/views/Message/index.js | 1 +
.../src/views/MessageList/MessageList.jsx | 60 +++-
23 files changed, 1340 insertions(+), 84 deletions(-)
create mode 100644 packages/layout_editor/src/data/messages.json
create mode 100644 packages/layout_editor/src/hooks/useDisplayNameColor.js
create mode 100644 packages/layout_editor/src/lib/isMessageLastSequential.js
create mode 100644 packages/layout_editor/src/lib/isMessageSequential.js
create mode 100644 packages/layout_editor/src/views/Markdown/Markdown.jsx
create mode 100644 packages/layout_editor/src/views/Markdown/index.js
create mode 100644 packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js
create mode 100644 packages/layout_editor/src/views/Message/BubbleVariant/BubbleThreadBtn.js
create mode 100644 packages/layout_editor/src/views/Message/BubbleVariant/useBubbleStyles.js
create mode 100644 packages/layout_editor/src/views/Message/Message.jsx
create mode 100644 packages/layout_editor/src/views/Message/Message.styles.js
create mode 100644 packages/layout_editor/src/views/Message/MessageAvatarContainer.jsx
create mode 100644 packages/layout_editor/src/views/Message/MessageBody.jsx
create mode 100644 packages/layout_editor/src/views/Message/MessageBodyContainer.jsx
create mode 100644 packages/layout_editor/src/views/Message/MessageDivider.jsx
create mode 100644 packages/layout_editor/src/views/Message/MessageHeader.jsx
create mode 100644 packages/layout_editor/src/views/Message/MessageToolbox.jsx
create mode 100644 packages/layout_editor/src/views/Message/index.js
diff --git a/packages/layout_editor/.eslintrc.cjs b/packages/layout_editor/.eslintrc.cjs
index 8153c0c9e..92640d851 100644
--- a/packages/layout_editor/.eslintrc.cjs
+++ b/packages/layout_editor/.eslintrc.cjs
@@ -4,15 +4,15 @@ module.exports = {
extends: [
"eslint:recommended",
"plugin:react/jsx-runtime",
- 'plugin:@typescript-eslint/recommended',
+ "plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
"plugin:react/recommended",
],
ignorePatterns: ["dist", ".eslintrc.cjs"],
- parser: '@typescript-eslint/parser',
+ parser: "@typescript-eslint/parser",
parserOptions: { ecmaVersion: "latest", sourceType: "module" },
settings: { react: { version: "18.2" } },
- plugins: ["react-refresh"],
+ plugins: ["react-refresh", "import"],
rules: {
"react/jsx-no-target-blank": "off",
"react-refresh/only-export-components": [
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
index 28890b26f..573bde6ab 100644
--- a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
@@ -2,7 +2,6 @@ import React from "react";
import {
Tooltip,
ActionButton,
- Icon,
Box,
useTheme,
} from "@embeddedchat/ui-elements";
@@ -10,7 +9,15 @@ import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { getSurfaceItemStyles } from "./SurfaceMenu.styles";
-const SurfaceItem = ({ id, label, iconName, onClick, position = "bottom" }) => {
+const SurfaceItem = ({
+ id,
+ label,
+ iconName,
+ onClick,
+ type,
+ position = "bottom",
+ size,
+}) => {
const { attributes, listeners, setNodeRef, transform, isDragging } =
useSortable({
id,
@@ -33,10 +40,16 @@ const SurfaceItem = ({ id, label, iconName, onClick, position = "bottom" }) => {
return (
-
-
-
-
+
+
);
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
index 84ce15692..f42799553 100644
--- a/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
@@ -2,11 +2,16 @@ import React from "react";
import SurfaceItem from "./SurfaceItem";
import { SortableContext } from "@dnd-kit/sortable";
-const SurfaceMenu = ({ options, tooltipPosition }) => {
+const SurfaceMenu = ({ options, tooltipPosition, size = "medium" }) => {
return (
{options?.map((item, idx) => (
-
+
))}
);
diff --git a/packages/layout_editor/src/data/messages.json b/packages/layout_editor/src/data/messages.json
new file mode 100644
index 000000000..26d5d2c60
--- /dev/null
+++ b/packages/layout_editor/src/data/messages.json
@@ -0,0 +1,132 @@
+[
+ {
+ "_id": "wz5cNwELaK6MnZWkN",
+ "rid": "GENERAL",
+ "msg": "That's great to hear! It's exciting that we can now customize the EmbeddedChat design using this layout editor. This will open up so many possibilities for tailoring the user experience exactly to our needs. Looking forward to seeing what we can create with it!",
+ "ts": "2024-07-14T09:22:39.277Z",
+ "u": {
+ "_id": "a9bAtEYzGoTHvtxws",
+ "username": "sidmohanty11",
+ "name": "Sidharth Mohanty"
+ },
+ "_updatedAt": "2024-07-14T09:22:39.362Z",
+ "urls": [],
+ "mentions": [],
+ "channels": [],
+ "md": [
+ {
+ "type": "PARAGRAPH",
+ "value": [
+ {
+ "type": "PLAIN_TEXT",
+ "value": "That's great to hear! It's exciting that we can now customize the EmbeddedChat design using this layout editor. This will open up so many possibilities for tailoring the user experience exactly to our needs. Looking forward to seeing what we can create with it!"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "_id": "62vhmKJGNoxgvLL7M",
+ "rid": "GENERAL",
+ "msg": "Do give it a try !",
+ "ts": "2024-07-14T09:22:16.995Z",
+ "u": {
+ "_id": "c9bAtEYzGoTHvtxws",
+ "username": "spiral_memory",
+ "name": "Zishan Ahmad"
+ },
+ "_updatedAt": "2024-07-14T09:22:17.039Z",
+ "urls": [],
+ "mentions": [],
+ "channels": [],
+ "md": [
+ {
+ "type": "PARAGRAPH",
+ "value": [
+ {
+ "type": "PLAIN_TEXT",
+ "value": "Do give it a try !"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "_id": "7JkH8StoJxeN8ftcn",
+ "rid": "GENERAL",
+ "msg": "I am good as well. We can now customize the EmbeddedChat design with this layout editor.",
+ "ts": "2024-07-14T09:22:11.965Z",
+ "u": {
+ "_id": "c9bAtEYzGoTHvtxws",
+ "username": "spiral_memory",
+ "name": "Zishan Ahmad"
+ },
+ "_updatedAt": "2024-07-14T09:22:12.015Z",
+ "urls": [],
+ "mentions": [],
+ "channels": [],
+ "md": [
+ {
+ "type": "PARAGRAPH",
+ "value": [
+ {
+ "type": "PLAIN_TEXT",
+ "value": "I am good as well. We can now customize the EmbeddedChat design with this layout editor."
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "_id": "DBLBa3TwkWSyW9ADz",
+ "rid": "GENERAL",
+ "msg": "I am good, How about you?",
+ "ts": "2024-07-14T09:21:20.600Z",
+ "u": {
+ "_id": "a9bAtEYzGoTHvtxws",
+ "username": "sidmohanty11",
+ "name": "Sidharth Mohanty"
+ },
+ "_updatedAt": "2024-07-14T09:21:20.688Z",
+ "urls": [],
+ "mentions": [],
+ "channels": [],
+ "md": [
+ {
+ "type": "PARAGRAPH",
+ "value": [
+ {
+ "type": "PLAIN_TEXT",
+ "value": "I am good, How about you?"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "_id": "nt6L6bijA7CNWd2ci",
+ "rid": "GENERAL",
+ "msg": "Hey, How are you Sidharth ?",
+ "ts": "2024-07-14T09:21:08.470Z",
+ "u": {
+ "_id": "c9bAtEYzGoTHvtxws",
+ "username": "spiral_memory",
+ "name": "Zishan Ahmad"
+ },
+ "_updatedAt": "2024-07-14T09:21:08.551Z",
+ "urls": [],
+ "mentions": [],
+ "channels": [],
+ "md": [
+ {
+ "type": "PARAGRAPH",
+ "value": [
+ {
+ "type": "PLAIN_TEXT",
+ "value": "Hey, How are you Sidharth ?"
+ }
+ ]
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/packages/layout_editor/src/hooks/useDisplayNameColor.js b/packages/layout_editor/src/hooks/useDisplayNameColor.js
new file mode 100644
index 000000000..5e9c32c07
--- /dev/null
+++ b/packages/layout_editor/src/hooks/useDisplayNameColor.js
@@ -0,0 +1,27 @@
+/* eslint-disable no-bitwise */
+import { useTheme } from '@embeddedchat/ui-elements';
+
+const simpleHash = (str) => {
+ if (!str) return 0;
+ let hash = 0;
+ for (let i = 0; i < str.length; i += 1) {
+ const char = str.charCodeAt(i);
+ hash = (hash << 5) - hash + char;
+ }
+ return hash;
+};
+
+const useDisplayNameColor = () => {
+ const { theme, mode } = useTheme();
+
+ const getDisplayNameColor = (username) => {
+ const hash = simpleHash(username);
+ const { saturation, luminance } = theme.schemes.contrastParams[mode];
+ const hue = Math.abs(hash) % 360;
+ return `hsl(${hue}, ${saturation}%, ${luminance}%)`;
+ };
+
+ return getDisplayNameColor;
+};
+
+export default useDisplayNameColor;
diff --git a/packages/layout_editor/src/lib/isMessageLastSequential.js b/packages/layout_editor/src/lib/isMessageLastSequential.js
new file mode 100644
index 000000000..ee558c463
--- /dev/null
+++ b/packages/layout_editor/src/lib/isMessageLastSequential.js
@@ -0,0 +1,19 @@
+import isMessageSequential from './isMessageSequential';
+
+const isMessageLastSequential = (current, next) => {
+ if (!next) {
+ return true;
+ }
+
+ if (current.u._id !== next.u._id) {
+ return true;
+ }
+
+ if (!isMessageSequential(next, current, 300)) {
+ return true;
+ }
+
+ return false;
+};
+
+export default isMessageLastSequential;
diff --git a/packages/layout_editor/src/lib/isMessageSequential.js b/packages/layout_editor/src/lib/isMessageSequential.js
new file mode 100644
index 000000000..261713675
--- /dev/null
+++ b/packages/layout_editor/src/lib/isMessageSequential.js
@@ -0,0 +1,34 @@
+import { differenceInSeconds, isSameDay } from 'date-fns';
+
+const isMessageSequential = (current, previous, groupingRange) => {
+ if (!previous) {
+ return false;
+ }
+
+ if (current.t || previous.t) {
+ return false;
+ }
+
+ if (current.groupable === false) {
+ return false;
+ }
+
+ if (current.u._id !== previous.u._id) {
+ return false;
+ }
+
+ if (current.alias !== previous.alias) {
+ return false;
+ }
+
+ const isTimeDiffSmall =
+ differenceInSeconds(new Date(current.ts), new Date(previous.ts)) <
+ groupingRange;
+
+ const isMessageNewDay =
+ !previous || !isSameDay(new Date(current.ts), new Date(previous.ts));
+
+ return isTimeDiffSmall && !isMessageNewDay;
+};
+
+export default isMessageSequential;
diff --git a/packages/layout_editor/src/theme/DefaultTheme.js b/packages/layout_editor/src/theme/DefaultTheme.js
index bcf1ac888..5392a374f 100644
--- a/packages/layout_editor/src/theme/DefaultTheme.js
+++ b/packages/layout_editor/src/theme/DefaultTheme.js
@@ -1,63 +1,73 @@
const DefaultTheme = {
schemes: {
- radius: '0.2rem',
+ radius: "0.2rem",
+ contrastParams: {
+ light: {
+ saturation: 70,
+ luminance: 19,
+ },
+ dark: {
+ saturation: 88,
+ luminance: 77,
+ },
+ },
common: {
- black: 'hsl(0, 100%, 0%)',
- white: 'hsl(0, 100%, 100%)',
+ black: "hsl(0, 100%, 0%)",
+ white: "hsl(0, 100%, 100%)",
},
light: {
- background: 'hsl(0, 0%, 100%)',
- foreground: 'hsl(240, 10%, 3.9%)',
- card: 'hsl(0, 0%, 100%)',
- cardForeground: 'hsl(240, 10%, 3.9%)',
- popover: 'hsl(0, 0%, 100%)',
- popoverForeground: 'hsl(240, 10%, 3.9%)',
- primary: 'hsl(240, 5.9%, 10%)',
- primaryForeground: 'hsl(0, 0%, 98%)',
- secondary: 'hsl(240, 4.8%, 95.9%)',
- secondaryForeground: 'hsl(240, 5.9%, 10%)',
- muted: 'hsl(240, 4.8%, 95.9%)',
- mutedForeground: 'hsl(240, 3.8%, 46.1%)',
- accent: 'hsl(240, 4.8%, 95.9%)',
- accentForeground: 'hsl(240, 5.9%, 10%)',
- destructive: 'hsl(0, 84.2%, 60.2%)',
- destructiveForeground: 'hsl(0, 0%, 98%)',
- border: 'hsl(240, 5.9%, 90%)',
- input: 'hsl(240, 5.9%, 90%)',
- ring: 'hsl(240, 5.9%, 10%)',
- warning: 'hsl(38, 92%, 50%)',
- warningForeground: 'hsl(48, 96%, 89%)',
- success: 'hsl(91, 60.4%, 81.2%)',
- successForeground: 'hsl(90, 61.1%, 14.1%)',
- info: 'hsl(214, 76.4%, 50.2%)',
- infoForeground: 'hsl(214.3, 77.8%, 92.9%)',
+ background: "hsl(0, 0%, 100%)",
+ foreground: "hsl(240, 10%, 3.9%)",
+ card: "hsl(0, 0%, 100%)",
+ cardForeground: "hsl(240, 10%, 3.9%)",
+ popover: "hsl(0, 0%, 100%)",
+ popoverForeground: "hsl(240, 10%, 3.9%)",
+ primary: "hsl(240, 5.9%, 10%)",
+ primaryForeground: "hsl(0, 0%, 98%)",
+ secondary: "hsl(240, 4.8%, 95.9%)",
+ secondaryForeground: "hsl(240, 5.9%, 10%)",
+ muted: "hsl(240, 4.8%, 95.9%)",
+ mutedForeground: "hsl(240, 3.8%, 46.1%)",
+ accent: "hsl(240, 4.8%, 95.9%)",
+ accentForeground: "hsl(240, 5.9%, 10%)",
+ destructive: "hsl(0, 84.2%, 60.2%)",
+ destructiveForeground: "hsl(0, 0%, 98%)",
+ border: "hsl(240, 5.9%, 90%)",
+ input: "hsl(240, 5.9%, 90%)",
+ ring: "hsl(240, 5.9%, 10%)",
+ warning: "hsl(38, 92%, 50%)",
+ warningForeground: "hsl(48, 96%, 89%)",
+ success: "hsl(91, 60.4%, 81.2%)",
+ successForeground: "hsl(90, 61.1%, 14.1%)",
+ info: "hsl(214, 76.4%, 50.2%)",
+ infoForeground: "hsl(214.3, 77.8%, 92.9%)",
},
dark: {
- background: 'hsl(240, 10%, 3.9%)',
- foreground: 'hsl(0, 0%, 98%)',
- card: 'hsl(240, 10%, 3.9%)',
- cardForeground: 'hsl(0, 0%, 98%)',
- popover: 'hsl(240, 10%, 3.9%)',
- popoverForeground: 'hsl(0, 0%, 98%)',
- primary: 'hsl(0, 0%, 98%)',
- primaryForeground: 'hsl(240, 5.9%, 10%)',
- secondary: 'hsl(240, 3.7%, 15.9%)',
- secondaryForeground: 'hsl(0, 0%, 98%)',
- muted: 'hsl(240, 3.7%, 15.9%)',
- mutedForeground: 'hsl(240, 5%, 64.9%)',
- accent: 'hsl(240, 3.7%, 15.9%)',
- accentForeground: 'hsl(0, 0%, 98%)',
- destructive: 'hsl(0, 62.8%, 30.6%)',
- destructiveForeground: 'hsl(0, 0%, 98%)',
- border: 'hsl(240, 3.7%, 15.9%)',
- input: 'hsl(240, 3.7%, 15.9%)',
- ring: 'hsl(240, 4.9%, 83.9%)',
- warning: 'hsl(48, 96%, 89%)',
- warningForeground: 'hsl(38, 92%, 50%)',
- success: 'hsl(90, 61.1%, 14.1%)',
- successForeground: 'hsl(90, 60%, 90.2%)',
- info: 'hsl(214.3, 77.8%, 92.9%)',
- infoForeground: 'hsl(214.4, 75.8%, 19.4%)',
+ background: "hsl(240, 10%, 3.9%)",
+ foreground: "hsl(0, 0%, 98%)",
+ card: "hsl(240, 10%, 3.9%)",
+ cardForeground: "hsl(0, 0%, 98%)",
+ popover: "hsl(240, 10%, 3.9%)",
+ popoverForeground: "hsl(0, 0%, 98%)",
+ primary: "hsl(0, 0%, 98%)",
+ primaryForeground: "hsl(240, 5.9%, 10%)",
+ secondary: "hsl(240, 3.7%, 15.9%)",
+ secondaryForeground: "hsl(0, 0%, 98%)",
+ muted: "hsl(240, 3.7%, 15.9%)",
+ mutedForeground: "hsl(240, 5%, 64.9%)",
+ accent: "hsl(240, 3.7%, 15.9%)",
+ accentForeground: "hsl(0, 0%, 98%)",
+ destructive: "hsl(0, 62.8%, 30.6%)",
+ destructiveForeground: "hsl(0, 0%, 98%)",
+ border: "hsl(240, 3.7%, 15.9%)",
+ input: "hsl(240, 3.7%, 15.9%)",
+ ring: "hsl(240, 4.9%, 83.9%)",
+ warning: "hsl(48, 96%, 89%)",
+ warningForeground: "hsl(38, 92%, 50%)",
+ success: "hsl(90, 61.1%, 14.1%)",
+ successForeground: "hsl(90, 60%, 90.2%)",
+ info: "hsl(214.3, 77.8%, 92.9%)",
+ infoForeground: "hsl(214.4, 75.8%, 19.4%)",
},
},
@@ -77,34 +87,34 @@ const DefaultTheme = {
fontWeightRegular: 400,
},
h1: {
- fontSize: '2rem',
+ fontSize: "2rem",
fontWeight: 800,
},
h2: {
- fontSize: '1.5rem',
+ fontSize: "1.5rem",
fontWeight: 800,
},
h3: {
- fontSize: '1.3rem',
+ fontSize: "1.3rem",
fontWeight: 400,
},
h4: {
- fontSize: '1rem',
+ fontSize: "1rem",
fontWeight: 400,
},
h5: {
- fontSize: '0.83rem',
+ fontSize: "0.83rem",
fontWeight: 400,
},
h6: {
- fontSize: '0.67rem',
+ fontSize: "0.67rem",
fontWeight: 500,
},
},
shadows: [
- 'none',
- 'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
- 'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
+ "none",
+ "rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px",
+ "rgba(100, 100, 111, 0.2) 0px 7px 29px 0px",
],
zIndex: {
divider: 1000,
diff --git a/packages/layout_editor/src/views/Markdown/Markdown.jsx b/packages/layout_editor/src/views/Markdown/Markdown.jsx
new file mode 100644
index 000000000..c54f1cd23
--- /dev/null
+++ b/packages/layout_editor/src/views/Markdown/Markdown.jsx
@@ -0,0 +1,29 @@
+import React, { useMemo } from "react";
+import PropTypes from "prop-types";
+import { Box } from "@embeddedchat/ui-elements";
+import { Markup, MarkupInteractionContext } from "@embeddedchat/markups";
+
+const Markdown = ({ body }) => {
+ const username = "spiral_memory";
+
+ const value = useMemo(() => {
+ const members = [];
+
+ return { members, username };
+ }, [username]);
+
+ return (
+
+
+
+
+
+ );
+};
+
+Markdown.propTypes = {
+ body: PropTypes.any,
+ isReaction: PropTypes.bool,
+};
+
+export default Markdown;
diff --git a/packages/layout_editor/src/views/Markdown/index.js b/packages/layout_editor/src/views/Markdown/index.js
new file mode 100644
index 000000000..45e90e969
--- /dev/null
+++ b/packages/layout_editor/src/views/Markdown/index.js
@@ -0,0 +1 @@
+export { default as Markdown } from './Markdown';
diff --git a/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js b/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js
new file mode 100644
index 000000000..576d30d2b
--- /dev/null
+++ b/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js
@@ -0,0 +1,200 @@
+import { css } from '@emotion/react';
+import { alpha } from '@embeddedchat/ui-elements';
+
+export const bubbleStyles = (customTheme) => {
+ const { theme, colors } = customTheme;
+
+ const styles = {
+ name: 'bubble',
+ messageParent: css`
+ display: flex;
+ gap: 0.25rem;
+ flex-direction: row;
+ align-items: flex-start;
+ padding: 0 2.25rem 0.25rem 2.25rem;
+ a {
+ color: ${colors.primaryForeground};
+ }
+ `,
+
+ messageBodyContainer: css`
+ display: flex;
+ flex: 1;
+ align-items: flex-start;
+ flex-direction: column;
+ `,
+
+ messageBody: css`
+ position: relative;
+ letter-spacing: 0rem;
+ font-size: 0.875rem;
+ font-weight: 400;
+ line-height: 1.25rem;
+ transition: opacity 0.3s linear;
+ word-break: break-word;
+ opacity: 1;
+ margin-top: 0.125rem;
+ margin-bottom: 0.125rem;
+ width: fit-content;
+ max-width: 80%;
+ padding: 0.5rem 0.75rem;
+ border-radius: ${theme.schemes.radius} ${theme.schemes.radius}
+ ${theme.schemes.radius} 0.2rem;
+ background: ${colors.primary};
+ color: ${colors.primaryForeground};
+ &:hover {
+ background: ${alpha(colors.primary, 0.8)};
+ }
+ `,
+
+ attachmentBody: css`
+ position: relative;
+ width: fit-content;
+ max-width: 80%;
+ border-radius: ${theme.schemes.radius} ${theme.schemes.radius}
+ ${theme.schemes.radius} 0.2rem;
+ `,
+
+ sequential: css`
+ border-radius: 0.2rem ${theme.schemes.radius} ${theme.schemes.radius}
+ 0.2rem;
+ `,
+ lastSequential: css`
+ border-radius: 0.2rem ${theme.schemes.radius} ${theme.schemes.radius};
+ `,
+
+ metricsContainer: css`
+ display: flex;
+ margin: 0.25rem;
+ `,
+
+ threadReplyButton: css`
+ background-color: ${colors.accent};
+ color: ${colors.accentForeground};
+ border-radius: 0.2rem;
+ `,
+
+ arcIcon: css`
+ transform: none;
+ `,
+
+ toolboxContainer: css`
+ display: none;
+ .ec-message-body:hover & {
+ display: flex;
+ position: absolute;
+ bottom: calc(100% - 20px);
+ left: calc(100% - 20px);
+ z-index: ${theme.zIndex.body + 1};
+ }
+ `,
+
+ videoAttachmentContainer: css`
+ border: 1px solid ${colors.border};
+ border-radius: inherit;
+ `,
+ imageAttachmentContainer: css`
+ border: 1px solid ${colors.border};
+ border-radius: inherit;
+ overflow: hidden;
+ `,
+ pinnedContainer: css`
+ max-width: 80%;
+ `,
+
+ quoteContainer: css`
+ background-color: ${colors.background};
+ color: ${colors.foreground};
+ flex: 1;
+ border-bottom-right-radius: inherit;
+ border-bottom-left-radius: inherit;
+ border: 2px solid ${colors.border};
+ margin: 0.2rem -0.75rem -0.5rem;
+ `,
+
+ textUserInfo: css`
+ align-self: flex-start;
+ `,
+
+ attachmentMetaContainer: css`
+ padding: 2.5% 2.5% 0;
+ `,
+
+ emojiPickerStyles: css`
+ position: absolute;
+ bottom: 100%;
+ left: calc(100% + 5px);
+ `,
+ };
+
+ return styles;
+};
+
+export const bubbleStylesMe = (customTheme) => {
+ const { theme, colors } = customTheme;
+
+ const styles = {
+ messageParentMe: css`
+ flex-direction: row-reverse;
+ `,
+
+ messageBodyContainerMe: css`
+ align-items: flex-end;
+ `,
+
+ messageBodyMe: css`
+ background: ${colors.secondary};
+ color: ${colors.secondaryForeground};
+ border-radius: ${theme.schemes.radius} ${theme.schemes.radius} 0.2rem
+ ${theme.schemes.radius};
+ &:hover {
+ background: ${alpha(colors.secondary, 0.8)};
+ }
+ `,
+
+ attachmentBodyMe: css`
+ border-radius: ${theme.schemes.radius} ${theme.schemes.radius} 0.2rem
+ ${theme.schemes.radius};
+ `,
+
+ lastSequentialMe: css`
+ border-radius: ${theme.schemes.radius} 0.2rem ${theme.schemes.radius}
+ ${theme.schemes.radius};
+ `,
+ sequentialMe: css`
+ border-radius: ${theme.schemes.radius} 0.2rem 0.2rem
+ ${theme.schemes.radius};
+ `,
+
+ metricsContainerMe: css`
+ flex-direction: row-reverse;
+ `,
+
+ arcIconMe: css`
+ transform: scaleX(-1);
+ `,
+
+ toolboxContainerMe: css`
+ .ec-message-body:hover & {
+ left: auto;
+ right: calc(100% - 20px);
+ }
+ `,
+
+ pinnedContainerMe: css`
+ border-inline-start: none;
+ border-inline-end: 3px solid ${colors.border};
+ `,
+
+ textUserInfoMe: css`
+ align-self: flex-end;
+ `,
+
+ emojiPickerStylesMe: css`
+ left: auto;
+ right: calc(100% + 5px);
+ `,
+ };
+
+ return styles;
+};
diff --git a/packages/layout_editor/src/views/Message/BubbleVariant/BubbleThreadBtn.js b/packages/layout_editor/src/views/Message/BubbleVariant/BubbleThreadBtn.js
new file mode 100644
index 000000000..fd966423e
--- /dev/null
+++ b/packages/layout_editor/src/views/Message/BubbleVariant/BubbleThreadBtn.js
@@ -0,0 +1,31 @@
+import React from 'react';
+import { format } from 'date-fns';
+import { Button, Icon, useTheme } from '@embeddedchat/ui-elements';
+
+const BubbleThreadBtn = ({ message, handleOpenThread, styles = {} }) => {
+ const { colors } = useTheme();
+
+ return (
+ <>
+
+
+ >
+ );
+};
+
+export default BubbleThreadBtn;
diff --git a/packages/layout_editor/src/views/Message/BubbleVariant/useBubbleStyles.js b/packages/layout_editor/src/views/Message/BubbleVariant/useBubbleStyles.js
new file mode 100644
index 000000000..6f3f81f45
--- /dev/null
+++ b/packages/layout_editor/src/views/Message/BubbleVariant/useBubbleStyles.js
@@ -0,0 +1,20 @@
+import { useTheme } from '@embeddedchat/ui-elements';
+import { bubbleStyles, bubbleStylesMe } from './Bubble.styles';
+
+const useBubbleStyles = (isMe = false) => {
+ const customTheme = useTheme();
+ const styles = bubbleStyles(customTheme);
+ const meStyles = bubbleStylesMe(customTheme);
+
+ const mergedStyles = {};
+
+ Object.keys(styles).forEach((key) => {
+ mergedStyles[key] = [styles[key], isMe && meStyles[`${key}Me`]].filter(
+ Boolean
+ );
+ });
+
+ return mergedStyles;
+};
+
+export default useBubbleStyles;
diff --git a/packages/layout_editor/src/views/Message/Message.jsx b/packages/layout_editor/src/views/Message/Message.jsx
new file mode 100644
index 000000000..c306e30c1
--- /dev/null
+++ b/packages/layout_editor/src/views/Message/Message.jsx
@@ -0,0 +1,88 @@
+import React from "react";
+import PropTypes from "prop-types";
+import { format } from "date-fns";
+import { Box } from "@embeddedchat/ui-elements";
+import { Markdown } from "../Markdown";
+import MessageHeader from "./MessageHeader";
+import { MessageBody } from "./MessageBody";
+import { MessageToolbox } from "./MessageToolbox";
+import { MessageDivider } from "./MessageDivider";
+import MessageAvatarContainer from "./MessageAvatarContainer";
+import MessageBodyContainer from "./MessageBodyContainer";
+import { useMessageStyles } from "./Message.styles";
+import useBubbleStyles from "./BubbleVariant/useBubbleStyles";
+
+const Message = ({
+ message,
+ sequential = false,
+ lastSequential = false,
+ newDay = false,
+ variantOverrides = "flat",
+}) => {
+ const isMe = message.u._id === "spiral_memory";
+ const styles = useMessageStyles();
+ const bubbleStyles = useBubbleStyles(isMe);
+ const shouldShowHeader = !sequential;
+ const variantStyles = variantOverrides === "bubble" ? bubbleStyles : {};
+
+ return (
+ <>
+
+
+
+
+ {shouldShowHeader && (
+
+ )}
+
+ {!message.t ? (
+ <>
+
+
+
+ {!message.t ? (
+
+ ) : (
+ <>>
+ )}
+
+ >
+ ) : null}
+
+
+ {newDay && (
+
+ {format(new Date(message.ts), "MMMM d, yyyy")}
+
+ )}
+ >
+ );
+};
+Message.propTypes = {
+ message: PropTypes.any,
+ sequential: PropTypes.bool,
+ newDay: PropTypes.bool,
+ type: PropTypes.oneOf(["thread", "default"]),
+ showAvatar: PropTypes.bool,
+};
+
+export default Message;
diff --git a/packages/layout_editor/src/views/Message/Message.styles.js b/packages/layout_editor/src/views/Message/Message.styles.js
new file mode 100644
index 000000000..f23b4de21
--- /dev/null
+++ b/packages/layout_editor/src/views/Message/Message.styles.js
@@ -0,0 +1,300 @@
+import { css } from '@emotion/react';
+import { lighten, darken, useTheme } from '@embeddedchat/ui-elements';
+
+export const useMessageStyles = () => {
+ const { mode, colors } = useTheme();
+
+ const main = css`
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ padding-top: 0.5rem;
+ padding-bottom: 0.25rem;
+ padding-left: 2.25rem;
+ padding-right: 2.25rem;
+ color: ${colors.foreground};
+
+ &:hover {
+ background-color: ${mode === 'light'
+ ? darken(colors.background, 0.03)
+ : lighten(colors.background, 1)};
+ }
+ `;
+ const messageEditing = css`
+ background-color: ${colors.secondary};
+ &:hover {
+ background-color: ${colors.secondary};
+ }
+ `;
+
+ const pendingMessageBody = css`
+ opacity: 0.4 !important;
+ white-space: pre-line;
+ `;
+
+ return { main, messageEditing, pendingMessageBody };
+};
+
+export const useMessageAvatarContainerStyles = () => {
+ const { colors } = useTheme();
+
+ const container = css`
+ margin: 3px;
+ width: 2.25em;
+ max-height: 2.25em;
+ display: flex;
+ justify-content: flex-end;
+ color: ${colors.primary};
+ `;
+
+ return { container };
+};
+
+export const MessageBodyStyles = {
+ messageBody: css`
+ position: relative;
+ letter-spacing: 0rem;
+ font-size: 0.875rem;
+ font-weight: 400;
+ line-height: 1.25rem;
+ flex-shrink: 1;
+ transition: opacity 0.3s linear;
+ word-break: break-word;
+ opacity: 1;
+ margin-top: 0.125rem;
+ margin-bottom: 0.125rem;
+ `,
+};
+
+export const useMessageDividerStyles = () => {
+ const { theme, colors } = useTheme();
+
+ const divider = css`
+ letter-spacing: 0rem;
+ font-size: 0.75rem;
+ font-weight: 700;
+ line-height: 1rem;
+ position: relative;
+ display: flex;
+ z-index: ${theme.zIndex.divider};
+ align-items: center;
+ margin-top: 0.5rem;
+ margin-bottom: 0.75rem;
+ padding-left: 1.25rem;
+ padding-right: 1.25rem;
+ `;
+
+ const dividerContent = css`
+ margin-top: 0.5rem;
+ margin-bottom: 0.5rem;
+ padding-left: 0.5rem;
+ padding-right: 0.5rem;
+ background-color: ${colors.secondary};
+ color: ${colors.secondaryForeground};
+ position: absolute;
+ left: 50%;
+ transform: translateX(-50%);
+ border-radius: ${theme.schemes.radius};
+ `;
+
+ const bar = css`
+ display: flex;
+ justify-content: flex-end;
+ align-items: center;
+ flex-grow: 1;
+ height: 1px;
+ background-color: ${colors.secondary};
+ `;
+
+ return { divider, bar, dividerContent };
+};
+
+export const useMessageHeaderStyles = () => {
+ const { theme, colors } = useTheme();
+
+ const header = css`
+ display: flex;
+ flex-direction: row;
+ flex-grow: 0;
+ flex-shrink: 1;
+ min-width: 1px;
+ margin-top: 0.125rem;
+ margin-bottom: 0.125rem;
+ gap: 0.125rem;
+ align-items: center;
+ `;
+
+ const name = css`
+ letter-spacing: 0rem;
+ font-size: 0.875rem;
+ font-weight: 700;
+ line-height: 1.25rem;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ flex-shrink: 1;
+ `;
+
+ const userName = css`
+ color: ${colors.accentForeground};
+ font-weight: 700;
+ letter-spacing: 0rem;
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ flex-shrink: 1;
+ `;
+
+ const userRole = css`
+ letter-spacing: 0rem;
+ font-size: 0.75rem;
+ padding: 0 0.25rem;
+ margin: 0 0.1rem;
+ border-radius: ${theme.schemes.radius};
+ font-weight: 700;
+ line-height: 1rem;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ background-color: ${colors.secondary};
+ `;
+
+ const userActions = css`
+ color: ${colors.accentForeground};
+ letter-spacing: 0rem;
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ flex-shrink: 1;
+ `;
+
+ const timestamp = css`
+ color: ${colors.accentForeground};
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ letter-spacing: 0rem;
+ font-size: 0.75rem;
+ font-weight: 400;
+ line-height: 1rem;
+ flex-shrink: 0;
+ margin-left: 0.25rem;
+ `;
+
+ return { header, name, userRole, userName, timestamp, userActions };
+};
+
+export const MessageMetricsStyles = {
+ metrics: css`
+ display: flex;
+ margin-left: -0.25rem;
+ margin-right: -0.25rem;
+ margin-top: 0.5rem;
+ `,
+
+ metricsItem: (isFirstMessage = false) => css`
+ letter-spacing: 0rem;
+ font-size: 0.625rem;
+ font-weight: 700;
+ line-height: 0.75rem;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin-left: ${isFirstMessage ? '0.5rem' : '0.25rem'};
+ `,
+
+ metricsItemLabel: css`
+ margin: 0.25rem;
+ margin-inline-start: 0.25rem;
+ white-space: nowrap;
+ `,
+};
+
+export const useMessageReactionsStyles = () => {
+ const { colors } = useTheme();
+ const container = css`
+ display: flex;
+ flex-flow: row wrap;
+ justify-content: flex-start;
+ `;
+
+ const reaction = css`
+ letter-spacing: 0rem;
+ font-size: 0.6rem;
+ display: inline-flex;
+ gap: 0.125rem;
+ align-items: center;
+ justify-content: center;
+ padding: 0.1rem;
+ margin: 0.125rem;
+ cursor: pointer;
+ img.joypixels {
+ height: 0.75em;
+ width: 0.75em;
+ }
+ p {
+ margin: 0;
+ }
+ border: 1px solid ${colors.border};
+ border-radius: 0.2rem;
+ `;
+
+ const reactionMine = css`
+ background: ${colors.secondary};
+ `;
+
+ return { container, reaction, reactionMine };
+};
+
+export const useMessageToolboxStyles = () => {
+ const { theme, colors } = useTheme();
+
+ const toolboxContainer = css`
+ display: none;
+ .ec-message:hover & {
+ display: flex;
+ position: absolute;
+ bottom: 100%;
+ z-index: ${theme.zIndex.body + 1};
+ right: 2rem;
+ }
+ `;
+
+ const toolbox = css`
+ display: flex;
+ margin-left: -0.25rem;
+ margin-right: -0.25rem;
+ margin-top: 0.125rem;
+ background-color: ${colors.background};
+ box-shadow: 0 0 2px ${colors.foreground};
+ gap: 0.25rem;
+ padding: 0.25rem;
+ border-radius: ${theme.schemes.radius};
+ `;
+
+ const emojiPickerStyles = css`
+ position: absolute;
+ bottom: 100%;
+ right: 1.5rem;
+ `;
+
+ return {
+ toolboxContainer,
+ toolbox,
+ emojiPickerStyles,
+ };
+};
+
+export const useMessageBodyContainerStyles = () => {
+ const bodyContainer = css`
+ margin-left: 5px;
+ position: relative;
+ width: 100%;
+ `;
+
+ return { bodyContainer };
+};
diff --git a/packages/layout_editor/src/views/Message/MessageAvatarContainer.jsx b/packages/layout_editor/src/views/Message/MessageAvatarContainer.jsx
new file mode 100644
index 000000000..15f7a36a3
--- /dev/null
+++ b/packages/layout_editor/src/views/Message/MessageAvatarContainer.jsx
@@ -0,0 +1,21 @@
+import React from "react";
+import { Box, Icon } from "@embeddedchat/ui-elements";
+import { useMessageAvatarContainerStyles } from "./Message.styles";
+
+const MessageAvatarContainer = ({ message, sequential }) => {
+ const styles = useMessageAvatarContainerStyles();
+
+ return (
+
+ {!sequential ? (
+
+ ) : null}
+
+ );
+};
+
+export default MessageAvatarContainer;
diff --git a/packages/layout_editor/src/views/Message/MessageBody.jsx b/packages/layout_editor/src/views/Message/MessageBody.jsx
new file mode 100644
index 000000000..7c7a5df62
--- /dev/null
+++ b/packages/layout_editor/src/views/Message/MessageBody.jsx
@@ -0,0 +1,30 @@
+import React from "react";
+import { Box } from "@embeddedchat/ui-elements";
+import { MessageBodyStyles as styles } from "./Message.styles";
+
+export const MessageBody = ({
+ children,
+ variantStyles = {},
+ isText = true,
+ sequential = false,
+ lastSequential = false,
+ ...props
+}) => {
+ const messageBodyStyles =
+ (isText ? variantStyles.messageBody : variantStyles.attachmentBody) ||
+ styles.messageBody;
+
+ return (
+
+ {children}
+
+ );
+};
diff --git a/packages/layout_editor/src/views/Message/MessageBodyContainer.jsx b/packages/layout_editor/src/views/Message/MessageBodyContainer.jsx
new file mode 100644
index 000000000..209c86712
--- /dev/null
+++ b/packages/layout_editor/src/views/Message/MessageBodyContainer.jsx
@@ -0,0 +1,19 @@
+import React from "react";
+import { Box } from "@embeddedchat/ui-elements";
+
+import { useMessageBodyContainerStyles } from "./Message.styles";
+
+const MessageBodyContainer = ({ children, variantStyles = {} }) => {
+ const styles = useMessageBodyContainerStyles();
+
+ return (
+
+ {children}
+
+ );
+};
+
+export default MessageBodyContainer;
diff --git a/packages/layout_editor/src/views/Message/MessageDivider.jsx b/packages/layout_editor/src/views/Message/MessageDivider.jsx
new file mode 100644
index 000000000..40182552e
--- /dev/null
+++ b/packages/layout_editor/src/views/Message/MessageDivider.jsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import {
+ Box,
+} from '@embeddedchat/ui-elements';
+
+import { useMessageDividerStyles } from './Message.styles';
+
+export const MessageDivider = ({
+ children,
+ ...props
+}) => {
+
+ const styles = useMessageDividerStyles();
+ return (
+
+ {children && (
+ <>
+
+
+ {children}
+
+ >
+ )}
+
+ );
+};
diff --git a/packages/layout_editor/src/views/Message/MessageHeader.jsx b/packages/layout_editor/src/views/Message/MessageHeader.jsx
new file mode 100644
index 000000000..a64f983de
--- /dev/null
+++ b/packages/layout_editor/src/views/Message/MessageHeader.jsx
@@ -0,0 +1,62 @@
+import React from "react";
+import PropTypes from "prop-types";
+import { format } from "date-fns";
+import {
+ Box,
+ Icon,
+ useTheme,
+ appendClassNames,
+} from "@embeddedchat/ui-elements";
+import { useMessageHeaderStyles } from "./Message.styles";
+import useDisplayNameColor from "../../hooks/useDisplayNameColor";
+
+const MessageHeader = ({ message, variantOverrides }) => {
+ const displayNameVariant = variantOverrides || "Normal";
+ const styles = useMessageHeaderStyles();
+ const { colors } = useTheme();
+ const getDisplayNameColor = useDisplayNameColor();
+
+ return (
+
+
+ @{message.u.username}
+
+
+
+ {format(new Date(message.ts), "h:mm a")}
+
+
+ {!message.t && (
+
+ {message.editedAt && (
+
+ )}
+
+ )}
+
+ );
+};
+
+export default MessageHeader;
+
+MessageHeader.propTypes = {
+ message: PropTypes.any,
+};
diff --git a/packages/layout_editor/src/views/Message/MessageToolbox.jsx b/packages/layout_editor/src/views/Message/MessageToolbox.jsx
new file mode 100644
index 000000000..a57a571f1
--- /dev/null
+++ b/packages/layout_editor/src/views/Message/MessageToolbox.jsx
@@ -0,0 +1,142 @@
+import React, { useMemo } from "react";
+import { Box, Menu } from "@embeddedchat/ui-elements";
+import { useMessageToolboxStyles } from "./Message.styles";
+import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
+
+export const MessageToolbox = ({
+ variantStyles = {},
+ optionConfig = {
+ surfaceItems: [
+ "reaction",
+ "reply",
+ "quote",
+ "star",
+ "pin",
+ "edit",
+ "delete",
+ "report",
+ ],
+
+ menuItems: [],
+ },
+
+ ...props
+}) => {
+ const styles = useMessageToolboxStyles();
+ const surfaceItems = optionConfig.surfaceItems;
+ const menuItems = optionConfig.menuItems;
+
+ const options = useMemo(
+ () => ({
+ reply: {
+ label: "Reply in thread",
+ id: "reply",
+ onClick: () => {},
+ iconName: "thread",
+ visible: true,
+ },
+ quote: {
+ label: "Quote",
+ id: "quote",
+ onClick: () => {},
+ iconName: "quote",
+ visible: true,
+ },
+ star: {
+ label: "Star",
+ id: "star",
+ onClick: () => {},
+ iconName: "star",
+ visible: true,
+ },
+ reaction: {
+ label: "Add reaction",
+ id: "reaction",
+ onClick: () => {},
+ iconName: "emoji",
+ visible: true,
+ },
+ pin: {
+ label: "Pin",
+ id: "pin",
+ onClick: () => {},
+ iconName: "pin",
+ visible: true,
+ },
+ edit: {
+ label: "Edit",
+ id: "edit",
+ onClick: () => {},
+ iconName: "edit",
+ visible: true,
+ },
+ delete: {
+ label: "Delete",
+ id: "delete",
+ onClick: () => {},
+ iconName: "trash",
+ visible: true,
+ type: "destructive",
+ },
+ report: {
+ label: "Report",
+ id: "report",
+ onClick: () => {},
+ iconName: "report",
+ visible: true,
+ type: "destructive",
+ },
+ }),
+ []
+ );
+
+ const menuOptions = menuItems
+ ?.map((item) => {
+ if (item in options && options[item].visible) {
+ return {
+ id: options[item].id,
+ action: options[item].onClick,
+ label: options[item].label,
+ icon: options[item].iconName,
+ };
+ }
+ return null;
+ })
+ .filter((option) => option !== null);
+
+ const surfaceOptions = surfaceItems
+ ?.map((item) => {
+ if (item in options && options[item].visible) {
+ return {
+ id: options[item].id,
+ onClick: options[item].onClick,
+ label: options[item].label,
+ iconName: options[item].iconName,
+ type: options[item].type,
+ };
+ }
+ return null;
+ })
+ .filter((option) => option !== null);
+
+ return (
+ <>
+
+
+ {surfaceOptions?.length > 0 && (
+
+ )}
+ {menuOptions?.length > 0 && (
+
+ )}
+
+
+ >
+ );
+};
diff --git a/packages/layout_editor/src/views/Message/index.js b/packages/layout_editor/src/views/Message/index.js
new file mode 100644
index 000000000..b0e7e95e8
--- /dev/null
+++ b/packages/layout_editor/src/views/Message/index.js
@@ -0,0 +1 @@
+export { default as Message } from './Message';
diff --git a/packages/layout_editor/src/views/MessageList/MessageList.jsx b/packages/layout_editor/src/views/MessageList/MessageList.jsx
index 26248259d..b70aedee7 100644
--- a/packages/layout_editor/src/views/MessageList/MessageList.jsx
+++ b/packages/layout_editor/src/views/MessageList/MessageList.jsx
@@ -1,19 +1,57 @@
import React from "react";
import PropTypes from "prop-types";
import { css } from "@emotion/react";
+import { isSameDay } from "date-fns";
import { Box, Icon } from "@embeddedchat/ui-elements";
+import Message from "../Message/Message";
+import isMessageLastSequential from "../../lib/isMessageLastSequential";
+import isMessageSequential from "../../lib/isMessageSequential";
+import messages from "../../data/messages.json";
-const MessageList = () => (
-
-
- Ready to chat? Login now to join the fun
-
-);
+const MessageList = () => {
+ const isMessageNewDay = (current, previous) =>
+ !previous || !isSameDay(new Date(current.ts), new Date(previous.ts));
+
+ return (
+ <>
+ {messages.length === 0 ? (
+
+
+ No messages
+
+ ) : (
+ <>
+ {messages.map((msg, index, arr) => {
+ const prev = arr[index + 1];
+ const next = arr[index - 1];
+
+ if (!msg) return null;
+ const newDay = isMessageNewDay(msg, prev);
+ const sequential = isMessageSequential(msg, prev, 300);
+ const lastSequential =
+ sequential && isMessageLastSequential(msg, next);
+
+ return (
+
+ );
+ })}
+ >
+ )}
+ >
+ );
+};
MessageList.propTypes = {
messages: PropTypes.arrayOf(PropTypes.shape),
From 5152e8cac86d8f16264e1404fbd314d6941ecce5 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 19:00:49 +0530
Subject: [PATCH 026/104] added emotion babel parser
---
packages/layout_editor/.eslintrc.cjs | 1 -
packages/layout_editor/package.json | 1 +
.../src/views/Message/Message.jsx | 4 ++--
packages/layout_editor/src/vite-env.d.ts | 1 +
packages/layout_editor/vite.config.ts | 19 +++++++++++++------
yarn.lock | 1 +
6 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/packages/layout_editor/.eslintrc.cjs b/packages/layout_editor/.eslintrc.cjs
index 92640d851..ab0963231 100644
--- a/packages/layout_editor/.eslintrc.cjs
+++ b/packages/layout_editor/.eslintrc.cjs
@@ -20,7 +20,6 @@ module.exports = {
{ allowConstantExport: true },
],
"react/prop-types": "off",
- "react/no-unknown-property": ["error", { ignore: ["css"] }],
"@typescript-eslint/no-unused-vars": ["warn"],
},
};
diff --git a/packages/layout_editor/package.json b/packages/layout_editor/package.json
index e163e8ff6..c67c27167 100644
--- a/packages/layout_editor/package.json
+++ b/packages/layout_editor/package.json
@@ -20,6 +20,7 @@
"react-dom": "^18.2.0"
},
"devDependencies": {
+ "@emotion/babel-plugin": "^11.11.0",
"@types/node": "^20.11.19",
"@types/react": "^18.2.55",
"@types/react-dom": "^18.2.19",
diff --git a/packages/layout_editor/src/views/Message/Message.jsx b/packages/layout_editor/src/views/Message/Message.jsx
index c306e30c1..aea8f6268 100644
--- a/packages/layout_editor/src/views/Message/Message.jsx
+++ b/packages/layout_editor/src/views/Message/Message.jsx
@@ -17,9 +17,9 @@ const Message = ({
sequential = false,
lastSequential = false,
newDay = false,
- variantOverrides = "flat",
+ variantOverrides = "default",
}) => {
- const isMe = message.u._id === "spiral_memory";
+ const isMe = message.u.username === "spiral_memory";
const styles = useMessageStyles();
const bubbleStyles = useBubbleStyles(isMe);
const shouldShowHeader = !sequential;
diff --git a/packages/layout_editor/src/vite-env.d.ts b/packages/layout_editor/src/vite-env.d.ts
index 11f02fe2a..683cbd2af 100644
--- a/packages/layout_editor/src/vite-env.d.ts
+++ b/packages/layout_editor/src/vite-env.d.ts
@@ -1 +1,2 @@
///
+///
diff --git a/packages/layout_editor/vite.config.ts b/packages/layout_editor/vite.config.ts
index 028287cd5..2e2219a6a 100644
--- a/packages/layout_editor/vite.config.ts
+++ b/packages/layout_editor/vite.config.ts
@@ -1,10 +1,17 @@
-import { defineConfig } from 'vite'
-import react from '@vitejs/plugin-react'
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
- plugins: [react()],
+ plugins: [
+ react({
+ jsxImportSource: "@emotion/react",
+ babel: {
+ plugins: ["@emotion/babel-plugin"],
+ },
+ }),
+ ],
define: {
- 'process.env': {}
- }
-})
+ "process.env": {},
+ },
+});
diff --git a/yarn.lock b/yarn.lock
index 8c81f2c8b..d573d2a32 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -20963,6 +20963,7 @@ __metadata:
"@dnd-kit/core": ^6.1.0
"@dnd-kit/sortable": ^8.0.0
"@embeddedchat/ui-elements": "workspace:^"
+ "@emotion/babel-plugin": ^11.11.0
"@types/node": ^20.11.19
"@types/react": ^18.2.55
"@types/react-dom": ^18.2.19
From b3253de762e9f6aa2f3e4d439e3f996876e5acc4 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 19:45:11 +0530
Subject: [PATCH 027/104] added special message style
---
.../src/views/Message/Message.jsx | 12 ++++----
.../src/views/Message/Message.styles.js | 29 ++++++++++---------
2 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/packages/layout_editor/src/views/Message/Message.jsx b/packages/layout_editor/src/views/Message/Message.jsx
index aea8f6268..b033e1fe8 100644
--- a/packages/layout_editor/src/views/Message/Message.jsx
+++ b/packages/layout_editor/src/views/Message/Message.jsx
@@ -29,7 +29,10 @@ const Message = ({
<>
@@ -56,11 +59,8 @@ const Message = ({
>
- {!message.t ? (
-
+ {!message.t && message._id === "62vhmKJGNoxgvLL7M" ? (
+
) : (
<>>
)}
diff --git a/packages/layout_editor/src/views/Message/Message.styles.js b/packages/layout_editor/src/views/Message/Message.styles.js
index f23b4de21..c5f01dd7e 100644
--- a/packages/layout_editor/src/views/Message/Message.styles.js
+++ b/packages/layout_editor/src/views/Message/Message.styles.js
@@ -1,5 +1,5 @@
-import { css } from '@emotion/react';
-import { lighten, darken, useTheme } from '@embeddedchat/ui-elements';
+import { css } from "@emotion/react";
+import { lighten, darken, useTheme } from "@embeddedchat/ui-elements";
export const useMessageStyles = () => {
const { mode, colors } = useTheme();
@@ -15,7 +15,7 @@ export const useMessageStyles = () => {
color: ${colors.foreground};
&:hover {
- background-color: ${mode === 'light'
+ background-color: ${mode === "light"
? darken(colors.background, 0.03)
: lighten(colors.background, 1)};
}
@@ -32,7 +32,13 @@ export const useMessageStyles = () => {
white-space: pre-line;
`;
- return { main, messageEditing, pendingMessageBody };
+ const specialMessage = css`
+ background-color: ${mode === "light"
+ ? darken(colors.background, 0.03)
+ : lighten(colors.background, 1)};
+ `;
+
+ return { main, messageEditing, pendingMessageBody, specialMessage };
};
export const useMessageAvatarContainerStyles = () => {
@@ -204,7 +210,7 @@ export const MessageMetricsStyles = {
display: flex;
justify-content: center;
align-items: center;
- margin-left: ${isFirstMessage ? '0.5rem' : '0.25rem'};
+ margin-left: ${isFirstMessage ? "0.5rem" : "0.25rem"};
`,
metricsItemLabel: css`
@@ -254,14 +260,11 @@ export const useMessageToolboxStyles = () => {
const { theme, colors } = useTheme();
const toolboxContainer = css`
- display: none;
- .ec-message:hover & {
- display: flex;
- position: absolute;
- bottom: 100%;
- z-index: ${theme.zIndex.body + 1};
- right: 2rem;
- }
+ display: flex;
+ position: absolute;
+ bottom: 100%;
+ z-index: ${theme.zIndex.body + 1};
+ right: 2rem;
`;
const toolbox = css`
From 4fa1ce0b34df291c422dccf4c6843e9c469b0853 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 23:10:30 +0530
Subject: [PATCH 028/104] added drag and drop in message toolbox
---
.../src/components/SortableMenu/Menu.jsx | 17 +-
.../components/SortableMenu/Menu.styles.js | 1 -
packages/layout_editor/src/data/messages.json | 4 +-
.../src/views/ChatHeader/ChatHeader.jsx | 4 +-
.../src/views/Message/MessageToolbox.jsx | 205 ++++++++++++++----
5 files changed, 178 insertions(+), 53 deletions(-)
diff --git a/packages/layout_editor/src/components/SortableMenu/Menu.jsx b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
index a6ab1d12c..d3dfd72af 100644
--- a/packages/layout_editor/src/components/SortableMenu/Menu.jsx
+++ b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
@@ -1,4 +1,4 @@
-import React from "react";
+import React, { useMemo } from "react";
import { css } from "@emotion/react";
import {
Box,
@@ -8,18 +8,26 @@ import {
} from "@embeddedchat/ui-elements";
import MenuItem from "./MenuItem";
import { getMenuStyles } from "./Menu.styles";
-import {
- SortableContext,
-} from "@dnd-kit/sortable";
+import { SortableContext } from "@dnd-kit/sortable";
const Menu = ({
options = [],
tooltip = { isToolTip: true, position: "bottom", text: "Options" },
+ from = "top",
size = "medium",
}) => {
const theme = useTheme();
const styles = getMenuStyles(theme);
+ const anchorStyle = useMemo(() => {
+ const positions = from.split(/\s+/);
+ const styleAnchor = {};
+ positions.forEach((pos) => {
+ styleAnchor[pos] = "100%";
+ });
+ return styleAnchor;
+ }, [from]);
+
return (
@@ -33,6 +41,7 @@ const Menu = ({
box-shadow: ${theme.theme.shadows[2]};
`,
]}
+ style={anchorStyle}
>
{options.map((option, idx) => (
diff --git a/packages/layout_editor/src/components/SortableMenu/Menu.styles.js b/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
index eb629e7e5..1a4dc0172 100644
--- a/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
+++ b/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
@@ -11,7 +11,6 @@ export const getMenuStyles = (customTheme) => {
container: css`
position: absolute;
- top: 100%;
right: 0;
display: flex;
flex-direction: column;
diff --git a/packages/layout_editor/src/data/messages.json b/packages/layout_editor/src/data/messages.json
index 26d5d2c60..2d64470fb 100644
--- a/packages/layout_editor/src/data/messages.json
+++ b/packages/layout_editor/src/data/messages.json
@@ -2,7 +2,7 @@
{
"_id": "wz5cNwELaK6MnZWkN",
"rid": "GENERAL",
- "msg": "That's great to hear! It's exciting that we can now customize the EmbeddedChat design using this layout editor. This will open up so many possibilities for tailoring the user experience exactly to our needs. Looking forward to seeing what we can create with it!",
+ "msg": "That's great to hear! It's exciting that we can now customize the EmbeddedChat design using this layout editor !",
"ts": "2024-07-14T09:22:39.277Z",
"u": {
"_id": "a9bAtEYzGoTHvtxws",
@@ -19,7 +19,7 @@
"value": [
{
"type": "PLAIN_TEXT",
- "value": "That's great to hear! It's exciting that we can now customize the EmbeddedChat design using this layout editor. This will open up so many possibilities for tailoring the user experience exactly to our needs. Looking forward to seeing what we can create with it!"
+ "value": "That's great to hear! It's exciting that we can now customize the EmbeddedChat design using this layout editor. This will open up so many possibilities for tailoring the user experience exactly to our needs !"
}
]
}
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
index 3018c0aba..a86ee89be 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -226,12 +226,12 @@ const ChatHeader = ({
general
-
Channel description
-
+
{
const styles = useMessageToolboxStyles();
- const surfaceItems = optionConfig.surfaceItems;
- const menuItems = optionConfig.menuItems;
+ const [surfaceItems, setSurfaceItems] = useState(optionConfig.surfaceItems);
+ const [menuItems, setMenuItems] = useState(optionConfig.menuItems);
+ const [activeSurfaceItem, setActiveSurfaceItem] = useState(null);
+ const [activeMenuItem, setActiveMenuItem] = useState(null);
+
+ const placeholderSurfaceItem = "placeholder-surface";
+ const placeholderMenuItem = "placeholder-menu";
+
+ const sensors = useSensors(
+ useSensor(PointerSensor),
+ useSensor(KeyboardSensor, {
+ coordinateGetter: sortableKeyboardCoordinates,
+ })
+ );
+
+ const handleDragStart = (event) => {
+ if (event.active.data.current?.type === "SurfaceOptions") {
+ setActiveSurfaceItem({
+ id: event.active.id,
+ iconName: event.active.data.current.icon,
+ label: event.active.data.current.label,
+ });
+ } else if (event.active.data.current?.type === "MenuOptions") {
+ setActiveMenuItem({
+ id: event.active.id,
+ icon: event.active.data.current.icon,
+ label: event.active.data.current.label,
+ });
+ }
+ };
+
+ const handleDragEnd = (event) => {
+ setActiveSurfaceItem(null);
+ setActiveMenuItem(null);
+ const { active, over } = event;
+
+ if (active.id !== over.id) {
+ if (
+ event.active.data.current?.type === "SurfaceOptions" &&
+ event.over.data.current?.type === "SurfaceOptions"
+ ) {
+ setSurfaceItems((items) => {
+ const oldIndex = items.indexOf(active.id);
+ const newIndex = items.indexOf(over.id);
+ return arrayMove(items, oldIndex, newIndex);
+ });
+ } else if (
+ event.active.data.current?.type === "MenuOptions" &&
+ event.over.data.current?.type === "MenuOptions"
+ ) {
+ setMenuItems((items) => {
+ const oldIndex = items.indexOf(active.id);
+ const newIndex = items.indexOf(over.id);
+ return arrayMove(items, oldIndex, newIndex);
+ });
+ } else if (
+ event.active.data.current?.type === "SurfaceOptions" &&
+ event.over.data.current?.type === "MenuOptions"
+ ) {
+ setSurfaceItems((items) => items.filter((item) => item !== active.id));
+ setMenuItems((items) => {
+ const newItems = [
+ ...items.filter((item) => item !== placeholderMenuItem),
+ active.id,
+ ];
+ return newItems;
+ });
+ } else if (
+ event.active.data.current?.type === "MenuOptions" &&
+ event.over.data.current?.type === "SurfaceOptions"
+ ) {
+ setMenuItems((items) => items.filter((item) => item !== active.id));
+ setSurfaceItems((items) => {
+ const newItems = [
+ ...items.filter((item) => item !== placeholderSurfaceItem),
+ active.id,
+ ];
+ return newItems;
+ });
+ }
+ }
+ };
const options = useMemo(
() => ({
@@ -90,52 +184,75 @@ export const MessageToolbox = ({
[]
);
- const menuOptions = menuItems
- ?.map((item) => {
- if (item in options && options[item].visible) {
- return {
- id: options[item].id,
- action: options[item].onClick,
- label: options[item].label,
- icon: options[item].iconName,
- };
- }
- return null;
- })
- .filter((option) => option !== null);
+ const menuOptions =
+ menuItems.length > 0
+ ? menuItems
+ ?.map((item) => {
+ if (item in options && options[item].visible) {
+ return {
+ id: options[item].id,
+ action: options[item].onClick,
+ label: options[item].label,
+ icon: options[item].iconName,
+ };
+ }
+ return null;
+ })
+ .filter((option) => option !== null)
+ : [{ id: placeholderMenuItem, label: "No items", icon: "plus" }];
- const surfaceOptions = surfaceItems
- ?.map((item) => {
- if (item in options && options[item].visible) {
- return {
- id: options[item].id,
- onClick: options[item].onClick,
- label: options[item].label,
- iconName: options[item].iconName,
- type: options[item].type,
- };
- }
- return null;
- })
- .filter((option) => option !== null);
+ const surfaceOptions =
+ surfaceItems.length > 0
+ ? surfaceItems
+ ?.map((item) => {
+ if (item in options && options[item].visible) {
+ return {
+ id: options[item].id,
+ onClick: options[item].onClick,
+ label: options[item].label,
+ iconName: options[item].iconName,
+ type: options[item].type,
+ };
+ }
+ return null;
+ })
+ .filter((option) => option !== null)
+ : [{ id: placeholderSurfaceItem, label: "No items", iconName: "plus" }];
return (
<>
-
- {surfaceOptions?.length > 0 && (
-
- )}
- {menuOptions?.length > 0 && (
-
+
+
+ {surfaceOptions?.length > 0 && (
+
+ )}
+ {menuOptions?.length > 0 && (
+
+ )}
+
+ {createPortal(
+
+ {activeSurfaceItem && (
+
+ )}
+ {activeMenuItem && }
+ ,
+ document.body
)}
-
+
>
);
From f529b9968cc25b165302975057a70e2f0d6e2e2c Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 14 Jul 2024 23:13:20 +0530
Subject: [PATCH 029/104] fixed mode
---
.../layout_editor/src/views/LayoutEditor.jsx | 31 ++++++++++---------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/packages/layout_editor/src/views/LayoutEditor.jsx b/packages/layout_editor/src/views/LayoutEditor.jsx
index 0807a3293..5df7bf41d 100644
--- a/packages/layout_editor/src/views/LayoutEditor.jsx
+++ b/packages/layout_editor/src/views/LayoutEditor.jsx
@@ -1,4 +1,4 @@
-import React from "react";
+import React, { useState } from "react";
import DefaultTheme from "../theme/DefaultTheme";
import { Box, ThemeProvider } from "@embeddedchat/ui-elements";
import { styles } from "./LayoutEditor.style";
@@ -6,18 +6,21 @@ import ChatLayout from "./ChatLayout/ChatLayout";
import ChatHeader from "./ChatHeader/ChatHeader";
import GlobalStyles from "./GlobalStyles";
-const LayoutEditor = () => (
-
-
-
-
-
-
-
-
-);
+const LayoutEditor = () => {
+ const [mode, setMode] = useState("light");
+ return (
+
+
+
+
+
+
+
+
+ );
+};
export default LayoutEditor;
From 80bede68648a43e3525404539efecd0ab4894c1f Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Mon, 15 Jul 2024 12:35:43 +0530
Subject: [PATCH 030/104] added sensor distance
---
.../src/components/SortableMenu/MenuItem.jsx | 1 +
.../components/SurfaceMenu/SurfaceItem.jsx | 3 +
.../src/views/ChatHeader/ChatHeader.jsx | 101 +++++++++++-------
.../ChatInput/ChatInputFormattingToolbar.jsx | 6 +-
.../src/views/Message/MessageToolbox.jsx | 6 +-
5 files changed, 77 insertions(+), 40 deletions(-)
diff --git a/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx b/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
index 90dc91d68..03b4ec4f5 100644
--- a/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
+++ b/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
@@ -28,6 +28,7 @@ const MenuItem = ({ id, icon, label, action, disabled }) => {
const style = {
transform: CSS.Transform.toString(transform),
transition,
+ cursor: "move",
};
if (isDragging) {
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
index 573bde6ab..694ee5a2d 100644
--- a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
@@ -49,6 +49,9 @@ const SurfaceItem = ({
size={size}
iconSize="small"
color={type}
+ style={{
+ cursor: "move",
+ }}
/>
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
index a86ee89be..483c84a20 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -123,40 +123,46 @@ const ChatHeader = ({
[]
);
- const menuOptions = menuItems.length > 0
- ? menuItems
- .map((item) => {
- if (item in options && options[item].visible) {
- return {
- id: options[item].id,
- action: options[item].onClick,
- label: options[item].label,
- icon: options[item].iconName,
- };
- }
- return null;
- })
- .filter((option) => option !== null)
- : [{ id: placeholderMenuItem, label: "No items", icon: "plus" }];
+ const menuOptions =
+ menuItems.length > 0
+ ? menuItems
+ .map((item) => {
+ if (item in options && options[item].visible) {
+ return {
+ id: options[item].id,
+ action: options[item].onClick,
+ label: options[item].label,
+ icon: options[item].iconName,
+ };
+ }
+ return null;
+ })
+ .filter((option) => option !== null)
+ : [{ id: placeholderMenuItem, label: "No items", icon: "plus" }];
- const surfaceOptions = surfaceItems.length > 0
- ? surfaceItems
- .map((item) => {
- if (item in options && options[item].visible) {
- return {
- id: options[item].id,
- onClick: options[item].onClick,
- label: options[item].label,
- iconName: options[item].iconName,
- };
- }
- return null;
- })
- .filter((option) => option !== null)
- : [{ id: placeholderSurfaceItem, label: "No items", iconName: "plus" }];
+ const surfaceOptions =
+ surfaceItems.length > 0
+ ? surfaceItems
+ .map((item) => {
+ if (item in options && options[item].visible) {
+ return {
+ id: options[item].id,
+ onClick: options[item].onClick,
+ label: options[item].label,
+ iconName: options[item].iconName,
+ };
+ }
+ return null;
+ })
+ .filter((option) => option !== null)
+ : [{ id: placeholderSurfaceItem, label: "No items", iconName: "plus" }];
const sensors = useSensors(
- useSensor(PointerSensor),
+ useSensor(PointerSensor, {
+ activationConstraint: {
+ distance: 1.5,
+ },
+ }),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
})
@@ -184,28 +190,46 @@ const ChatHeader = ({
const { active, over } = event;
if (active.id !== over.id) {
- if (event.active.data.current?.type === "SurfaceOptions" && event.over.data.current?.type === "SurfaceOptions") {
+ if (
+ event.active.data.current?.type === "SurfaceOptions" &&
+ event.over.data.current?.type === "SurfaceOptions"
+ ) {
setSurfaceItems((items) => {
const oldIndex = items.indexOf(active.id);
const newIndex = items.indexOf(over.id);
return arrayMove(items, oldIndex, newIndex);
});
- } else if (event.active.data.current?.type === "MenuOptions" && event.over.data.current?.type === "MenuOptions") {
+ } else if (
+ event.active.data.current?.type === "MenuOptions" &&
+ event.over.data.current?.type === "MenuOptions"
+ ) {
setMenuItems((items) => {
const oldIndex = items.indexOf(active.id);
const newIndex = items.indexOf(over.id);
return arrayMove(items, oldIndex, newIndex);
});
- } else if (event.active.data.current?.type === "SurfaceOptions" && event.over.data.current?.type === "MenuOptions") {
+ } else if (
+ event.active.data.current?.type === "SurfaceOptions" &&
+ event.over.data.current?.type === "MenuOptions"
+ ) {
setSurfaceItems((items) => items.filter((item) => item !== active.id));
setMenuItems((items) => {
- const newItems = [...items.filter((item) => item !== placeholderMenuItem), active.id];
+ const newItems = [
+ ...items.filter((item) => item !== placeholderMenuItem),
+ active.id,
+ ];
return newItems;
});
- } else if (event.active.data.current?.type === "MenuOptions" && event.over.data.current?.type === "SurfaceOptions") {
+ } else if (
+ event.active.data.current?.type === "MenuOptions" &&
+ event.over.data.current?.type === "SurfaceOptions"
+ ) {
setMenuItems((items) => items.filter((item) => item !== active.id));
setSurfaceItems((items) => {
- const newItems = [...items.filter((item) => item !== placeholderSurfaceItem), active.id];
+ const newItems = [
+ ...items.filter((item) => item !== placeholderSurfaceItem),
+ active.id,
+ ];
return newItems;
});
}
@@ -226,7 +250,8 @@ const ChatHeader = ({
general
-
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx b/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
index 0b2ef4bb6..5f203fdb0 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
+++ b/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
@@ -67,7 +67,11 @@ const ChatInputFormattingToolbar = ({
}, []);
const sensors = useSensors(
- useSensor(PointerSensor),
+ useSensor(PointerSensor, {
+ activationConstraint: {
+ distance: 1.5,
+ },
+ }),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
})
diff --git a/packages/layout_editor/src/views/Message/MessageToolbox.jsx b/packages/layout_editor/src/views/Message/MessageToolbox.jsx
index 2d08fc2f6..5f8293906 100644
--- a/packages/layout_editor/src/views/Message/MessageToolbox.jsx
+++ b/packages/layout_editor/src/views/Message/MessageToolbox.jsx
@@ -46,7 +46,11 @@ export const MessageToolbox = ({
const placeholderMenuItem = "placeholder-menu";
const sensors = useSensors(
- useSensor(PointerSensor),
+ useSensor(PointerSensor, {
+ activationConstraint: {
+ distance: 1.5,
+ },
+ }),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
})
From a45980583a7bd90ac4a632097c2869cef89642bc Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Mon, 15 Jul 2024 16:20:27 +0530
Subject: [PATCH 031/104] added formatter own sortable context
---
.../components/SurfaceMenu/SurfaceItem.jsx | 2 +-
.../src/views/ChatInput/ChatInput.jsx | 4 +-
.../src/views/ChatInput/ChatInput.styles.js | 130 +++++++++++-------
...attingToolbar.jsx => ChatInputToolbar.jsx} | 33 ++++-
.../src/views/ChatInput/Formatters.jsx | 80 +++++++++++
5 files changed, 187 insertions(+), 62 deletions(-)
rename packages/layout_editor/src/views/ChatInput/{ChatInputFormattingToolbar.jsx => ChatInputToolbar.jsx} (80%)
create mode 100644 packages/layout_editor/src/views/ChatInput/Formatters.jsx
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
index 694ee5a2d..89b318fa5 100644
--- a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
@@ -39,7 +39,7 @@ const SurfaceItem = ({
}
return (
-
+
{
const styles = useChatInputStyles();
@@ -55,7 +55,7 @@ const ChatInput = () => {
/>
-
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js b/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
index f9be35ba0..c03c61a22 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
+++ b/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
@@ -4,70 +4,94 @@ import { darken, useTheme } from "@embeddedchat/ui-elements";
export const useChatInputStyles = () => {
const { theme, colors } = useTheme();
- const inputWithFormattingBox = css`
- border: 1px solid ${colors.border};
- border-radius: ${theme.schemes.radius};
- margin: 0.5rem 2rem 1rem 2rem;
- &.focused {
- border: ${`1.5px solid ${colors.ring}`};
- }
- `;
+ const styles = {
+ inputWithFormattingBox: css`
+ border: 1px solid ${colors.border};
+ border-radius: ${theme.schemes.radius};
+ margin: 0.5rem 2rem 1rem 2rem;
+ &.focused {
+ border: ${`1.5px solid ${colors.ring}`};
+ }
+ `,
- const inputBox = css`
- display: flex;
- align-items: center;
- flex-direction: row;
- padding: 0.5rem;
- `;
+ inputBox: css`
+ display: flex;
+ align-items: center;
+ flex-direction: row;
+ padding: 0.5rem;
+ `,
- const textInput = css`
- flex: 1;
- word-wrap: break-word;
- white-space: pre-wrap;
- overflow: auto;
- overflow-x: hidden;
- resize: none;
- border: none;
- outline: none;
- font-size: 14px;
-
- &:focus {
+ textInput: css`
+ flex: 1;
+ word-wrap: break-word;
+ white-space: pre-wrap;
+ overflow: auto;
+ overflow-x: hidden;
+ resize: none;
border: none;
outline: none;
- }
+ font-size: 14px;
- &:disabled {
- cursor: not-allowed;
- }
+ &:focus {
+ border: none;
+ outline: none;
+ }
- &::placeholder {
- padding-left: 5px;
- }
- `;
+ &:disabled {
+ cursor: not-allowed;
+ }
- return {
- inputWithFormattingBox,
- inputBox,
- textInput,
+ &::placeholder {
+ padding-left: 5px;
+ }
+ `,
};
+
+ return styles;
};
-export const useChatInputFormattingToolbarStyles = () => {
+export const useChatInputToolbarStyles = () => {
const { theme, mode, colors } = useTheme();
- const chatFormat = css`
- bottom: 0;
- padding: 0.2rem;
- align-items: center;
- background-color: ${mode === "light"
- ? darken(colors.background, 0.03)
- : colors.secondary};
- display: flex;
- position: relative;
- flex-direction: row;
- gap: 0.375rem;
- border-radius: 0 0 ${theme.schemes.radius} ${theme.schemes.radius};
- `;
+ const styles = {
+ chatFormat: css`
+ bottom: 0;
+ padding: 0.2rem;
+ align-items: center;
+ background-color: ${mode === "light"
+ ? darken(colors.background, 0.03)
+ : colors.secondary};
+ display: flex;
+ position: relative;
+ flex-direction: row;
+ gap: 0.375rem;
+ border-radius: 0 0 ${theme.schemes.radius} ${theme.schemes.radius};
+ `,
+ };
+
+ return styles;
+};
+
+export const useFormatterStyles = () => {
+ const { theme, colors } = useTheme();
+ const styles = {
+ toolboxContainer: css`
+ display: flex;
+ position: absolute;
+ bottom: 100%;
+ left: auto;
+ z-index: ${theme.zIndex.body + 1};
+ `,
+
+ toolbox: css`
+ display: flex;
+ background-color: ${colors.background};
+ box-shadow: 0 0 2px ${colors.foreground};
+ gap: 0.25rem;
+ padding: 0.25rem;
+ border-radius: ${theme.schemes.radius};
+ `,
+ };
- return { chatFormat };
+ return styles;
};
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx b/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
similarity index 80%
rename from packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
rename to packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
index 5f203fdb0..8c18eb71e 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInputFormattingToolbar.jsx
+++ b/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
@@ -1,8 +1,9 @@
-import React, { useMemo, useState } from "react";
+import React, { useEffect, useMemo, useState } from "react";
import { Box } from "@embeddedchat/ui-elements";
-import { useChatInputFormattingToolbarStyles } from "./ChatInput.styles";
+import { useChatInputToolbarStyles } from "./ChatInput.styles";
import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
import SurfaceItem from "../../components/SurfaceMenu/SurfaceItem";
+import Formatters from "./Formatters";
import {
DndContext,
closestCenter,
@@ -15,15 +16,18 @@ import {
import { sortableKeyboardCoordinates, arrayMove } from "@dnd-kit/sortable";
import { createPortal } from "react-dom";
-const ChatInputFormattingToolbar = ({
+const ChatInputToolbar = ({
optionConfig = {
surfaceItems: ["emoji", "formatter", "audio", "video", "file"],
formatters: ["bold", "italic", "strike", "code", "multiline"],
},
}) => {
- const styles = useChatInputFormattingToolbarStyles();
+ const styles = useChatInputToolbarStyles();
const [surfaceItems, setSurfaceItems] = useState(optionConfig.surfaceItems);
+ const [formatters, setFormatters] = useState(optionConfig.formatters);
const [activeSurfaceItem, setActiveSurfaceItem] = useState(null);
+ const [formattersVisible, setFormattersVisible] = useState(false);
+
const placeholderSurfaceItem = "placeholder-surface";
const options = useMemo(() => {
@@ -59,7 +63,9 @@ const ChatInputFormattingToolbar = ({
formatter: {
label: "Formatter",
id: "formatter",
- onClick: () => {},
+ onClick: () => {
+ setFormattersVisible((prev) => !prev);
+ },
iconName: "format-text",
visible: true,
},
@@ -79,6 +85,9 @@ const ChatInputFormattingToolbar = ({
const handleDragStart = (event) => {
if (event.active.data.current?.type === "SurfaceOptions") {
+ if (options[event.active.id] !== undefined) {
+ setFormattersVisible(false);
+ }
setActiveSurfaceItem({
id: event.active.id,
iconName: event.active.data.current.icon,
@@ -101,6 +110,12 @@ const ChatInputFormattingToolbar = ({
const newIndex = items.indexOf(over.id);
return arrayMove(items, oldIndex, newIndex);
});
+
+ setFormatters((items) => {
+ const oldIndex = items.indexOf(active.id);
+ const newIndex = items.indexOf(over.id);
+ return arrayMove(items, oldIndex, newIndex);
+ });
}
}
};
@@ -145,8 +160,14 @@ const ChatInputFormattingToolbar = ({
,
document.body
)}
+
+ {formattersVisible &&
+ createPortal(
+ ,
+ document.getElementById("formatter")
+ )}
);
};
-export default ChatInputFormattingToolbar;
+export default ChatInputToolbar;
diff --git a/packages/layout_editor/src/views/ChatInput/Formatters.jsx b/packages/layout_editor/src/views/ChatInput/Formatters.jsx
new file mode 100644
index 000000000..dcd4ece7f
--- /dev/null
+++ b/packages/layout_editor/src/views/ChatInput/Formatters.jsx
@@ -0,0 +1,80 @@
+import React, { useMemo } from "react";
+import { Box } from "@embeddedchat/ui-elements";
+import { useFormatterStyles } from "./ChatInput.styles";
+import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
+
+const Formatters = ({ formatters }) => {
+ const styles = useFormatterStyles();
+
+ const options = useMemo(() => {
+ return {
+ bold: {
+ label: "Bold",
+ id: "bold",
+ onClick: () => {},
+ iconName: "bold",
+ visible: true,
+ },
+ italic: {
+ label: "Italic",
+ id: "italic",
+ onClick: () => {},
+ iconName: "italic",
+ visible: true,
+ },
+ strike: {
+ label: "Strike",
+ id: "strike",
+ onClick: () => {},
+ iconName: "strike",
+ visible: true,
+ },
+ code: {
+ label: "Code",
+ id: "code",
+ onClick: () => {},
+ iconName: "code",
+ visible: true,
+ },
+ multiline: {
+ label: "Multiline",
+ id: "multiline",
+ onClick: () => {},
+ iconName: "multiline",
+ visible: true,
+ },
+ };
+ }, []);
+
+ const surfaceOptions = useMemo(() => {
+ return (
+ formatters.length > 0 &&
+ formatters
+ .map((item) => {
+ if (item === "formatter") {
+ return options.formatter;
+ }
+ if (options[item] && options[item].visible) {
+ return {
+ id: options[item].id,
+ onClick: options[item].onClick,
+ label: options[item].label,
+ iconName: options[item].iconName,
+ };
+ }
+ return null;
+ })
+ .filter((option) => option !== null)
+ );
+ }, [formatters, options]);
+
+ return (
+
+
+ {surfaceOptions?.length > 0 && }
+
+
+ );
+};
+
+export default Formatters;
From 5690dc187af3043c2c72946cdf813d1f72d0f2ea Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Mon, 15 Jul 2024 18:22:46 +0530
Subject: [PATCH 032/104] added conditional check
---
packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx | 4 ++--
.../layout_editor/src/views/ChatInput/ChatInputToolbar.jsx | 4 ++--
packages/layout_editor/src/views/Message/MessageToolbox.jsx | 6 +++---
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
index 483c84a20..4e0a0026a 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -187,9 +187,9 @@ const ChatHeader = ({
const handleDragEnd = (event) => {
setActiveSurfaceItem(null);
setActiveMenuItem(null);
- const { active, over } = event;
+ const { active, over } = event || {};
- if (active.id !== over.id) {
+ if (active?.id !== over?.id) {
if (
event.active.data.current?.type === "SurfaceOptions" &&
event.over.data.current?.type === "SurfaceOptions"
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx b/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
index 8c18eb71e..db0f56ad0 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
+++ b/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
@@ -98,9 +98,9 @@ const ChatInputToolbar = ({
const handleDragEnd = (event) => {
setActiveSurfaceItem(null);
- const { active, over } = event;
+ const { active, over } = event || {};
- if (active.id !== over.id) {
+ if (active?.id !== over?.id) {
if (
event.active.data.current?.type === "SurfaceOptions" &&
event.over.data.current?.type === "SurfaceOptions"
diff --git a/packages/layout_editor/src/views/Message/MessageToolbox.jsx b/packages/layout_editor/src/views/Message/MessageToolbox.jsx
index 5f8293906..cf059a8ca 100644
--- a/packages/layout_editor/src/views/Message/MessageToolbox.jsx
+++ b/packages/layout_editor/src/views/Message/MessageToolbox.jsx
@@ -48,7 +48,7 @@ export const MessageToolbox = ({
const sensors = useSensors(
useSensor(PointerSensor, {
activationConstraint: {
- distance: 1.5,
+ distance: 1.5,
},
}),
useSensor(KeyboardSensor, {
@@ -75,9 +75,9 @@ export const MessageToolbox = ({
const handleDragEnd = (event) => {
setActiveSurfaceItem(null);
setActiveMenuItem(null);
- const { active, over } = event;
+ const { active, over } = event || {};
- if (active.id !== over.id) {
+ if (active?.id !== over?.id) {
if (
event.active.data.current?.type === "SurfaceOptions" &&
event.over.data.current?.type === "SurfaceOptions"
From 29435792c20551a53abf7aecd67573c43412f0a2 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Mon, 15 Jul 2024 19:02:07 +0530
Subject: [PATCH 033/104] added cross icon for option deletion
---
.../src/components/SortableMenu/Menu.jsx | 2 +-
.../components/SortableMenu/Menu.styles.js | 23 ++++++++++-
.../src/components/SortableMenu/MenuItem.jsx | 18 +++++++--
.../components/SurfaceMenu/SurfaceItem.jsx | 40 ++++++++++++-------
.../SurfaceMenu/SurfaceMenu.styles.js | 25 ++++++++++++
5 files changed, 88 insertions(+), 20 deletions(-)
diff --git a/packages/layout_editor/src/components/SortableMenu/Menu.jsx b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
index d3dfd72af..d0a33127f 100644
--- a/packages/layout_editor/src/components/SortableMenu/Menu.jsx
+++ b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
@@ -23,7 +23,7 @@ const Menu = ({
const positions = from.split(/\s+/);
const styleAnchor = {};
positions.forEach((pos) => {
- styleAnchor[pos] = "100%";
+ styleAnchor[pos] = "120%";
});
return styleAnchor;
}, [from]);
diff --git a/packages/layout_editor/src/components/SortableMenu/Menu.styles.js b/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
index 1a4dc0172..83576a74f 100644
--- a/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
+++ b/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
@@ -36,7 +36,7 @@ export const getMenuItemStyles = (customTheme) => {
display: flex;
flex-direction: row;
align-items: center;
- justify-content: flex-start;
+ justify-content: space-between;
padding: 0.25em 0.75em;
white-space: nowrap;
gap: 0.2rem;
@@ -48,11 +48,32 @@ export const getMenuItemStyles = (customTheme) => {
cursor: pointer;
}
`,
+
+ mainItems: css`
+ display: flex;
+ align-items: center;
+ gap: 0.2rem;
+ `,
+
disabled: css`
cursor: not-allowed !important;
color: ${colors.mutedForeground};
`,
+ icon: css`
+ visibility: hidden;
+ &:hover {
+ fill: ${colors.destructive};
+ }
+ `,
+
+ showIcon: css`
+ &:hover .crossIcon {
+ visibility: visible;
+ cursor: pointer;
+ }
+ `,
+
dragOverlay: css`
padding: 0.5rem 0.75em;
border: 1px solid ${colors.border};
diff --git a/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx b/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
index 03b4ec4f5..6d687c485 100644
--- a/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
+++ b/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
@@ -28,7 +28,7 @@ const MenuItem = ({ id, icon, label, action, disabled }) => {
const style = {
transform: CSS.Transform.toString(transform),
transition,
- cursor: "move",
+ cursor: "grab",
};
if (isDragging) {
@@ -41,11 +41,21 @@ const MenuItem = ({ id, icon, label, action, disabled }) => {
style={style}
{...attributes}
{...listeners}
- css={[styles.item, disabled && styles.disabled]}
+ css={[styles.item, styles.showIcon, disabled && styles.disabled]}
onClick={!disabled && action}
>
-
- {label}
+
+
+ {label}
+
+
+
);
};
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
index 89b318fa5..876b192ce 100644
--- a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
@@ -4,6 +4,7 @@ import {
ActionButton,
Box,
useTheme,
+ Icon,
} from "@embeddedchat/ui-elements";
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
@@ -40,20 +41,31 @@ const SurfaceItem = ({
return (
-
-
-
+
+
+
+
+
+
+
+
);
};
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.styles.js b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.styles.js
index 87984171e..166e24603 100644
--- a/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.styles.js
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.styles.js
@@ -10,6 +10,31 @@ export const getSurfaceItemStyles = (customTheme) => {
border: 1px solid ${colors.border};
border-radius: ${theme.schemes.radius};
`,
+
+ itemContainer: css`
+ &:hover .crossIcon {
+ visibility: visible;
+ cursor: pointer;
+ width: 14px;
+ height: 14px;
+ border-radius: 50%;
+ background: ${colors.secondary};
+ border: 1px solid ${colors.border};
+ }
+ `,
+
+ iconBox: css`
+ position: absolute;
+ bottom: 60%;
+ right: 0;
+ visibility: hidden;
+ `,
+
+ icon: css`
+ &:hover {
+ fill: ${colors.destructive};
+ }
+ `,
};
return styles;
From 9dfbc2384f5e77b35c95fcf8caaab7b60eb96e29 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Mon, 15 Jul 2024 23:06:03 +0530
Subject: [PATCH 034/104] enabled deletion of otpions
---
.../src/components/SortableMenu/Menu.jsx | 3 +-
.../src/components/SortableMenu/MenuItem.jsx | 26 ++++++++++------
.../components/SurfaceMenu/SurfaceItem.jsx | 31 +++++++++++++------
.../components/SurfaceMenu/SurfaceMenu.jsx | 9 ++----
.../src/views/ChatHeader/ChatHeader.jsx | 19 ++++++++++--
.../src/views/ChatInput/ChatInputToolbar.jsx | 16 ++++++++--
.../src/views/ChatInput/Formatters.jsx | 6 ++--
.../src/views/Message/MessageToolbox.jsx | 15 ++++++++-
8 files changed, 91 insertions(+), 34 deletions(-)
diff --git a/packages/layout_editor/src/components/SortableMenu/Menu.jsx b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
index d0a33127f..692cd7e6c 100644
--- a/packages/layout_editor/src/components/SortableMenu/Menu.jsx
+++ b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
@@ -15,6 +15,7 @@ const Menu = ({
tooltip = { isToolTip: true, position: "bottom", text: "Options" },
from = "top",
size = "medium",
+ ...props
}) => {
const theme = useTheme();
const styles = getMenuStyles(theme);
@@ -45,7 +46,7 @@ const Menu = ({
>
{options.map((option, idx) => (
-
+
))}
diff --git a/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx b/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
index 6d687c485..0c970b261 100644
--- a/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
+++ b/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
@@ -5,7 +5,7 @@ import { getMenuItemStyles } from "./Menu.styles";
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
-const MenuItem = ({ id, icon, label, action, disabled }) => {
+const MenuItem = ({ id, icon, label, action, disabled, onRemove }) => {
const theme = useTheme();
const styles = getMenuItemStyles(theme);
@@ -35,6 +35,10 @@ const MenuItem = ({ id, icon, label, action, disabled }) => {
return ;
}
+ const handleRemoveItem = (id) => {
+ if (id !== "placeholder-menu") onRemove(id);
+ };
+
return (
{
{label}
-
-
+ {id !== "placeholder-menu" && (
+ {
+ handleRemoveItem(id);
+ }}
+ />
+ )}
);
};
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
index 876b192ce..01148304d 100644
--- a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
@@ -15,6 +15,7 @@ const SurfaceItem = ({
label,
iconName,
onClick,
+ onRemove,
type,
position = "bottom",
size,
@@ -39,6 +40,10 @@ const SurfaceItem = ({
return ;
}
+ const handleRemoveItem = (id) => {
+ if (id !== "placeholder-surface") onRemove(id);
+ };
+
return (
@@ -55,15 +60,23 @@ const SurfaceItem = ({
cursor: "grab",
}}
/>
-
-
-
+
+ {id !== "placeholder-surface" && (
+ {
+ handleRemoveItem(id);
+ }}
+ >
+
+
+ )}
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
index f42799553..aa9ba8a1c 100644
--- a/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
@@ -2,16 +2,11 @@ import React from "react";
import SurfaceItem from "./SurfaceItem";
import { SortableContext } from "@dnd-kit/sortable";
-const SurfaceMenu = ({ options, tooltipPosition, size = "medium" }) => {
+const SurfaceMenu = ({ options, ...props }) => {
return (
{options?.map((item, idx) => (
-
+
))}
);
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
index 4e0a0026a..eaa27317e 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -160,7 +160,7 @@ const ChatHeader = ({
const sensors = useSensors(
useSensor(PointerSensor, {
activationConstraint: {
- distance: 1.5,
+ distance: 1.5,
},
}),
useSensor(KeyboardSensor, {
@@ -236,6 +236,14 @@ const ChatHeader = ({
}
};
+ const removeSurfaceItem = (idToRemove) => {
+ setSurfaceItems((items) => items.filter((item) => item !== idToRemove));
+ };
+
+ const removeMenuItem = (idToRemove) => {
+ setMenuItems((items) => items.filter((item) => item !== idToRemove));
+ };
+
return (
@@ -267,9 +275,14 @@ const ChatHeader = ({
>
{surfaceOptions.length > 0 && (
-
+
+ )}
+ {menuOptions.length > 0 && (
+
)}
- {menuOptions.length > 0 && }
{createPortal(
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx b/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
index db0f56ad0..5ecb17c17 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
+++ b/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
@@ -141,6 +141,14 @@ const ChatInputToolbar = ({
: [{ id: placeholderSurfaceItem, label: "No items", iconName: "plus" }];
}, [surfaceItems, options]);
+ const removeSurfaceItem = (idToRemove) => {
+ setSurfaceItems((items) => items.filter((item) => item !== idToRemove));
+ };
+
+ const removeFormatters = (idToRemove) => {
+ setFormatters((items) => items.filter((item) => item !== idToRemove));
+ };
+
return (
{surfaceOptions.length > 0 && (
-
+
)}
@@ -163,7 +175,7 @@ const ChatInputToolbar = ({
{formattersVisible &&
createPortal(
- ,
+ ,
document.getElementById("formatter")
)}
diff --git a/packages/layout_editor/src/views/ChatInput/Formatters.jsx b/packages/layout_editor/src/views/ChatInput/Formatters.jsx
index dcd4ece7f..c0ebe271a 100644
--- a/packages/layout_editor/src/views/ChatInput/Formatters.jsx
+++ b/packages/layout_editor/src/views/ChatInput/Formatters.jsx
@@ -3,7 +3,7 @@ import { Box } from "@embeddedchat/ui-elements";
import { useFormatterStyles } from "./ChatInput.styles";
import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
-const Formatters = ({ formatters }) => {
+const Formatters = ({ formatters, ...props }) => {
const styles = useFormatterStyles();
const options = useMemo(() => {
@@ -71,7 +71,9 @@ const Formatters = ({ formatters }) => {
return (
- {surfaceOptions?.length > 0 && }
+ {surfaceOptions?.length > 0 && (
+
+ )}
);
diff --git a/packages/layout_editor/src/views/Message/MessageToolbox.jsx b/packages/layout_editor/src/views/Message/MessageToolbox.jsx
index cf059a8ca..823987653 100644
--- a/packages/layout_editor/src/views/Message/MessageToolbox.jsx
+++ b/packages/layout_editor/src/views/Message/MessageToolbox.jsx
@@ -223,6 +223,14 @@ export const MessageToolbox = ({
.filter((option) => option !== null)
: [{ id: placeholderSurfaceItem, label: "No items", iconName: "plus" }];
+ const removeSurfaceItem = (idToRemove) => {
+ setSurfaceItems((items) => items.filter((item) => item !== idToRemove));
+ };
+
+ const removeMenuItem = (idToRemove) => {
+ setMenuItems((items) => items.filter((item) => item !== idToRemove));
+ };
+
return (
<>
@@ -234,7 +242,11 @@ export const MessageToolbox = ({
>
{surfaceOptions?.length > 0 && (
-
+
)}
{menuOptions?.length > 0 && (
)}
From 8a009df7c06c32962ecc37c93cf296cf36232317 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Mon, 15 Jul 2024 23:23:50 +0530
Subject: [PATCH 035/104] fixed removal of noItems
---
packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx | 6 ++++--
packages/layout_editor/src/views/Message/MessageToolbox.jsx | 6 ++++--
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
index eaa27317e..0bff084ae 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -210,7 +210,8 @@ const ChatHeader = ({
});
} else if (
event.active.data.current?.type === "SurfaceOptions" &&
- event.over.data.current?.type === "MenuOptions"
+ event.over.data.current?.type === "MenuOptions" &&
+ active.id !== placeholderSurfaceItem
) {
setSurfaceItems((items) => items.filter((item) => item !== active.id));
setMenuItems((items) => {
@@ -222,7 +223,8 @@ const ChatHeader = ({
});
} else if (
event.active.data.current?.type === "MenuOptions" &&
- event.over.data.current?.type === "SurfaceOptions"
+ event.over.data.current?.type === "SurfaceOptions" &&
+ active.id !== placeholderMenuItem
) {
setMenuItems((items) => items.filter((item) => item !== active.id));
setSurfaceItems((items) => {
diff --git a/packages/layout_editor/src/views/Message/MessageToolbox.jsx b/packages/layout_editor/src/views/Message/MessageToolbox.jsx
index 823987653..4bbfcf525 100644
--- a/packages/layout_editor/src/views/Message/MessageToolbox.jsx
+++ b/packages/layout_editor/src/views/Message/MessageToolbox.jsx
@@ -98,7 +98,8 @@ export const MessageToolbox = ({
});
} else if (
event.active.data.current?.type === "SurfaceOptions" &&
- event.over.data.current?.type === "MenuOptions"
+ event.over.data.current?.type === "MenuOptions" &&
+ active.id !== placeholderSurfaceItem
) {
setSurfaceItems((items) => items.filter((item) => item !== active.id));
setMenuItems((items) => {
@@ -110,7 +111,8 @@ export const MessageToolbox = ({
});
} else if (
event.active.data.current?.type === "MenuOptions" &&
- event.over.data.current?.type === "SurfaceOptions"
+ event.over.data.current?.type === "SurfaceOptions" &&
+ active.id !== placeholderMenuItem
) {
setMenuItems((items) => items.filter((item) => item !== active.id));
setSurfaceItems((items) => {
From e81fccc4b1bc3989242c8afa44dde25b474a309e Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Mon, 15 Jul 2024 23:30:03 +0530
Subject: [PATCH 036/104] fixed minor issues
---
.../src/components/SurfaceMenu/SurfaceItem.jsx | 4 ++--
.../src/views/ChatInput/Formatters.jsx | 16 +++++++++-------
2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
index 01148304d..1ac42812b 100644
--- a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
@@ -17,7 +17,7 @@ const SurfaceItem = ({
onClick,
onRemove,
type,
- position = "bottom",
+ tooltipPosition = "bottom",
size,
}) => {
const { attributes, listeners, setNodeRef, transform, isDragging } =
@@ -47,7 +47,7 @@ const SurfaceItem = ({
return (
-
+
{
}, [formatters, options]);
return (
-
-
- {surfaceOptions?.length > 0 && (
-
- )}
-
-
+ <>
+ {surfaceOptions?.length > 0 && (
+
+
+
+
+
+ )}
+ >
);
};
From 70f0912d3a8e1015200bc7111516fa164ec655ac Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Tue, 16 Jul 2024 00:05:28 +0530
Subject: [PATCH 037/104] setup demo sidebar
---
.../src/views/ChatLayout/ChatLayout.jsx | 37 +++++++------
.../src/views/DemoSidebar/DemoSidebar.jsx | 55 +++++++++++++++++++
.../views/DemoSidebar/DemoSidebar.styles.js | 31 +++++++++++
3 files changed, 106 insertions(+), 17 deletions(-)
create mode 100644 packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
create mode 100644 packages/layout_editor/src/views/DemoSidebar/DemoSidebar.styles.js
diff --git a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
index 6e37d26e5..3552b0ab8 100644
--- a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
+++ b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
@@ -1,22 +1,25 @@
-import React from 'react';
-import { Box } from '@embeddedchat/ui-elements';
-import ChatBody from '../Chatbody/ChatBody';
-import ChatInput from '../ChatInput/ChatInput';
-import styles from './ChatLayout.styles';
+import React from "react";
+import { Box } from "@embeddedchat/ui-elements";
+import ChatBody from "../Chatbody/ChatBody";
+import ChatInput from "../ChatInput/ChatInput";
+import styles from "./ChatLayout.styles";
+import DemoSidebar from "../DemoSidebar/DemoSidebar";
-const ChatLayout = () => (
-
-
-
-
-
-
+const ChatLayout = () => {
+ const members = [];
+ return (
+
+
+
+
+
+
-
- {/* {showMembers && }
- )} */}
+
+
+
-
-);
+ );
+};
export default ChatLayout;
diff --git a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
new file mode 100644
index 000000000..1582833d8
--- /dev/null
+++ b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
@@ -0,0 +1,55 @@
+import React from "react";
+import PropTypes from "prop-types";
+import { Box, Avatar, Icon, Sidebar, Popup } from "@embeddedchat/ui-elements";
+import { css } from "@emotion/react";
+import { useDemoSidebarStyles } from "./DemoSidebar.styles";
+
+const DemoSidebar = ({ members, viewType = "Sidebar" }) => {
+ const ViewComponent = viewType === "Popup" ? Popup : Sidebar;
+ const styles = useDemoSidebarStyles();
+ return (
+
+ {members.map((member, index) => (
+
+
+
+ {member.userStatus && (
+
+ )}
+ {member.username}
+
+
+ ))}
+
+ );
+};
+
+DemoSidebar.propTypes = {
+ members: PropTypes.arrayOf(
+ PropTypes.shape({
+ avatarUrl: PropTypes.string,
+ userStatus: PropTypes.string,
+ username: PropTypes.string.isRequired,
+ })
+ ).isRequired,
+ viewType: PropTypes.oneOf(["Sidebar", "Popup"]),
+};
+
+export default DemoSidebar;
diff --git a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.styles.js b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.styles.js
new file mode 100644
index 000000000..3ac6aaf1b
--- /dev/null
+++ b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.styles.js
@@ -0,0 +1,31 @@
+import { css } from "@emotion/react";
+
+export const useDemoSidebarStyles = () => {
+ const styles = {
+ container: css`
+ display: flex;
+ flex-direction: column;
+ overflow: auto;
+ width: 100%;
+ align-items: center;
+ justify-content: center;
+ padding: 0 1rem 1rem;
+ `,
+
+ itemContainer: css`
+ width: 100%;
+ padding-bottom: 8px;
+ padding-top: 8px;
+ display: flex;
+ align-items: center;
+ `,
+
+ icon: css`
+ padding: 0.125em;
+ margin-right: 0.5rem;
+ align-self: center;
+ `,
+ };
+
+ return styles;
+};
From 7b8f1a858d3664d9d09a1a2e35112464c99549c5 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Tue, 16 Jul 2024 00:23:18 +0530
Subject: [PATCH 038/104] added dummy members
---
packages/layout_editor/src/data/members.json | 16 ++++++
.../src/views/ChatLayout/ChatLayout.jsx | 2 +-
.../src/views/DemoSidebar/DemoSidebar.jsx | 50 ++++++++++---------
3 files changed, 43 insertions(+), 25 deletions(-)
create mode 100644 packages/layout_editor/src/data/members.json
diff --git a/packages/layout_editor/src/data/members.json b/packages/layout_editor/src/data/members.json
new file mode 100644
index 000000000..a9e6c3570
--- /dev/null
+++ b/packages/layout_editor/src/data/members.json
@@ -0,0 +1,16 @@
+[
+ {
+ "_id": "a9bAtEYzGoTHvtxws",
+ "status": "away",
+ "_updatedAt": "2024-07-15T18:47:50.807Z",
+ "name": "Sidharth Mohanty",
+ "username": "sidmohanty11"
+ },
+ {
+ "_id": "c9bAtEYzGoTHvtxws",
+ "status": "online",
+ "_updatedAt": "2024-07-15T18:47:50.807Z",
+ "name": "Zishan Ahmad",
+ "username": "spiral_memory"
+ }
+]
\ No newline at end of file
diff --git a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
index 3552b0ab8..cfe675bcf 100644
--- a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
+++ b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
@@ -4,9 +4,9 @@ import ChatBody from "../Chatbody/ChatBody";
import ChatInput from "../ChatInput/ChatInput";
import styles from "./ChatLayout.styles";
import DemoSidebar from "../DemoSidebar/DemoSidebar";
+import members from "../../data/members.json";
const ChatLayout = () => {
- const members = [];
return (
diff --git a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
index 1582833d8..054a31a6c 100644
--- a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
+++ b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
@@ -1,6 +1,6 @@
import React from "react";
import PropTypes from "prop-types";
-import { Box, Avatar, Icon, Sidebar, Popup } from "@embeddedchat/ui-elements";
+import { Box, Icon, Sidebar, Popup } from "@embeddedchat/ui-elements";
import { css } from "@emotion/react";
import { useDemoSidebarStyles } from "./DemoSidebar.styles";
@@ -13,30 +13,32 @@ const DemoSidebar = ({ members, viewType = "Sidebar" }) => {
iconName="members"
{...(viewType === "Popup" ? { isPopupHeader: true } : {})}
>
- {members.map((member, index) => (
-
-
-
- {member.userStatus && (
-
- )}
- {member.username}
+
+ {members.map((member, index) => (
+
+
+
+ {member.status && (
+
+ )}
+ {member.username}
+
-
- ))}
+ ))}
+
);
};
From c1ef5164576fc653584ad3fb284cdec2b81f6854 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Tue, 16 Jul 2024 14:21:27 +0530
Subject: [PATCH 039/104] changed use to get for stylings
---
.../src/views/ChatHeader/ChatHeader.jsx | 3 +-
.../src/views/ChatHeader/ChatHeader.styles.js | 24 +-
.../src/views/ChatInput/ChatInput.jsx | 11 +-
.../src/views/ChatInput/ChatInput.styles.js | 13 +-
.../src/views/ChatInput/ChatInputToolbar.jsx | 8 +-
.../src/views/ChatInput/Formatters.jsx | 6 +-
.../src/views/ChatLayout/ChatLayout.jsx | 3 +-
.../src/views/ChatLayout/ChatLayout.styles.js | 32 +-
.../src/views/Chatbody/ChatBody.jsx | 12 +-
.../src/views/Chatbody/ChatBody.styles.js | 32 +-
.../src/views/DemoSidebar/DemoSidebar.jsx | 4 +-
.../views/DemoSidebar/DemoSidebar.styles.js | 2 +-
.../layout_editor/src/views/GlobalStyles.jsx | 11 +-
.../Message/BubbleVariant/Bubble.styles.js | 10 +-
.../Message/BubbleVariant/useBubbleStyles.js | 10 +-
.../src/views/Message/Message.jsx | 6 +-
.../src/views/Message/Message.styles.js | 503 +++++++++---------
.../views/Message/MessageAvatarContainer.jsx | 6 +-
.../src/views/Message/MessageBody.jsx | 3 +-
.../views/Message/MessageBodyContainer.jsx | 4 +-
.../src/views/Message/MessageDivider.jsx | 18 +-
.../src/views/Message/MessageHeader.jsx | 4 +-
.../src/views/Message/MessageToolbox.jsx | 6 +-
23 files changed, 360 insertions(+), 371 deletions(-)
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
index 0bff084ae..007024aa5 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -30,8 +30,7 @@ const ChatHeader = ({
menuItems: ["files", "members", "search", "rInfo", "logout"],
},
}) => {
- const theme = useTheme();
- const styles = getChatHeaderStyles(theme);
+ const styles = getChatHeaderStyles(useTheme());
const [surfaceItems, setSurfaceItems] = useState(optionConfig.surfaceItems);
const [menuItems, setMenuItems] = useState(optionConfig.menuItems);
const [activeSurfaceItem, setActiveSurfaceItem] = useState(null);
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js b/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
index cf06e9685..101837e06 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
@@ -1,15 +1,7 @@
import { css } from "@emotion/react";
import { darken } from "@embeddedchat/ui-elements";
-const rowCentreAlign = css`
- display: flex;
- flex-direction: ;
- align-items: center;
-`;
-
-export const getChatHeaderStyles = (customTheme) => {
- const { theme, mode, colors } = customTheme;
-
+export const getChatHeaderStyles = ({ theme, mode, colors }) => {
const styles = {
clearSpacing: css`
margin: 0;
@@ -17,7 +9,9 @@ export const getChatHeaderStyles = (customTheme) => {
`,
chatHeaderChild: css`
- ${rowCentreAlign}
+ display: flex;
+ flex-direction: ;
+ align-items: center;
padding: 0 0.75rem;
justify-content: space-between;
width: 100%;
@@ -36,13 +30,17 @@ export const getChatHeaderStyles = (customTheme) => {
`,
channelDescription: css`
- ${rowCentreAlign}
+ display: flex;
+ flex-direction: ;
+ align-items: center;
gap: 0.5rem;
`,
chatHeaderIconRow: css`
- ${rowCentreAlign}
- position:relative;
+ display: flex;
+ flex-direction: ;
+ align-items: center;
+ position: relative;
gap: 0.5rem;
`,
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInput.jsx b/packages/layout_editor/src/views/ChatInput/ChatInput.jsx
index ced155b93..de0c4b3be 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInput.jsx
+++ b/packages/layout_editor/src/views/ChatInput/ChatInput.jsx
@@ -1,11 +1,11 @@
import React, { useRef } from "react";
import { css } from "@emotion/react";
-import { Box, Input, ActionButton } from "@embeddedchat/ui-elements";
-import { useChatInputStyles } from "./ChatInput.styles";
+import { Box, Input, ActionButton, useTheme } from "@embeddedchat/ui-elements";
+import { getChatInputStyles } from "./ChatInput.styles";
import ChatInputToolbar from "./ChatInputToolbar";
const ChatInput = () => {
- const styles = useChatInputStyles();
+ const styles = getChatInputStyles(useTheme());
const inputRef = useRef(null);
const messageRef = useRef(null);
@@ -55,10 +55,7 @@ const ChatInput = () => {
/>
-
+
);
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js b/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
index c03c61a22..c38db696c 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
+++ b/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
@@ -1,9 +1,7 @@
import { css } from "@emotion/react";
-import { darken, useTheme } from "@embeddedchat/ui-elements";
-
-export const useChatInputStyles = () => {
- const { theme, colors } = useTheme();
+import { darken } from "@embeddedchat/ui-elements";
+export const getChatInputStyles = ({ theme, colors }) => {
const styles = {
inputWithFormattingBox: css`
border: 1px solid ${colors.border};
@@ -50,9 +48,7 @@ export const useChatInputStyles = () => {
return styles;
};
-export const useChatInputToolbarStyles = () => {
- const { theme, mode, colors } = useTheme();
-
+export const getChatInputToolbarStyles = ({ theme, mode, colors }) => {
const styles = {
chatFormat: css`
bottom: 0;
@@ -72,8 +68,7 @@ export const useChatInputToolbarStyles = () => {
return styles;
};
-export const useFormatterStyles = () => {
- const { theme, colors } = useTheme();
+export const getFormatterStyles = ({ theme, colors }) => {
const styles = {
toolboxContainer: css`
display: flex;
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx b/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
index 5ecb17c17..49d1d77ac 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
+++ b/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
@@ -1,6 +1,6 @@
-import React, { useEffect, useMemo, useState } from "react";
-import { Box } from "@embeddedchat/ui-elements";
-import { useChatInputToolbarStyles } from "./ChatInput.styles";
+import React, { useMemo, useState } from "react";
+import { Box, useTheme } from "@embeddedchat/ui-elements";
+import { getChatInputToolbarStyles } from "./ChatInput.styles";
import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
import SurfaceItem from "../../components/SurfaceMenu/SurfaceItem";
import Formatters from "./Formatters";
@@ -22,7 +22,7 @@ const ChatInputToolbar = ({
formatters: ["bold", "italic", "strike", "code", "multiline"],
},
}) => {
- const styles = useChatInputToolbarStyles();
+ const styles = getChatInputToolbarStyles(useTheme());
const [surfaceItems, setSurfaceItems] = useState(optionConfig.surfaceItems);
const [formatters, setFormatters] = useState(optionConfig.formatters);
const [activeSurfaceItem, setActiveSurfaceItem] = useState(null);
diff --git a/packages/layout_editor/src/views/ChatInput/Formatters.jsx b/packages/layout_editor/src/views/ChatInput/Formatters.jsx
index ac2570638..94f9491b4 100644
--- a/packages/layout_editor/src/views/ChatInput/Formatters.jsx
+++ b/packages/layout_editor/src/views/ChatInput/Formatters.jsx
@@ -1,10 +1,10 @@
import React, { useMemo } from "react";
-import { Box } from "@embeddedchat/ui-elements";
-import { useFormatterStyles } from "./ChatInput.styles";
+import { Box, useTheme } from "@embeddedchat/ui-elements";
+import { getFormatterStyles } from "./ChatInput.styles";
import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
const Formatters = ({ formatters, ...props }) => {
- const styles = useFormatterStyles();
+ const styles = getFormatterStyles(useTheme());
const options = useMemo(() => {
return {
diff --git a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
index cfe675bcf..0fc1000b0 100644
--- a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
+++ b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
@@ -2,11 +2,12 @@ import React from "react";
import { Box } from "@embeddedchat/ui-elements";
import ChatBody from "../Chatbody/ChatBody";
import ChatInput from "../ChatInput/ChatInput";
-import styles from "./ChatLayout.styles";
+import { getChatLayoutStyles } from "./ChatLayout.styles";
import DemoSidebar from "../DemoSidebar/DemoSidebar";
import members from "../../data/members.json";
const ChatLayout = () => {
+ const styles = getChatLayoutStyles();
return (
diff --git a/packages/layout_editor/src/views/ChatLayout/ChatLayout.styles.js b/packages/layout_editor/src/views/ChatLayout/ChatLayout.styles.js
index 12a45957b..ddfa382d0 100644
--- a/packages/layout_editor/src/views/ChatLayout/ChatLayout.styles.js
+++ b/packages/layout_editor/src/views/ChatLayout/ChatLayout.styles.js
@@ -1,18 +1,20 @@
-import { css } from '@emotion/react';
+import { css } from "@emotion/react";
-const styles = {
- layout: css`
- flex-basis: 100%;
- display: flex;
- overflow: hidden;
- `,
+export const getChatLayoutStyles = () => {
+ const styles = {
+ layout: css`
+ flex-basis: 100%;
+ display: flex;
+ overflow: hidden;
+ `,
- chatMain: css`
- display: flex;
- flex-direction: column;
- flex-grow: 1;
- position: relative;
- `,
-};
+ chatMain: css`
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+ position: relative;
+ `,
+ };
-export default styles;
+ return styles;
+};
diff --git a/packages/layout_editor/src/views/Chatbody/ChatBody.jsx b/packages/layout_editor/src/views/Chatbody/ChatBody.jsx
index ccc8790f0..de2fcf78d 100644
--- a/packages/layout_editor/src/views/Chatbody/ChatBody.jsx
+++ b/packages/layout_editor/src/views/Chatbody/ChatBody.jsx
@@ -1,11 +1,11 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { Box } from '@embeddedchat/ui-elements';
-import { useChatbodyStyles } from './ChatBody.styles';
-import MessageList from '../MessageList/MessageList';
+import React from "react";
+import PropTypes from "prop-types";
+import { Box } from "@embeddedchat/ui-elements";
+import { getChatbodyStyles } from "./ChatBody.styles";
+import MessageList from "../MessageList/MessageList";
const ChatBody = () => {
- const styles = useChatbodyStyles();
+ const styles = getChatbodyStyles();
return (
diff --git a/packages/layout_editor/src/views/Chatbody/ChatBody.styles.js b/packages/layout_editor/src/views/Chatbody/ChatBody.styles.js
index 5ada0d0ca..99321e2eb 100644
--- a/packages/layout_editor/src/views/Chatbody/ChatBody.styles.js
+++ b/packages/layout_editor/src/views/Chatbody/ChatBody.styles.js
@@ -1,18 +1,20 @@
-import { css } from '@emotion/react';
+import { css } from "@emotion/react";
-export const useChatbodyStyles = () => {
- const chatbodyContainer = css`
- flex: 1;
- word-break: break-all;
- overflow: auto;
- overflow-x: hidden;
- display: flex;
- flex-direction: column-reverse;
- max-height: 600px;
- position: relative;
- padding-top: 70px;
- margin-top: 0.25rem;
- `;
+export const getChatbodyStyles = () => {
+ const styles = {
+ chatbodyContainer: css`
+ flex: 1;
+ word-break: break-all;
+ overflow: auto;
+ overflow-x: hidden;
+ display: flex;
+ flex-direction: column-reverse;
+ max-height: 600px;
+ position: relative;
+ padding-top: 70px;
+ margin-top: 0.25rem;
+ `,
+ };
- return { chatbodyContainer };
+ return styles;
};
diff --git a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
index 054a31a6c..7e549a2b4 100644
--- a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
+++ b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
@@ -2,11 +2,11 @@ import React from "react";
import PropTypes from "prop-types";
import { Box, Icon, Sidebar, Popup } from "@embeddedchat/ui-elements";
import { css } from "@emotion/react";
-import { useDemoSidebarStyles } from "./DemoSidebar.styles";
+import { getDemoSidebarStyles } from "./DemoSidebar.styles";
const DemoSidebar = ({ members, viewType = "Sidebar" }) => {
const ViewComponent = viewType === "Popup" ? Popup : Sidebar;
- const styles = useDemoSidebarStyles();
+ const styles = getDemoSidebarStyles();
return (
{
+export const getDemoSidebarStyles = () => {
const styles = {
container: css`
display: flex;
diff --git a/packages/layout_editor/src/views/GlobalStyles.jsx b/packages/layout_editor/src/views/GlobalStyles.jsx
index d17c40143..72d9e52f6 100644
--- a/packages/layout_editor/src/views/GlobalStyles.jsx
+++ b/packages/layout_editor/src/views/GlobalStyles.jsx
@@ -1,8 +1,8 @@
-import React from 'react';
-import { css, Global } from '@emotion/react';
-import { useTheme, alpha } from '@embeddedchat/ui-elements';
+import React from "react";
+import { css, Global } from "@emotion/react";
+import { useTheme, alpha } from "@embeddedchat/ui-elements";
-const useStyles = (colors, theme) => css`
+const useStyles = ({ colors, theme }) => css`
.ec-embedded-chat * {
box-sizing: border-box;
margin: 0;
@@ -39,8 +39,7 @@ const useStyles = (colors, theme) => css`
`;
const GlobalStyles = () => {
- const { theme, colors } = useTheme();
- const styles = useStyles(colors, theme);
+ const styles = useStyles(useTheme());
return ;
};
diff --git a/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js b/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js
index 576d30d2b..137f36390 100644
--- a/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js
+++ b/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js
@@ -1,11 +1,9 @@
-import { css } from '@emotion/react';
-import { alpha } from '@embeddedchat/ui-elements';
-
-export const bubbleStyles = (customTheme) => {
- const { theme, colors } = customTheme;
+import { css } from "@emotion/react";
+import { alpha } from "@embeddedchat/ui-elements";
+export const bubbleStyles = ({ theme, colors }) => {
const styles = {
- name: 'bubble',
+ name: "bubble",
messageParent: css`
display: flex;
gap: 0.25rem;
diff --git a/packages/layout_editor/src/views/Message/BubbleVariant/useBubbleStyles.js b/packages/layout_editor/src/views/Message/BubbleVariant/useBubbleStyles.js
index 6f3f81f45..4f80b1596 100644
--- a/packages/layout_editor/src/views/Message/BubbleVariant/useBubbleStyles.js
+++ b/packages/layout_editor/src/views/Message/BubbleVariant/useBubbleStyles.js
@@ -1,10 +1,10 @@
-import { useTheme } from '@embeddedchat/ui-elements';
-import { bubbleStyles, bubbleStylesMe } from './Bubble.styles';
+import { useTheme } from "@embeddedchat/ui-elements";
+import { bubbleStyles, bubbleStylesMe } from "./Bubble.styles";
const useBubbleStyles = (isMe = false) => {
- const customTheme = useTheme();
- const styles = bubbleStyles(customTheme);
- const meStyles = bubbleStylesMe(customTheme);
+ const theme = useTheme();
+ const styles = bubbleStyles(theme);
+ const meStyles = bubbleStylesMe(theme);
const mergedStyles = {};
diff --git a/packages/layout_editor/src/views/Message/Message.jsx b/packages/layout_editor/src/views/Message/Message.jsx
index b033e1fe8..404afb04c 100644
--- a/packages/layout_editor/src/views/Message/Message.jsx
+++ b/packages/layout_editor/src/views/Message/Message.jsx
@@ -1,7 +1,7 @@
import React from "react";
import PropTypes from "prop-types";
import { format } from "date-fns";
-import { Box } from "@embeddedchat/ui-elements";
+import { Box, useTheme } from "@embeddedchat/ui-elements";
import { Markdown } from "../Markdown";
import MessageHeader from "./MessageHeader";
import { MessageBody } from "./MessageBody";
@@ -9,7 +9,7 @@ import { MessageToolbox } from "./MessageToolbox";
import { MessageDivider } from "./MessageDivider";
import MessageAvatarContainer from "./MessageAvatarContainer";
import MessageBodyContainer from "./MessageBodyContainer";
-import { useMessageStyles } from "./Message.styles";
+import { getMessageStyles } from "./Message.styles";
import useBubbleStyles from "./BubbleVariant/useBubbleStyles";
const Message = ({
@@ -20,7 +20,7 @@ const Message = ({
variantOverrides = "default",
}) => {
const isMe = message.u.username === "spiral_memory";
- const styles = useMessageStyles();
+ const styles = getMessageStyles(useTheme());
const bubbleStyles = useBubbleStyles(isMe);
const shouldShowHeader = !sequential;
const variantStyles = variantOverrides === "bubble" ? bubbleStyles : {};
diff --git a/packages/layout_editor/src/views/Message/Message.styles.js b/packages/layout_editor/src/views/Message/Message.styles.js
index c5f01dd7e..f865d21d6 100644
--- a/packages/layout_editor/src/views/Message/Message.styles.js
+++ b/packages/layout_editor/src/views/Message/Message.styles.js
@@ -1,200 +1,204 @@
import { css } from "@emotion/react";
-import { lighten, darken, useTheme } from "@embeddedchat/ui-elements";
+import { lighten, darken } from "@embeddedchat/ui-elements";
+
+export const getMessageStyles = ({ mode, colors }) => {
+ const styles = {
+ main: css`
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ padding-top: 0.5rem;
+ padding-bottom: 0.25rem;
+ padding-left: 2.25rem;
+ padding-right: 2.25rem;
+ color: ${colors.foreground};
+
+ &:hover {
+ background-color: ${mode === "light"
+ ? darken(colors.background, 0.03)
+ : lighten(colors.background, 1)};
+ }
+ `,
+ messageEditing: css`
+ background-color: ${colors.secondary};
+ &:hover {
+ background-color: ${colors.secondary};
+ }
+ `,
-export const useMessageStyles = () => {
- const { mode, colors } = useTheme();
+ pendingMessageBody: css`
+ opacity: 0.4 !important;
+ white-space: pre-line;
+ `,
- const main = css`
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- padding-top: 0.5rem;
- padding-bottom: 0.25rem;
- padding-left: 2.25rem;
- padding-right: 2.25rem;
- color: ${colors.foreground};
-
- &:hover {
+ specialMessage: css`
background-color: ${mode === "light"
? darken(colors.background, 0.03)
: lighten(colors.background, 1)};
- }
- `;
- const messageEditing = css`
- background-color: ${colors.secondary};
- &:hover {
- background-color: ${colors.secondary};
- }
- `;
-
- const pendingMessageBody = css`
- opacity: 0.4 !important;
- white-space: pre-line;
- `;
-
- const specialMessage = css`
- background-color: ${mode === "light"
- ? darken(colors.background, 0.03)
- : lighten(colors.background, 1)};
- `;
+ `,
+ };
- return { main, messageEditing, pendingMessageBody, specialMessage };
+ return styles;
};
-export const useMessageAvatarContainerStyles = () => {
- const { colors } = useTheme();
-
- const container = css`
- margin: 3px;
- width: 2.25em;
- max-height: 2.25em;
- display: flex;
- justify-content: flex-end;
- color: ${colors.primary};
- `;
-
- return { container };
-};
+export const getMessageAvatarContainerStyles = ({ colors }) => {
+ const styles = {
+ container: css`
+ margin: 3px;
+ width: 2.25em;
+ max-height: 2.25em;
+ display: flex;
+ justify-content: flex-end;
+ color: ${colors.primary};
+ `,
+ };
-export const MessageBodyStyles = {
- messageBody: css`
- position: relative;
- letter-spacing: 0rem;
- font-size: 0.875rem;
- font-weight: 400;
- line-height: 1.25rem;
- flex-shrink: 1;
- transition: opacity 0.3s linear;
- word-break: break-word;
- opacity: 1;
- margin-top: 0.125rem;
- margin-bottom: 0.125rem;
- `,
+ return styles;
};
-export const useMessageDividerStyles = () => {
- const { theme, colors } = useTheme();
-
- const divider = css`
- letter-spacing: 0rem;
- font-size: 0.75rem;
- font-weight: 700;
- line-height: 1rem;
- position: relative;
- display: flex;
- z-index: ${theme.zIndex.divider};
- align-items: center;
- margin-top: 0.5rem;
- margin-bottom: 0.75rem;
- padding-left: 1.25rem;
- padding-right: 1.25rem;
- `;
-
- const dividerContent = css`
- margin-top: 0.5rem;
- margin-bottom: 0.5rem;
- padding-left: 0.5rem;
- padding-right: 0.5rem;
- background-color: ${colors.secondary};
- color: ${colors.secondaryForeground};
- position: absolute;
- left: 50%;
- transform: translateX(-50%);
- border-radius: ${theme.schemes.radius};
- `;
-
- const bar = css`
- display: flex;
- justify-content: flex-end;
- align-items: center;
- flex-grow: 1;
- height: 1px;
- background-color: ${colors.secondary};
- `;
+export const getMessageBodyStyles = () => {
+ const styles = {
+ messageBody: css`
+ position: relative;
+ letter-spacing: 0rem;
+ font-size: 0.875rem;
+ font-weight: 400;
+ line-height: 1.25rem;
+ flex-shrink: 1;
+ transition: opacity 0.3s linear;
+ word-break: break-word;
+ opacity: 1;
+ margin-top: 0.125rem;
+ margin-bottom: 0.125rem;
+ `,
+ };
- return { divider, bar, dividerContent };
+ return styles;
};
-export const useMessageHeaderStyles = () => {
- const { theme, colors } = useTheme();
-
- const header = css`
- display: flex;
- flex-direction: row;
- flex-grow: 0;
- flex-shrink: 1;
- min-width: 1px;
- margin-top: 0.125rem;
- margin-bottom: 0.125rem;
- gap: 0.125rem;
- align-items: center;
- `;
-
- const name = css`
- letter-spacing: 0rem;
- font-size: 0.875rem;
- font-weight: 700;
- line-height: 1.25rem;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- flex-shrink: 1;
- `;
-
- const userName = css`
- color: ${colors.accentForeground};
- font-weight: 700;
- letter-spacing: 0rem;
- font-size: 0.875rem;
- line-height: 1.25rem;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- flex-shrink: 1;
- `;
+export const getMessageDividerStyles = ({ theme, colors }) => {
+ const styles = {
+ divider: css`
+ letter-spacing: 0rem;
+ font-size: 0.75rem;
+ font-weight: 700;
+ line-height: 1rem;
+ position: relative;
+ display: flex;
+ z-index: ${theme.zIndex.divider};
+ align-items: center;
+ margin-top: 0.5rem;
+ margin-bottom: 0.75rem;
+ padding-left: 1.25rem;
+ padding-right: 1.25rem;
+ `,
+
+ dividerContent: css`
+ margin-top: 0.5rem;
+ margin-bottom: 0.5rem;
+ padding-left: 0.5rem;
+ padding-right: 0.5rem;
+ background-color: ${colors.secondary};
+ color: ${colors.secondaryForeground};
+ position: absolute;
+ left: 50%;
+ transform: translateX(-50%);
+ border-radius: ${theme.schemes.radius};
+ `,
+
+ bar: css`
+ display: flex;
+ justify-content: flex-end;
+ align-items: center;
+ flex-grow: 1;
+ height: 1px;
+ background-color: ${colors.secondary};
+ `,
+ };
- const userRole = css`
- letter-spacing: 0rem;
- font-size: 0.75rem;
- padding: 0 0.25rem;
- margin: 0 0.1rem;
- border-radius: ${theme.schemes.radius};
- font-weight: 700;
- line-height: 1rem;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- background-color: ${colors.secondary};
- `;
+ return styles;
+};
- const userActions = css`
- color: ${colors.accentForeground};
- letter-spacing: 0rem;
- font-size: 0.875rem;
- line-height: 1.25rem;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- flex-shrink: 1;
- `;
+export const getMessageHeaderStyles = ({ theme, colors }) => {
+ const styles = {
+ header: css`
+ display: flex;
+ flex-direction: row;
+ flex-grow: 0;
+ flex-shrink: 1;
+ min-width: 1px;
+ margin-top: 0.125rem;
+ margin-bottom: 0.125rem;
+ gap: 0.125rem;
+ align-items: center;
+ `,
+
+ name: css`
+ letter-spacing: 0rem;
+ font-size: 0.875rem;
+ font-weight: 700;
+ line-height: 1.25rem;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ flex-shrink: 1;
+ `,
+
+ userName: css`
+ color: ${colors.accentForeground};
+ font-weight: 700;
+ letter-spacing: 0rem;
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ flex-shrink: 1;
+ `,
+
+ userRole: css`
+ letter-spacing: 0rem;
+ font-size: 0.75rem;
+ padding: 0 0.25rem;
+ margin: 0 0.1rem;
+ border-radius: ${theme.schemes.radius};
+ font-weight: 700;
+ line-height: 1rem;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ background-color: ${colors.secondary};
+ `,
+
+ userActions: css`
+ color: ${colors.accentForeground};
+ letter-spacing: 0rem;
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ flex-shrink: 1;
+ `,
+
+ timestamp: css`
+ color: ${colors.accentForeground};
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ letter-spacing: 0rem;
+ font-size: 0.75rem;
+ font-weight: 400;
+ line-height: 1rem;
+ flex-shrink: 0;
+ margin-left: 0.25rem;
+ `,
+ };
- const timestamp = css`
- color: ${colors.accentForeground};
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- letter-spacing: 0rem;
- font-size: 0.75rem;
- font-weight: 400;
- line-height: 1rem;
- flex-shrink: 0;
- margin-left: 0.25rem;
- `;
-
- return { header, name, userRole, userName, timestamp, userActions };
+ return styles;
};
-export const MessageMetricsStyles = {
+export const getMessageMetricsStyles = {
metrics: css`
display: flex;
margin-left: -0.25rem;
@@ -220,84 +224,83 @@ export const MessageMetricsStyles = {
`,
};
-export const useMessageReactionsStyles = () => {
- const { colors } = useTheme();
- const container = css`
- display: flex;
- flex-flow: row wrap;
- justify-content: flex-start;
- `;
+export const getMessageReactionsStyles = ({ colors }) => {
+ const styles = {
+ container: css`
+ display: flex;
+ flex-flow: row wrap;
+ justify-content: flex-start;
+ `,
+
+ reaction: css`
+ letter-spacing: 0rem;
+ font-size: 0.6rem;
+ display: inline-flex;
+ gap: 0.125rem;
+ align-items: center;
+ justify-content: center;
+ padding: 0.1rem;
+ margin: 0.125rem;
+ cursor: pointer;
+ img.joypixels {
+ height: 0.75em;
+ width: 0.75em;
+ }
+ p {
+ margin: 0;
+ }
+ border: 1px solid ${colors.border};
+ border-radius: 0.2rem;
+ `,
+
+ reactionMine: css`
+ background: ${colors.secondary};
+ `,
+ };
- const reaction = css`
- letter-spacing: 0rem;
- font-size: 0.6rem;
- display: inline-flex;
- gap: 0.125rem;
- align-items: center;
- justify-content: center;
- padding: 0.1rem;
- margin: 0.125rem;
- cursor: pointer;
- img.joypixels {
- height: 0.75em;
- width: 0.75em;
- }
- p {
- margin: 0;
- }
- border: 1px solid ${colors.border};
- border-radius: 0.2rem;
- `;
-
- const reactionMine = css`
- background: ${colors.secondary};
- `;
-
- return { container, reaction, reactionMine };
+ return styles;
};
-export const useMessageToolboxStyles = () => {
- const { theme, colors } = useTheme();
-
- const toolboxContainer = css`
- display: flex;
- position: absolute;
- bottom: 100%;
- z-index: ${theme.zIndex.body + 1};
- right: 2rem;
- `;
-
- const toolbox = css`
- display: flex;
- margin-left: -0.25rem;
- margin-right: -0.25rem;
- margin-top: 0.125rem;
- background-color: ${colors.background};
- box-shadow: 0 0 2px ${colors.foreground};
- gap: 0.25rem;
- padding: 0.25rem;
- border-radius: ${theme.schemes.radius};
- `;
-
- const emojiPickerStyles = css`
- position: absolute;
- bottom: 100%;
- right: 1.5rem;
- `;
-
- return {
- toolboxContainer,
- toolbox,
- emojiPickerStyles,
+export const getMessageToolboxStyles = ({ theme, colors }) => {
+ const styles = {
+ toolboxContainer: css`
+ display: flex;
+ position: absolute;
+ bottom: 100%;
+ z-index: ${theme.zIndex.body + 1};
+ right: 2rem;
+ `,
+
+ toolbox: css`
+ display: flex;
+ margin-left: -0.25rem;
+ margin-right: -0.25rem;
+ margin-top: 0.125rem;
+ background-color: ${colors.background};
+ box-shadow: 0 0 2px ${colors.foreground};
+ gap: 0.25rem;
+ padding: 0.25rem;
+ border-radius: ${theme.schemes.radius};
+ `,
+
+ emojiPickerStyles: css`
+ position: absolute;
+ bottom: 100%;
+ right: 1.5rem;
+ `,
};
+
+ return styles;
};
-export const useMessageBodyContainerStyles = () => {
- const bodyContainer = css`
- margin-left: 5px;
- position: relative;
- width: 100%;
- `;
+export const getMessageBodyContainerStyles = () => {
+ const styles = {
+ bodyContainer: css`
+ margin-left: 5px;
+ position: relative;
+ width: 100%;
+ `,
+ };
- return { bodyContainer };
+ return styles;
};
diff --git a/packages/layout_editor/src/views/Message/MessageAvatarContainer.jsx b/packages/layout_editor/src/views/Message/MessageAvatarContainer.jsx
index 15f7a36a3..9a9ee65e3 100644
--- a/packages/layout_editor/src/views/Message/MessageAvatarContainer.jsx
+++ b/packages/layout_editor/src/views/Message/MessageAvatarContainer.jsx
@@ -1,9 +1,9 @@
import React from "react";
-import { Box, Icon } from "@embeddedchat/ui-elements";
-import { useMessageAvatarContainerStyles } from "./Message.styles";
+import { Box, Icon, useTheme } from "@embeddedchat/ui-elements";
+import { getMessageAvatarContainerStyles } from "./Message.styles";
const MessageAvatarContainer = ({ message, sequential }) => {
- const styles = useMessageAvatarContainerStyles();
+ const styles = getMessageAvatarContainerStyles(useTheme());
return (
diff --git a/packages/layout_editor/src/views/Message/MessageBody.jsx b/packages/layout_editor/src/views/Message/MessageBody.jsx
index 7c7a5df62..d0eb14658 100644
--- a/packages/layout_editor/src/views/Message/MessageBody.jsx
+++ b/packages/layout_editor/src/views/Message/MessageBody.jsx
@@ -1,6 +1,6 @@
import React from "react";
import { Box } from "@embeddedchat/ui-elements";
-import { MessageBodyStyles as styles } from "./Message.styles";
+import { getMessageBodyStyles } from "./Message.styles";
export const MessageBody = ({
children,
@@ -10,6 +10,7 @@ export const MessageBody = ({
lastSequential = false,
...props
}) => {
+ const styles = getMessageBodyStyles();
const messageBodyStyles =
(isText ? variantStyles.messageBody : variantStyles.attachmentBody) ||
styles.messageBody;
diff --git a/packages/layout_editor/src/views/Message/MessageBodyContainer.jsx b/packages/layout_editor/src/views/Message/MessageBodyContainer.jsx
index 209c86712..c89b53efb 100644
--- a/packages/layout_editor/src/views/Message/MessageBodyContainer.jsx
+++ b/packages/layout_editor/src/views/Message/MessageBodyContainer.jsx
@@ -1,10 +1,10 @@
import React from "react";
import { Box } from "@embeddedchat/ui-elements";
-import { useMessageBodyContainerStyles } from "./Message.styles";
+import { getMessageBodyContainerStyles } from "./Message.styles";
const MessageBodyContainer = ({ children, variantStyles = {} }) => {
- const styles = useMessageBodyContainerStyles();
+ const styles = getMessageBodyContainerStyles();
return (
{
-
- const styles = useMessageDividerStyles();
+export const MessageDivider = ({ children, ...props }) => {
+ const styles = getMessageDividerStyles(useTheme());
return (
{children && (
diff --git a/packages/layout_editor/src/views/Message/MessageHeader.jsx b/packages/layout_editor/src/views/Message/MessageHeader.jsx
index a64f983de..a3dadfb37 100644
--- a/packages/layout_editor/src/views/Message/MessageHeader.jsx
+++ b/packages/layout_editor/src/views/Message/MessageHeader.jsx
@@ -7,12 +7,12 @@ import {
useTheme,
appendClassNames,
} from "@embeddedchat/ui-elements";
-import { useMessageHeaderStyles } from "./Message.styles";
+import { getMessageHeaderStyles } from "./Message.styles";
import useDisplayNameColor from "../../hooks/useDisplayNameColor";
const MessageHeader = ({ message, variantOverrides }) => {
const displayNameVariant = variantOverrides || "Normal";
- const styles = useMessageHeaderStyles();
+ const styles = getMessageHeaderStyles(useTheme());
const { colors } = useTheme();
const getDisplayNameColor = useDisplayNameColor();
diff --git a/packages/layout_editor/src/views/Message/MessageToolbox.jsx b/packages/layout_editor/src/views/Message/MessageToolbox.jsx
index 4bbfcf525..a4d48cac4 100644
--- a/packages/layout_editor/src/views/Message/MessageToolbox.jsx
+++ b/packages/layout_editor/src/views/Message/MessageToolbox.jsx
@@ -1,7 +1,7 @@
import React, { useMemo, useState } from "react";
-import { Box } from "@embeddedchat/ui-elements";
+import { Box, useTheme } from "@embeddedchat/ui-elements";
import { Menu } from "../../components/SortableMenu";
-import { useMessageToolboxStyles } from "./Message.styles";
+import { getMessageToolboxStyles } from "./Message.styles";
import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
import SurfaceItem from "../../components/SurfaceMenu/SurfaceItem";
import MenuItem from "../../components/SortableMenu/MenuItem";
@@ -36,7 +36,7 @@ export const MessageToolbox = ({
...props
}) => {
- const styles = useMessageToolboxStyles();
+ const styles = getMessageToolboxStyles(useTheme());
const [surfaceItems, setSurfaceItems] = useState(optionConfig.surfaceItems);
const [menuItems, setMenuItems] = useState(optionConfig.menuItems);
const [activeSurfaceItem, setActiveSurfaceItem] = useState(null);
From 871aa6900b2ef735972412cda192f112a290187d Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Tue, 16 Jul 2024 15:25:12 +0530
Subject: [PATCH 040/104] changed eslint config
shifted to js project
---
packages/layout_editor/.eslintrc.cjs | 11 +-
packages/layout_editor/.prettierrc | 4 +
packages/layout_editor/README.md | 9 +-
packages/layout_editor/package.json | 18 +-
packages/layout_editor/src/App.jsx | 4 +-
.../src/components/SortableMenu/Menu.jsx | 20 +-
.../components/SortableMenu/Menu.styles.js | 10 +-
.../src/components/SortableMenu/MenuItem.jsx | 18 +-
.../src/components/SortableMenu/index.js | 2 +-
.../components/SurfaceMenu/SurfaceItem.jsx | 20 +-
.../components/SurfaceMenu/SurfaceMenu.jsx | 6 +-
.../SurfaceMenu/SurfaceMenu.styles.js | 6 +-
.../src/hooks/useDisplayNameColor.js | 1 -
packages/layout_editor/src/main.jsx | 8 +-
packages/layout_editor/src/main.tsx | 8 +-
.../layout_editor/src/theme/DefaultTheme.js | 124 ++--
.../src/views/ChatHeader/ChatHeader.jsx | 5 +-
packages/layout_editor/tests/example.spec.ts | 4 +-
packages/layout_editor/tsconfig.json | 26 -
packages/layout_editor/tsconfig.node.json | 11 -
packages/layout_editor/vite.config.ts | 11 +-
packages/react-native/package.json | 2 +-
yarn.lock | 696 +++++++++++++++++-
23 files changed, 804 insertions(+), 220 deletions(-)
create mode 100644 packages/layout_editor/.prettierrc
delete mode 100644 packages/layout_editor/tsconfig.json
delete mode 100644 packages/layout_editor/tsconfig.node.json
diff --git a/packages/layout_editor/.eslintrc.cjs b/packages/layout_editor/.eslintrc.cjs
index ab0963231..bf64d1237 100644
--- a/packages/layout_editor/.eslintrc.cjs
+++ b/packages/layout_editor/.eslintrc.cjs
@@ -2,17 +2,14 @@ module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
- "eslint:recommended",
- "plugin:react/jsx-runtime",
- "plugin:@typescript-eslint/recommended",
- "plugin:react-hooks/recommended",
"plugin:react/recommended",
+ "plugin:react-hooks/recommended",
+ "prettier",
],
ignorePatterns: ["dist", ".eslintrc.cjs"],
- parser: "@typescript-eslint/parser",
parserOptions: { ecmaVersion: "latest", sourceType: "module" },
settings: { react: { version: "18.2" } },
- plugins: ["react-refresh", "import"],
+ plugins: ["react-refresh"],
rules: {
"react/jsx-no-target-blank": "off",
"react-refresh/only-export-components": [
@@ -20,6 +17,6 @@ module.exports = {
{ allowConstantExport: true },
],
"react/prop-types": "off",
- "@typescript-eslint/no-unused-vars": ["warn"],
+ "react/no-unknown-property": ["error", { ignore: ["css"] }],
},
};
diff --git a/packages/layout_editor/.prettierrc b/packages/layout_editor/.prettierrc
new file mode 100644
index 000000000..76e396e59
--- /dev/null
+++ b/packages/layout_editor/.prettierrc
@@ -0,0 +1,4 @@
+{
+ "singleQuote": true,
+ "semi": true
+}
\ No newline at end of file
diff --git a/packages/layout_editor/README.md b/packages/layout_editor/README.md
index 181d94ad9..f768e33fc 100644
--- a/packages/layout_editor/README.md
+++ b/packages/layout_editor/README.md
@@ -1 +1,8 @@
-# E2E EmbeddedChat setup
+# React + Vite
+
+This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
+
+Currently, two official plugins are available:
+
+- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
+- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
diff --git a/packages/layout_editor/package.json b/packages/layout_editor/package.json
index c67c27167..90dd03b21 100644
--- a/packages/layout_editor/package.json
+++ b/packages/layout_editor/package.json
@@ -5,12 +5,9 @@
"type": "module",
"scripts": {
"dev": "vite",
- "build": "tsc && vite build",
- "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
- "preview": "vite preview",
- "test": "playwright test",
- "format": "prettier --write 'src/' ",
- "format:check": "prettier --check 'src/' "
+ "build": "vite build",
+ "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
+ "preview": "vite preview"
},
"dependencies": {
"@dnd-kit/core": "^6.1.0",
@@ -20,17 +17,12 @@
"react-dom": "^18.2.0"
},
"devDependencies": {
- "@emotion/babel-plugin": "^11.11.0",
- "@types/node": "^20.11.19",
- "@types/react": "^18.2.55",
- "@types/react-dom": "^18.2.19",
- "@typescript-eslint/eslint-plugin": "^6.21.0",
- "@typescript-eslint/parser": "^6.21.0",
+ "@emotion/babel-preset-css-prop": "^11.11.0",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^8.56.0",
+ "eslint-plugin-react": "^7.34.4",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
- "typescript": "^5.2.2",
"vite": "^5.1.0"
}
}
diff --git a/packages/layout_editor/src/App.jsx b/packages/layout_editor/src/App.jsx
index 33a8002f1..0e7bcf715 100644
--- a/packages/layout_editor/src/App.jsx
+++ b/packages/layout_editor/src/App.jsx
@@ -1,5 +1,5 @@
-import React from "react";
-import LayoutEditor from "./views/LayoutEditor";
+import React from 'react';
+import LayoutEditor from './views/LayoutEditor';
const App = () => {
return ;
diff --git a/packages/layout_editor/src/components/SortableMenu/Menu.jsx b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
index 692cd7e6c..37deccd89 100644
--- a/packages/layout_editor/src/components/SortableMenu/Menu.jsx
+++ b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
@@ -1,20 +1,20 @@
-import React, { useMemo } from "react";
-import { css } from "@emotion/react";
+import React, { useMemo } from 'react';
+import { css } from '@emotion/react';
import {
Box,
ActionButton,
Tooltip,
useTheme,
-} from "@embeddedchat/ui-elements";
-import MenuItem from "./MenuItem";
-import { getMenuStyles } from "./Menu.styles";
-import { SortableContext } from "@dnd-kit/sortable";
+} from '@embeddedchat/ui-elements';
+import MenuItem from './MenuItem';
+import { getMenuStyles } from './Menu.styles';
+import { SortableContext } from '@dnd-kit/sortable';
const Menu = ({
options = [],
- tooltip = { isToolTip: true, position: "bottom", text: "Options" },
- from = "top",
- size = "medium",
+ tooltip = { isToolTip: true, position: 'bottom', text: 'Options' },
+ from = 'top',
+ size = 'medium',
...props
}) => {
const theme = useTheme();
@@ -24,7 +24,7 @@ const Menu = ({
const positions = from.split(/\s+/);
const styleAnchor = {};
positions.forEach((pos) => {
- styleAnchor[pos] = "120%";
+ styleAnchor[pos] = '120%';
});
return styleAnchor;
}, [from]);
diff --git a/packages/layout_editor/src/components/SortableMenu/Menu.styles.js b/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
index 83576a74f..0202e392b 100644
--- a/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
+++ b/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
@@ -1,9 +1,7 @@
-import { css } from "@emotion/react";
-import { lighten, darken } from "@embeddedchat/ui-elements";
-
-export const getMenuStyles = (customTheme) => {
- const { theme, colors } = customTheme;
+import { css } from '@emotion/react';
+import { lighten, darken } from '@embeddedchat/ui-elements';
+export const getMenuStyles = ({ theme, colors }) => {
const styles = {
wrapper: css`
position: relative;
@@ -42,7 +40,7 @@ export const getMenuItemStyles = (customTheme) => {
gap: 0.2rem;
color: ${colors.foreground};
&:hover {
- background-color: ${mode === "light"
+ background-color: ${mode === 'light'
? darken(colors.background, 0.05)
: lighten(colors.background, 2)};
cursor: pointer;
diff --git a/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx b/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
index 0c970b261..63d94b47d 100644
--- a/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
+++ b/packages/layout_editor/src/components/SortableMenu/MenuItem.jsx
@@ -1,9 +1,9 @@
-import React from "react";
-import { Box, Icon, useTheme } from "@embeddedchat/ui-elements";
+import React from 'react';
+import { Box, Icon, useTheme } from '@embeddedchat/ui-elements';
-import { getMenuItemStyles } from "./Menu.styles";
-import { useSortable } from "@dnd-kit/sortable";
-import { CSS } from "@dnd-kit/utilities";
+import { getMenuItemStyles } from './Menu.styles';
+import { useSortable } from '@dnd-kit/sortable';
+import { CSS } from '@dnd-kit/utilities';
const MenuItem = ({ id, icon, label, action, disabled, onRemove }) => {
const theme = useTheme();
@@ -19,7 +19,7 @@ const MenuItem = ({ id, icon, label, action, disabled, onRemove }) => {
} = useSortable({
id,
data: {
- type: "MenuOptions",
+ type: 'MenuOptions',
icon,
label,
},
@@ -28,7 +28,7 @@ const MenuItem = ({ id, icon, label, action, disabled, onRemove }) => {
const style = {
transform: CSS.Transform.toString(transform),
transition,
- cursor: "grab",
+ cursor: 'grab',
};
if (isDragging) {
@@ -36,7 +36,7 @@ const MenuItem = ({ id, icon, label, action, disabled, onRemove }) => {
}
const handleRemoveItem = (id) => {
- if (id !== "placeholder-menu") onRemove(id);
+ if (id !== 'placeholder-menu') onRemove(id);
};
return (
@@ -52,7 +52,7 @@ const MenuItem = ({ id, icon, label, action, disabled, onRemove }) => {
{label}
- {id !== "placeholder-menu" && (
+ {id !== 'placeholder-menu' && (
{
const { attributes, listeners, setNodeRef, transform, isDragging } =
useSortable({
id,
data: {
- type: "SurfaceOptions",
+ type: 'SurfaceOptions',
icon: iconName,
label,
},
@@ -41,7 +41,7 @@ const SurfaceItem = ({
}
const handleRemoveItem = (id) => {
- if (id !== "placeholder-surface") onRemove(id);
+ if (id !== 'placeholder-surface') onRemove(id);
};
return (
@@ -57,11 +57,11 @@ const SurfaceItem = ({
iconSize="small"
color={type}
style={{
- cursor: "grab",
+ cursor: 'grab',
}}
/>
- {id !== "placeholder-surface" && (
+ {id !== 'placeholder-surface' && (
{
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
index aa9ba8a1c..1aeef53b7 100644
--- a/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.jsx
@@ -1,6 +1,6 @@
-import React from "react";
-import SurfaceItem from "./SurfaceItem";
-import { SortableContext } from "@dnd-kit/sortable";
+import React from 'react';
+import SurfaceItem from './SurfaceItem';
+import { SortableContext } from '@dnd-kit/sortable';
const SurfaceMenu = ({ options, ...props }) => {
return (
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.styles.js b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.styles.js
index 166e24603..1d86eaf16 100644
--- a/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.styles.js
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceMenu.styles.js
@@ -1,8 +1,6 @@
-import { css } from "@emotion/react";
-
-export const getSurfaceItemStyles = (customTheme) => {
- const { theme, colors } = customTheme;
+import { css } from '@emotion/react';
+export const getSurfaceItemStyles = ({ theme, colors }) => {
const styles = {
overlayBox: css`
width: 24px;
diff --git a/packages/layout_editor/src/hooks/useDisplayNameColor.js b/packages/layout_editor/src/hooks/useDisplayNameColor.js
index 5e9c32c07..043ca8a89 100644
--- a/packages/layout_editor/src/hooks/useDisplayNameColor.js
+++ b/packages/layout_editor/src/hooks/useDisplayNameColor.js
@@ -1,4 +1,3 @@
-/* eslint-disable no-bitwise */
import { useTheme } from '@embeddedchat/ui-elements';
const simpleHash = (str) => {
diff --git a/packages/layout_editor/src/main.jsx b/packages/layout_editor/src/main.jsx
index 569fdf2fd..6f4d6559c 100644
--- a/packages/layout_editor/src/main.jsx
+++ b/packages/layout_editor/src/main.jsx
@@ -1,8 +1,8 @@
-import React from "react";
-import ReactDOM from "react-dom/client";
-import App from "./App.jsx";
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import App from './App.jsx';
-ReactDOM.createRoot(document.getElementById("root")).render(
+ReactDOM.createRoot(document.getElementById('root')).render(
diff --git a/packages/layout_editor/src/main.tsx b/packages/layout_editor/src/main.tsx
index 577372105..265922afa 100644
--- a/packages/layout_editor/src/main.tsx
+++ b/packages/layout_editor/src/main.tsx
@@ -1,8 +1,8 @@
-import React from "react";
-import ReactDOM from "react-dom/client";
-import App from "./App.jsx";
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import App from './App.jsx';
-ReactDOM.createRoot(document.getElementById("root")!).render(
+ReactDOM.createRoot(document.getElementById('root')!).render(
diff --git a/packages/layout_editor/src/theme/DefaultTheme.js b/packages/layout_editor/src/theme/DefaultTheme.js
index 5392a374f..da20fd7ac 100644
--- a/packages/layout_editor/src/theme/DefaultTheme.js
+++ b/packages/layout_editor/src/theme/DefaultTheme.js
@@ -1,6 +1,6 @@
const DefaultTheme = {
schemes: {
- radius: "0.2rem",
+ radius: '0.2rem',
contrastParams: {
light: {
saturation: 70,
@@ -12,62 +12,62 @@ const DefaultTheme = {
},
},
common: {
- black: "hsl(0, 100%, 0%)",
- white: "hsl(0, 100%, 100%)",
+ black: 'hsl(0, 100%, 0%)',
+ white: 'hsl(0, 100%, 100%)',
},
light: {
- background: "hsl(0, 0%, 100%)",
- foreground: "hsl(240, 10%, 3.9%)",
- card: "hsl(0, 0%, 100%)",
- cardForeground: "hsl(240, 10%, 3.9%)",
- popover: "hsl(0, 0%, 100%)",
- popoverForeground: "hsl(240, 10%, 3.9%)",
- primary: "hsl(240, 5.9%, 10%)",
- primaryForeground: "hsl(0, 0%, 98%)",
- secondary: "hsl(240, 4.8%, 95.9%)",
- secondaryForeground: "hsl(240, 5.9%, 10%)",
- muted: "hsl(240, 4.8%, 95.9%)",
- mutedForeground: "hsl(240, 3.8%, 46.1%)",
- accent: "hsl(240, 4.8%, 95.9%)",
- accentForeground: "hsl(240, 5.9%, 10%)",
- destructive: "hsl(0, 84.2%, 60.2%)",
- destructiveForeground: "hsl(0, 0%, 98%)",
- border: "hsl(240, 5.9%, 90%)",
- input: "hsl(240, 5.9%, 90%)",
- ring: "hsl(240, 5.9%, 10%)",
- warning: "hsl(38, 92%, 50%)",
- warningForeground: "hsl(48, 96%, 89%)",
- success: "hsl(91, 60.4%, 81.2%)",
- successForeground: "hsl(90, 61.1%, 14.1%)",
- info: "hsl(214, 76.4%, 50.2%)",
- infoForeground: "hsl(214.3, 77.8%, 92.9%)",
+ background: 'hsl(0, 0%, 100%)',
+ foreground: 'hsl(240, 10%, 3.9%)',
+ card: 'hsl(0, 0%, 100%)',
+ cardForeground: 'hsl(240, 10%, 3.9%)',
+ popover: 'hsl(0, 0%, 100%)',
+ popoverForeground: 'hsl(240, 10%, 3.9%)',
+ primary: 'hsl(240, 5.9%, 10%)',
+ primaryForeground: 'hsl(0, 0%, 98%)',
+ secondary: 'hsl(240, 4.8%, 95.9%)',
+ secondaryForeground: 'hsl(240, 5.9%, 10%)',
+ muted: 'hsl(240, 4.8%, 95.9%)',
+ mutedForeground: 'hsl(240, 3.8%, 46.1%)',
+ accent: 'hsl(240, 4.8%, 95.9%)',
+ accentForeground: 'hsl(240, 5.9%, 10%)',
+ destructive: 'hsl(0, 84.2%, 60.2%)',
+ destructiveForeground: 'hsl(0, 0%, 98%)',
+ border: 'hsl(240, 5.9%, 90%)',
+ input: 'hsl(240, 5.9%, 90%)',
+ ring: 'hsl(240, 5.9%, 10%)',
+ warning: 'hsl(38, 92%, 50%)',
+ warningForeground: 'hsl(48, 96%, 89%)',
+ success: 'hsl(91, 60.4%, 81.2%)',
+ successForeground: 'hsl(90, 61.1%, 14.1%)',
+ info: 'hsl(214, 76.4%, 50.2%)',
+ infoForeground: 'hsl(214.3, 77.8%, 92.9%)',
},
dark: {
- background: "hsl(240, 10%, 3.9%)",
- foreground: "hsl(0, 0%, 98%)",
- card: "hsl(240, 10%, 3.9%)",
- cardForeground: "hsl(0, 0%, 98%)",
- popover: "hsl(240, 10%, 3.9%)",
- popoverForeground: "hsl(0, 0%, 98%)",
- primary: "hsl(0, 0%, 98%)",
- primaryForeground: "hsl(240, 5.9%, 10%)",
- secondary: "hsl(240, 3.7%, 15.9%)",
- secondaryForeground: "hsl(0, 0%, 98%)",
- muted: "hsl(240, 3.7%, 15.9%)",
- mutedForeground: "hsl(240, 5%, 64.9%)",
- accent: "hsl(240, 3.7%, 15.9%)",
- accentForeground: "hsl(0, 0%, 98%)",
- destructive: "hsl(0, 62.8%, 30.6%)",
- destructiveForeground: "hsl(0, 0%, 98%)",
- border: "hsl(240, 3.7%, 15.9%)",
- input: "hsl(240, 3.7%, 15.9%)",
- ring: "hsl(240, 4.9%, 83.9%)",
- warning: "hsl(48, 96%, 89%)",
- warningForeground: "hsl(38, 92%, 50%)",
- success: "hsl(90, 61.1%, 14.1%)",
- successForeground: "hsl(90, 60%, 90.2%)",
- info: "hsl(214.3, 77.8%, 92.9%)",
- infoForeground: "hsl(214.4, 75.8%, 19.4%)",
+ background: 'hsl(240, 10%, 3.9%)',
+ foreground: 'hsl(0, 0%, 98%)',
+ card: 'hsl(240, 10%, 3.9%)',
+ cardForeground: 'hsl(0, 0%, 98%)',
+ popover: 'hsl(240, 10%, 3.9%)',
+ popoverForeground: 'hsl(0, 0%, 98%)',
+ primary: 'hsl(0, 0%, 98%)',
+ primaryForeground: 'hsl(240, 5.9%, 10%)',
+ secondary: 'hsl(240, 3.7%, 15.9%)',
+ secondaryForeground: 'hsl(0, 0%, 98%)',
+ muted: 'hsl(240, 3.7%, 15.9%)',
+ mutedForeground: 'hsl(240, 5%, 64.9%)',
+ accent: 'hsl(240, 3.7%, 15.9%)',
+ accentForeground: 'hsl(0, 0%, 98%)',
+ destructive: 'hsl(0, 62.8%, 30.6%)',
+ destructiveForeground: 'hsl(0, 0%, 98%)',
+ border: 'hsl(240, 3.7%, 15.9%)',
+ input: 'hsl(240, 3.7%, 15.9%)',
+ ring: 'hsl(240, 4.9%, 83.9%)',
+ warning: 'hsl(48, 96%, 89%)',
+ warningForeground: 'hsl(38, 92%, 50%)',
+ success: 'hsl(90, 61.1%, 14.1%)',
+ successForeground: 'hsl(90, 60%, 90.2%)',
+ info: 'hsl(214.3, 77.8%, 92.9%)',
+ infoForeground: 'hsl(214.4, 75.8%, 19.4%)',
},
},
@@ -87,34 +87,34 @@ const DefaultTheme = {
fontWeightRegular: 400,
},
h1: {
- fontSize: "2rem",
+ fontSize: '2rem',
fontWeight: 800,
},
h2: {
- fontSize: "1.5rem",
+ fontSize: '1.5rem',
fontWeight: 800,
},
h3: {
- fontSize: "1.3rem",
+ fontSize: '1.3rem',
fontWeight: 400,
},
h4: {
- fontSize: "1rem",
+ fontSize: '1rem',
fontWeight: 400,
},
h5: {
- fontSize: "0.83rem",
+ fontSize: '0.83rem',
fontWeight: 400,
},
h6: {
- fontSize: "0.67rem",
+ fontSize: '0.67rem',
fontWeight: 500,
},
},
shadows: [
- "none",
- "rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px",
- "rgba(100, 100, 111, 0.2) 0px 7px 29px 0px",
+ 'none',
+ 'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
+ 'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
],
zIndex: {
divider: 1000,
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
index 007024aa5..4da65a240 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -259,13 +259,12 @@ const ChatHeader = ({
general
-
Channel description
-
+
{
test('EmbeddedChat has a title', async ({ page }) => {
await page.goto('/');
- await expect(page.locator('.ec-chat-header--channelName')).toHaveText('Login to chat');
+ await expect(page.locator('.ec-chat-header--channelName')).toHaveText(
+ 'Login to chat'
+ );
});
test('EmbeddedChat has messages', async ({ page }) => {
diff --git a/packages/layout_editor/tsconfig.json b/packages/layout_editor/tsconfig.json
deleted file mode 100644
index 1ae247aeb..000000000
--- a/packages/layout_editor/tsconfig.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "compilerOptions": {
- "target": "ES2020",
- "useDefineForClassFields": true,
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
- "module": "ESNext",
- "skipLibCheck": true,
- "allowJs": true,
-
- /* Bundler mode */
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "react-jsx",
-
- /* Linting */
- "strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true
- },
- "include": ["src"],
- "references": [{ "path": "./tsconfig.node.json" }]
-}
diff --git a/packages/layout_editor/tsconfig.node.json b/packages/layout_editor/tsconfig.node.json
deleted file mode 100644
index 97ede7ee6..000000000
--- a/packages/layout_editor/tsconfig.node.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "compilerOptions": {
- "composite": true,
- "skipLibCheck": true,
- "module": "ESNext",
- "moduleResolution": "bundler",
- "allowSyntheticDefaultImports": true,
- "strict": true
- },
- "include": ["vite.config.ts"]
-}
diff --git a/packages/layout_editor/vite.config.ts b/packages/layout_editor/vite.config.ts
index 2e2219a6a..f10075223 100644
--- a/packages/layout_editor/vite.config.ts
+++ b/packages/layout_editor/vite.config.ts
@@ -1,17 +1,14 @@
-import { defineConfig } from "vite";
-import react from "@vitejs/plugin-react";
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react({
- jsxImportSource: "@emotion/react",
+ jsxImportSource: '@emotion/react',
babel: {
- plugins: ["@emotion/babel-plugin"],
+ plugins: ['@emotion/babel-plugin'],
},
}),
],
- define: {
- "process.env": {},
- },
});
diff --git a/packages/react-native/package.json b/packages/react-native/package.json
index 35cd7435e..c68e9bce8 100644
--- a/packages/react-native/package.json
+++ b/packages/react-native/package.json
@@ -2,7 +2,7 @@
"dependencies": {
"@embeddedchat/api": "0.0.2",
"@emotion/native": "^11.11.0",
- "@emotion/react": "^11.11.1",
+ "@emotion/react": "11.7.1",
"@expo/vector-icons": "^13.0.0",
"@gorhom/bottom-sheet": "^4",
"@react-native-async-storage/async-storage": "1.17.11",
diff --git a/yarn.lock b/yarn.lock
index d573d2a32..1a5c60869 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2392,7 +2392,7 @@ __metadata:
"@babel/eslint-parser": ^7.22.15
"@embeddedchat/api": 0.0.2
"@emotion/native": ^11.11.0
- "@emotion/react": ^11.11.1
+ "@emotion/react": 11.7.1
"@expo/vector-icons": ^13.0.0
"@gorhom/bottom-sheet": ^4
"@react-native-async-storage/async-storage": 1.17.11
@@ -2678,7 +2678,7 @@ __metadata:
languageName: node
linkType: hard
-"@emotion/cache@npm:^11.11.0, @emotion/cache@npm:^11.7.1":
+"@emotion/cache@npm:^11.7.1":
version: 11.11.0
resolution: "@emotion/cache@npm:11.11.0"
dependencies:
@@ -2751,27 +2751,6 @@ __metadata:
languageName: node
linkType: hard
-"@emotion/react@npm:^11.11.1":
- version: 11.11.1
- resolution: "@emotion/react@npm:11.11.1"
- dependencies:
- "@babel/runtime": ^7.18.3
- "@emotion/babel-plugin": ^11.11.0
- "@emotion/cache": ^11.11.0
- "@emotion/serialize": ^1.1.2
- "@emotion/use-insertion-effect-with-fallbacks": ^1.0.1
- "@emotion/utils": ^1.2.1
- "@emotion/weak-memoize": ^0.3.1
- hoist-non-react-statics: ^3.3.1
- peerDependencies:
- react: ">=16.8.0"
- peerDependenciesMeta:
- "@types/react":
- optional: true
- checksum: aec3c36650f5f0d3d4445ff44d73dd88712b1609645b6af3e6d08049cfbc51f1785fe13dea1a1d4ab1b0800d68f2339ab11e459687180362b1ef98863155aae5
- languageName: node
- linkType: hard
-
"@emotion/serialize@npm:^1.0.2, @emotion/serialize@npm:^1.1.2":
version: 1.1.2
resolution: "@emotion/serialize@npm:1.1.2"
@@ -2799,7 +2778,7 @@ __metadata:
languageName: node
linkType: hard
-"@emotion/use-insertion-effect-with-fallbacks@npm:^1.0.0, @emotion/use-insertion-effect-with-fallbacks@npm:^1.0.1":
+"@emotion/use-insertion-effect-with-fallbacks@npm:^1.0.0":
version: 1.0.1
resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.0.1"
peerDependencies:
@@ -11327,6 +11306,16 @@ __metadata:
languageName: node
linkType: hard
+"array-buffer-byte-length@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "array-buffer-byte-length@npm:1.0.1"
+ dependencies:
+ call-bind: ^1.0.5
+ is-array-buffer: ^3.0.4
+ checksum: 53524e08f40867f6a9f35318fafe467c32e45e9c682ba67b11943e167344d2febc0f6977a17e699b05699e805c3e8f073d876f8bbf1b559ed494ad2cd0fae09e
+ languageName: node
+ linkType: hard
+
"array-differ@npm:^3.0.0":
version: 3.0.0
resolution: "array-differ@npm:3.0.0"
@@ -11361,6 +11350,20 @@ __metadata:
languageName: node
linkType: hard
+"array-includes@npm:^3.1.8":
+ version: 3.1.8
+ resolution: "array-includes@npm:3.1.8"
+ dependencies:
+ call-bind: ^1.0.7
+ define-properties: ^1.2.1
+ es-abstract: ^1.23.2
+ es-object-atoms: ^1.0.0
+ get-intrinsic: ^1.2.4
+ is-string: ^1.0.7
+ checksum: eb39ba5530f64e4d8acab39297c11c1c5be2a4ea188ab2b34aba5fb7224d918f77717a9d57a3e2900caaa8440e59431bdaf5c974d5212ef65d97f132e38e2d91
+ languageName: node
+ linkType: hard
+
"array-union@npm:^2.1.0":
version: 2.1.0
resolution: "array-union@npm:2.1.0"
@@ -11375,6 +11378,20 @@ __metadata:
languageName: node
linkType: hard
+"array.prototype.findlast@npm:^1.2.5":
+ version: 1.2.5
+ resolution: "array.prototype.findlast@npm:1.2.5"
+ dependencies:
+ call-bind: ^1.0.7
+ define-properties: ^1.2.1
+ es-abstract: ^1.23.2
+ es-errors: ^1.3.0
+ es-object-atoms: ^1.0.0
+ es-shim-unscopables: ^1.0.2
+ checksum: 83ce4ad95bae07f136d316f5a7c3a5b911ac3296c3476abe60225bc4a17938bf37541972fcc37dd5adbc99cbb9c928c70bbbfc1c1ce549d41a415144030bb446
+ languageName: node
+ linkType: hard
+
"array.prototype.findlastindex@npm:^1.2.3":
version: 1.2.3
resolution: "array.prototype.findlastindex@npm:1.2.3"
@@ -11438,6 +11455,18 @@ __metadata:
languageName: node
linkType: hard
+"array.prototype.toreversed@npm:^1.1.2":
+ version: 1.1.2
+ resolution: "array.prototype.toreversed@npm:1.1.2"
+ dependencies:
+ call-bind: ^1.0.2
+ define-properties: ^1.2.0
+ es-abstract: ^1.22.1
+ es-shim-unscopables: ^1.0.0
+ checksum: 58598193426282155297bedf950dc8d464624a0d81659822fb73124286688644cb7e0e4927a07f3ab2daaeb6617b647736cc3a5e6ca7ade5bb8e573b284e6240
+ languageName: node
+ linkType: hard
+
"array.prototype.tosorted@npm:^1.1.1":
version: 1.1.2
resolution: "array.prototype.tosorted@npm:1.1.2"
@@ -11451,6 +11480,19 @@ __metadata:
languageName: node
linkType: hard
+"array.prototype.tosorted@npm:^1.1.4":
+ version: 1.1.4
+ resolution: "array.prototype.tosorted@npm:1.1.4"
+ dependencies:
+ call-bind: ^1.0.7
+ define-properties: ^1.2.1
+ es-abstract: ^1.23.3
+ es-errors: ^1.3.0
+ es-shim-unscopables: ^1.0.2
+ checksum: e4142d6f556bcbb4f393c02e7dbaea9af8f620c040450c2be137c9cbbd1a17f216b9c688c5f2c08fbb038ab83f55993fa6efdd9a05881d84693c7bcb5422127a
+ languageName: node
+ linkType: hard
+
"arraybuffer.prototype.slice@npm:^1.0.2":
version: 1.0.2
resolution: "arraybuffer.prototype.slice@npm:1.0.2"
@@ -11466,6 +11508,22 @@ __metadata:
languageName: node
linkType: hard
+"arraybuffer.prototype.slice@npm:^1.0.3":
+ version: 1.0.3
+ resolution: "arraybuffer.prototype.slice@npm:1.0.3"
+ dependencies:
+ array-buffer-byte-length: ^1.0.1
+ call-bind: ^1.0.5
+ define-properties: ^1.2.1
+ es-abstract: ^1.22.3
+ es-errors: ^1.2.1
+ get-intrinsic: ^1.2.3
+ is-array-buffer: ^3.0.4
+ is-shared-array-buffer: ^1.0.2
+ checksum: 352259cba534dcdd969c92ab002efd2ba5025b2e3b9bead3973150edbdf0696c629d7f4b3f061c5931511e8207bdc2306da614703c820b45dabce39e3daf7e3e
+ languageName: node
+ linkType: hard
+
"arrify@npm:^1.0.1":
version: 1.0.1
resolution: "arrify@npm:1.0.1"
@@ -11646,6 +11704,15 @@ __metadata:
languageName: node
linkType: hard
+"available-typed-arrays@npm:^1.0.7":
+ version: 1.0.7
+ resolution: "available-typed-arrays@npm:1.0.7"
+ dependencies:
+ possible-typed-array-names: ^1.0.0
+ checksum: 1aa3ffbfe6578276996de660848b6e95669d9a95ad149e3dd0c0cda77db6ee1dbd9d1dd723b65b6d277b882dd0c4b91a654ae9d3cf9e1254b7e93e4908d78fd3
+ languageName: node
+ linkType: hard
+
"axe-core@npm:=4.7.0":
version: 4.7.0
resolution: "axe-core@npm:4.7.0"
@@ -12733,6 +12800,19 @@ __metadata:
languageName: node
linkType: hard
+"call-bind@npm:^1.0.6, call-bind@npm:^1.0.7":
+ version: 1.0.7
+ resolution: "call-bind@npm:1.0.7"
+ dependencies:
+ es-define-property: ^1.0.0
+ es-errors: ^1.3.0
+ function-bind: ^1.1.2
+ get-intrinsic: ^1.2.4
+ set-function-length: ^1.2.1
+ checksum: 295c0c62b90dd6522e6db3b0ab1ce26bdf9e7404215bda13cfee25b626b5ff1a7761324d58d38b1ef1607fc65aca2d06e44d2e18d0dfc6c14b465b00d8660029
+ languageName: node
+ linkType: hard
+
"caller-callsite@npm:^2.0.0":
version: 2.0.0
resolution: "caller-callsite@npm:2.0.0"
@@ -14297,6 +14377,39 @@ __metadata:
languageName: node
linkType: hard
+"data-view-buffer@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "data-view-buffer@npm:1.0.1"
+ dependencies:
+ call-bind: ^1.0.6
+ es-errors: ^1.3.0
+ is-data-view: ^1.0.1
+ checksum: ce24348f3c6231223b216da92e7e6a57a12b4af81a23f27eff8feabdf06acfb16c00639c8b705ca4d167f761cfc756e27e5f065d0a1f840c10b907fdaf8b988c
+ languageName: node
+ linkType: hard
+
+"data-view-byte-length@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "data-view-byte-length@npm:1.0.1"
+ dependencies:
+ call-bind: ^1.0.7
+ es-errors: ^1.3.0
+ is-data-view: ^1.0.1
+ checksum: dbb3200edcb7c1ef0d68979834f81d64fd8cab2f7691b3a4c6b97e67f22182f3ec2c8602efd7b76997b55af6ff8bce485829c1feda4fa2165a6b71fb7baa4269
+ languageName: node
+ linkType: hard
+
+"data-view-byte-offset@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "data-view-byte-offset@npm:1.0.0"
+ dependencies:
+ call-bind: ^1.0.6
+ es-errors: ^1.3.0
+ is-data-view: ^1.0.1
+ checksum: 7f0bf8720b7414ca719eedf1846aeec392f2054d7af707c5dc9a753cc77eb8625f067fa901e0b5127e831f9da9056138d894b9c2be79c27a21f6db5824f009c2
+ languageName: node
+ linkType: hard
+
"date-fns@npm:^2.29.1, date-fns@npm:^2.30.0":
version: 2.30.0
resolution: "date-fns@npm:2.30.0"
@@ -14496,6 +14609,17 @@ __metadata:
languageName: node
linkType: hard
+"define-data-property@npm:^1.1.4":
+ version: 1.1.4
+ resolution: "define-data-property@npm:1.1.4"
+ dependencies:
+ es-define-property: ^1.0.0
+ es-errors: ^1.3.0
+ gopd: ^1.0.1
+ checksum: 8068ee6cab694d409ac25936eb861eea704b7763f7f342adbdfe337fc27c78d7ae0eff2364b2917b58c508d723c7a074326d068eef2e45c4edcd85cf94d0313b
+ languageName: node
+ linkType: hard
+
"define-lazy-prop@npm:^2.0.0":
version: 2.0.0
resolution: "define-lazy-prop@npm:2.0.0"
@@ -15238,6 +15362,60 @@ __metadata:
languageName: node
linkType: hard
+"es-abstract@npm:^1.17.5, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3":
+ version: 1.23.3
+ resolution: "es-abstract@npm:1.23.3"
+ dependencies:
+ array-buffer-byte-length: ^1.0.1
+ arraybuffer.prototype.slice: ^1.0.3
+ available-typed-arrays: ^1.0.7
+ call-bind: ^1.0.7
+ data-view-buffer: ^1.0.1
+ data-view-byte-length: ^1.0.1
+ data-view-byte-offset: ^1.0.0
+ es-define-property: ^1.0.0
+ es-errors: ^1.3.0
+ es-object-atoms: ^1.0.0
+ es-set-tostringtag: ^2.0.3
+ es-to-primitive: ^1.2.1
+ function.prototype.name: ^1.1.6
+ get-intrinsic: ^1.2.4
+ get-symbol-description: ^1.0.2
+ globalthis: ^1.0.3
+ gopd: ^1.0.1
+ has-property-descriptors: ^1.0.2
+ has-proto: ^1.0.3
+ has-symbols: ^1.0.3
+ hasown: ^2.0.2
+ internal-slot: ^1.0.7
+ is-array-buffer: ^3.0.4
+ is-callable: ^1.2.7
+ is-data-view: ^1.0.1
+ is-negative-zero: ^2.0.3
+ is-regex: ^1.1.4
+ is-shared-array-buffer: ^1.0.3
+ is-string: ^1.0.7
+ is-typed-array: ^1.1.13
+ is-weakref: ^1.0.2
+ object-inspect: ^1.13.1
+ object-keys: ^1.1.1
+ object.assign: ^4.1.5
+ regexp.prototype.flags: ^1.5.2
+ safe-array-concat: ^1.1.2
+ safe-regex-test: ^1.0.3
+ string.prototype.trim: ^1.2.9
+ string.prototype.trimend: ^1.0.8
+ string.prototype.trimstart: ^1.0.8
+ typed-array-buffer: ^1.0.2
+ typed-array-byte-length: ^1.0.1
+ typed-array-byte-offset: ^1.0.2
+ typed-array-length: ^1.0.6
+ unbox-primitive: ^1.0.2
+ which-typed-array: ^1.1.15
+ checksum: f840cf161224252512f9527306b57117192696571e07920f777cb893454e32999206198b4f075516112af6459daca282826d1735c450528470356d09eff3a9ae
+ languageName: node
+ linkType: hard
+
"es-abstract@npm:^1.22.1":
version: 1.22.3
resolution: "es-abstract@npm:1.22.3"
@@ -15292,6 +15470,22 @@ __metadata:
languageName: node
linkType: hard
+"es-define-property@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "es-define-property@npm:1.0.0"
+ dependencies:
+ get-intrinsic: ^1.2.4
+ checksum: f66ece0a887b6dca71848fa71f70461357c0e4e7249696f81bad0a1f347eed7b31262af4a29f5d726dc026426f085483b6b90301855e647aa8e21936f07293c6
+ languageName: node
+ linkType: hard
+
+"es-errors@npm:^1.2.1, es-errors@npm:^1.3.0":
+ version: 1.3.0
+ resolution: "es-errors@npm:1.3.0"
+ checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5
+ languageName: node
+ linkType: hard
+
"es-get-iterator@npm:^1.0.2, es-get-iterator@npm:^1.1.3":
version: 1.1.3
resolution: "es-get-iterator@npm:1.1.3"
@@ -15331,6 +15525,28 @@ __metadata:
languageName: node
linkType: hard
+"es-iterator-helpers@npm:^1.0.19":
+ version: 1.0.19
+ resolution: "es-iterator-helpers@npm:1.0.19"
+ dependencies:
+ call-bind: ^1.0.7
+ define-properties: ^1.2.1
+ es-abstract: ^1.23.3
+ es-errors: ^1.3.0
+ es-set-tostringtag: ^2.0.3
+ function-bind: ^1.1.2
+ get-intrinsic: ^1.2.4
+ globalthis: ^1.0.3
+ has-property-descriptors: ^1.0.2
+ has-proto: ^1.0.3
+ has-symbols: ^1.0.3
+ internal-slot: ^1.0.7
+ iterator.prototype: ^1.1.2
+ safe-array-concat: ^1.1.2
+ checksum: 7ae112b88359fbaf4b9d7d1d1358ae57c5138768c57ba3a8fb930393662653b0512bfd7917c15890d1471577fb012fee8b73b4465e59b331739e6ee94f961683
+ languageName: node
+ linkType: hard
+
"es-module-lexer@npm:^1.0.5, es-module-lexer@npm:^1.2.1":
version: 1.4.1
resolution: "es-module-lexer@npm:1.4.1"
@@ -15345,6 +15561,15 @@ __metadata:
languageName: node
linkType: hard
+"es-object-atoms@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "es-object-atoms@npm:1.0.0"
+ dependencies:
+ es-errors: ^1.3.0
+ checksum: 26f0ff78ab93b63394e8403c353842b2272836968de4eafe97656adfb8a7c84b9099bf0fe96ed58f4a4cddc860f6e34c77f91649a58a5daa4a9c40b902744e3c
+ languageName: node
+ linkType: hard
+
"es-set-tostringtag@npm:^2.0.1":
version: 2.0.2
resolution: "es-set-tostringtag@npm:2.0.2"
@@ -15356,7 +15581,18 @@ __metadata:
languageName: node
linkType: hard
-"es-shim-unscopables@npm:^1.0.0":
+"es-set-tostringtag@npm:^2.0.3":
+ version: 2.0.3
+ resolution: "es-set-tostringtag@npm:2.0.3"
+ dependencies:
+ get-intrinsic: ^1.2.4
+ has-tostringtag: ^1.0.2
+ hasown: ^2.0.1
+ checksum: 7227fa48a41c0ce83e0377b11130d324ac797390688135b8da5c28994c0165be8b252e15cd1de41e1325e5a5412511586960213e88f9ab4a5e7d028895db5129
+ languageName: node
+ linkType: hard
+
+"es-shim-unscopables@npm:^1.0.0, es-shim-unscopables@npm:^1.0.2":
version: 1.0.2
resolution: "es-shim-unscopables@npm:1.0.2"
dependencies:
@@ -15985,6 +16221,35 @@ __metadata:
languageName: node
linkType: hard
+"eslint-plugin-react@npm:^7.34.4":
+ version: 7.34.4
+ resolution: "eslint-plugin-react@npm:7.34.4"
+ dependencies:
+ array-includes: ^3.1.8
+ array.prototype.findlast: ^1.2.5
+ array.prototype.flatmap: ^1.3.2
+ array.prototype.toreversed: ^1.1.2
+ array.prototype.tosorted: ^1.1.4
+ doctrine: ^2.1.0
+ es-iterator-helpers: ^1.0.19
+ estraverse: ^5.3.0
+ hasown: ^2.0.2
+ jsx-ast-utils: ^2.4.1 || ^3.0.0
+ minimatch: ^3.1.2
+ object.entries: ^1.1.8
+ object.fromentries: ^2.0.8
+ object.values: ^1.2.0
+ prop-types: ^15.8.1
+ resolve: ^2.0.0-next.5
+ semver: ^6.3.1
+ string.prototype.matchall: ^4.0.11
+ string.prototype.repeat: ^1.0.0
+ peerDependencies:
+ eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
+ checksum: 7bb7bdbec4ec628e1f139edbfa25f11ef6db8c92e9970866838bcb6d4dea471519dc0e5a0b3bd763afd1a8715fd54fe7f5317387580ff1e92eeb87eeba13bacf
+ languageName: node
+ linkType: hard
+
"eslint-plugin-storybook@npm:^0.6.12":
version: 0.6.15
resolution: "eslint-plugin-storybook@npm:0.6.15"
@@ -17589,6 +17854,19 @@ __metadata:
languageName: node
linkType: hard
+"get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4":
+ version: 1.2.4
+ resolution: "get-intrinsic@npm:1.2.4"
+ dependencies:
+ es-errors: ^1.3.0
+ function-bind: ^1.1.2
+ has-proto: ^1.0.1
+ has-symbols: ^1.0.3
+ hasown: ^2.0.0
+ checksum: 414e3cdf2c203d1b9d7d33111df746a4512a1aa622770b361dadddf8ed0b5aeb26c560f49ca077e24bfafb0acb55ca908d1f709216ccba33ffc548ec8a79a951
+ languageName: node
+ linkType: hard
+
"get-nonce@npm:^1.0.0":
version: 1.0.1
resolution: "get-nonce@npm:1.0.1"
@@ -17685,6 +17963,17 @@ __metadata:
languageName: node
linkType: hard
+"get-symbol-description@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "get-symbol-description@npm:1.0.2"
+ dependencies:
+ call-bind: ^1.0.5
+ es-errors: ^1.3.0
+ get-intrinsic: ^1.2.4
+ checksum: e1cb53bc211f9dbe9691a4f97a46837a553c4e7caadd0488dc24ac694db8a390b93edd412b48dcdd0b4bbb4c595de1709effc75fc87c0839deedc6968f5bd973
+ languageName: node
+ linkType: hard
+
"get-value@npm:^2.0.3, get-value@npm:^2.0.6":
version: 2.0.6
resolution: "get-value@npm:2.0.6"
@@ -18131,6 +18420,15 @@ __metadata:
languageName: node
linkType: hard
+"has-property-descriptors@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "has-property-descriptors@npm:1.0.2"
+ dependencies:
+ es-define-property: ^1.0.0
+ checksum: fcbb246ea2838058be39887935231c6d5788babed499d0e9d0cc5737494c48aba4fe17ba1449e0d0fbbb1e36175442faa37f9c427ae357d6ccb1d895fbcd3de3
+ languageName: node
+ linkType: hard
+
"has-proto@npm:^1.0.1":
version: 1.0.1
resolution: "has-proto@npm:1.0.1"
@@ -18138,6 +18436,13 @@ __metadata:
languageName: node
linkType: hard
+"has-proto@npm:^1.0.3":
+ version: 1.0.3
+ resolution: "has-proto@npm:1.0.3"
+ checksum: fe7c3d50b33f50f3933a04413ed1f69441d21d2d2944f81036276d30635cad9279f6b43bc8f32036c31ebdfcf6e731150f46c1907ad90c669ffe9b066c3ba5c4
+ languageName: node
+ linkType: hard
+
"has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3":
version: 1.0.3
resolution: "has-symbols@npm:1.0.3"
@@ -18154,6 +18459,15 @@ __metadata:
languageName: node
linkType: hard
+"has-tostringtag@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "has-tostringtag@npm:1.0.2"
+ dependencies:
+ has-symbols: ^1.0.3
+ checksum: 999d60bb753ad714356b2c6c87b7fb74f32463b8426e159397da4bde5bca7e598ab1073f4d8d4deafac297f2eb311484cd177af242776bf05f0d11565680468d
+ languageName: node
+ linkType: hard
+
"has-unicode@npm:2.0.1, has-unicode@npm:^2.0.1":
version: 2.0.1
resolution: "has-unicode@npm:2.0.1"
@@ -18230,6 +18544,15 @@ __metadata:
languageName: node
linkType: hard
+"hasown@npm:^2.0.1, hasown@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "hasown@npm:2.0.2"
+ dependencies:
+ function-bind: ^1.1.2
+ checksum: e8516f776a15149ca6c6ed2ae3110c417a00b62260e222590e54aa367cbcd6ed99122020b37b7fbdf05748df57b265e70095d7bf35a47660587619b15ffb93db
+ languageName: node
+ linkType: hard
+
"he@npm:^1.2.0":
version: 1.2.0
resolution: "he@npm:1.2.0"
@@ -18970,6 +19293,17 @@ __metadata:
languageName: node
linkType: hard
+"internal-slot@npm:^1.0.7":
+ version: 1.0.7
+ resolution: "internal-slot@npm:1.0.7"
+ dependencies:
+ es-errors: ^1.3.0
+ hasown: ^2.0.0
+ side-channel: ^1.0.4
+ checksum: cadc5eea5d7d9bc2342e93aae9f31f04c196afebb11bde97448327049f492cd7081e18623ae71388aac9cd237b692ca3a105be9c68ac39c1dec679d7409e33eb
+ languageName: node
+ linkType: hard
+
"interpret@npm:^2.2.0":
version: 2.2.0
resolution: "interpret@npm:2.2.0"
@@ -19058,6 +19392,16 @@ __metadata:
languageName: node
linkType: hard
+"is-array-buffer@npm:^3.0.4":
+ version: 3.0.4
+ resolution: "is-array-buffer@npm:3.0.4"
+ dependencies:
+ call-bind: ^1.0.2
+ get-intrinsic: ^1.2.1
+ checksum: e4e3e6ef0ff2239e75371d221f74bc3c26a03564a22efb39f6bb02609b598917ddeecef4e8c877df2a25888f247a98198959842a5e73236bc7f22cabdf6351a7
+ languageName: node
+ linkType: hard
+
"is-arrayish@npm:^0.2.1":
version: 0.2.1
resolution: "is-arrayish@npm:0.2.1"
@@ -19181,6 +19525,15 @@ __metadata:
languageName: node
linkType: hard
+"is-data-view@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "is-data-view@npm:1.0.1"
+ dependencies:
+ is-typed-array: ^1.1.13
+ checksum: 4ba4562ac2b2ec005fefe48269d6bd0152785458cd253c746154ffb8a8ab506a29d0cfb3b74af87513843776a88e4981ae25c89457bf640a33748eab1a7216b5
+ languageName: node
+ linkType: hard
+
"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5":
version: 1.0.5
resolution: "is-date-object@npm:1.0.5"
@@ -19421,6 +19774,13 @@ __metadata:
languageName: node
linkType: hard
+"is-negative-zero@npm:^2.0.3":
+ version: 2.0.3
+ resolution: "is-negative-zero@npm:2.0.3"
+ checksum: c1e6b23d2070c0539d7b36022d5a94407132411d01aba39ec549af824231f3804b1aea90b5e4e58e807a65d23ceb538ed6e355ce76b267bdd86edb757ffcbdcd
+ languageName: node
+ linkType: hard
+
"is-number-object@npm:^1.0.4":
version: 1.0.7
resolution: "is-number-object@npm:1.0.7"
@@ -19567,6 +19927,15 @@ __metadata:
languageName: node
linkType: hard
+"is-shared-array-buffer@npm:^1.0.3":
+ version: 1.0.3
+ resolution: "is-shared-array-buffer@npm:1.0.3"
+ dependencies:
+ call-bind: ^1.0.7
+ checksum: a4fff602c309e64ccaa83b859255a43bb011145a42d3f56f67d9268b55bc7e6d98a5981a1d834186ad3105d6739d21547083fe7259c76c0468483fc538e716d8
+ languageName: node
+ linkType: hard
+
"is-ssh@npm:^1.4.0":
version: 1.4.0
resolution: "is-ssh@npm:1.4.0"
@@ -19642,6 +20011,15 @@ __metadata:
languageName: node
linkType: hard
+"is-typed-array@npm:^1.1.13":
+ version: 1.1.13
+ resolution: "is-typed-array@npm:1.1.13"
+ dependencies:
+ which-typed-array: ^1.1.14
+ checksum: 150f9ada183a61554c91e1c4290086d2c100b0dff45f60b028519be72a8db964da403c48760723bf5253979b8dffe7b544246e0e5351dcd05c5fdb1dcc1dc0f0
+ languageName: node
+ linkType: hard
+
"is-typedarray@npm:^1.0.0":
version: 1.0.0
resolution: "is-typedarray@npm:1.0.0"
@@ -20963,19 +21341,14 @@ __metadata:
"@dnd-kit/core": ^6.1.0
"@dnd-kit/sortable": ^8.0.0
"@embeddedchat/ui-elements": "workspace:^"
- "@emotion/babel-plugin": ^11.11.0
- "@types/node": ^20.11.19
- "@types/react": ^18.2.55
- "@types/react-dom": ^18.2.19
- "@typescript-eslint/eslint-plugin": ^6.21.0
- "@typescript-eslint/parser": ^6.21.0
+ "@emotion/babel-preset-css-prop": ^11.11.0
"@vitejs/plugin-react": ^4.2.1
eslint: ^8.56.0
+ eslint-plugin-react: ^7.34.4
eslint-plugin-react-hooks: ^4.6.0
eslint-plugin-react-refresh: ^0.4.5
react: ^18.2.0
react-dom: ^18.2.0
- typescript: ^5.2.2
vite: ^5.1.0
languageName: unknown
linkType: soft
@@ -24030,6 +24403,18 @@ __metadata:
languageName: node
linkType: hard
+"object.assign@npm:^4.1.5":
+ version: 4.1.5
+ resolution: "object.assign@npm:4.1.5"
+ dependencies:
+ call-bind: ^1.0.5
+ define-properties: ^1.2.1
+ has-symbols: ^1.0.3
+ object-keys: ^1.1.1
+ checksum: f9aeac0541661370a1fc86e6a8065eb1668d3e771f7dbb33ee54578201336c057b21ee61207a186dd42db0c62201d91aac703d20d12a79fc79c353eed44d4e25
+ languageName: node
+ linkType: hard
+
"object.entries@npm:^1.1.0, object.entries@npm:^1.1.5, object.entries@npm:^1.1.6, object.entries@npm:^1.1.7":
version: 1.1.7
resolution: "object.entries@npm:1.1.7"
@@ -24041,6 +24426,17 @@ __metadata:
languageName: node
linkType: hard
+"object.entries@npm:^1.1.8":
+ version: 1.1.8
+ resolution: "object.entries@npm:1.1.8"
+ dependencies:
+ call-bind: ^1.0.7
+ define-properties: ^1.2.1
+ es-object-atoms: ^1.0.0
+ checksum: 5314877cb637ef3437a30bba61d9bacdb3ce74bf73ac101518be0633c37840c8cc67407edb341f766e8093b3d7516d5c3358f25adfee4a2c697c0ec4c8491907
+ languageName: node
+ linkType: hard
+
"object.fromentries@npm:^2.0.0 || ^1.0.0, object.fromentries@npm:^2.0.6, object.fromentries@npm:^2.0.7":
version: 2.0.7
resolution: "object.fromentries@npm:2.0.7"
@@ -24052,6 +24448,18 @@ __metadata:
languageName: node
linkType: hard
+"object.fromentries@npm:^2.0.8":
+ version: 2.0.8
+ resolution: "object.fromentries@npm:2.0.8"
+ dependencies:
+ call-bind: ^1.0.7
+ define-properties: ^1.2.1
+ es-abstract: ^1.23.2
+ es-object-atoms: ^1.0.0
+ checksum: 29b2207a2db2782d7ced83f93b3ff5d425f901945f3665ffda1821e30a7253cd1fd6b891a64279976098137ddfa883d748787a6fea53ecdb51f8df8b8cec0ae1
+ languageName: node
+ linkType: hard
+
"object.getownpropertydescriptors@npm:^2.0.3, object.getownpropertydescriptors@npm:^2.1.2":
version: 2.1.7
resolution: "object.getownpropertydescriptors@npm:2.1.7"
@@ -24107,6 +24515,17 @@ __metadata:
languageName: node
linkType: hard
+"object.values@npm:^1.2.0":
+ version: 1.2.0
+ resolution: "object.values@npm:1.2.0"
+ dependencies:
+ call-bind: ^1.0.7
+ define-properties: ^1.2.1
+ es-object-atoms: ^1.0.0
+ checksum: 51fef456c2a544275cb1766897f34ded968b22adfc13ba13b5e4815fdaf4304a90d42a3aee114b1f1ede048a4890381d47a5594d84296f2767c6a0364b9da8fa
+ languageName: node
+ linkType: hard
+
"objectorarray@npm:^1.0.5":
version: 1.0.5
resolution: "objectorarray@npm:1.0.5"
@@ -25110,6 +25529,13 @@ __metadata:
languageName: node
linkType: hard
+"possible-typed-array-names@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "possible-typed-array-names@npm:1.0.0"
+ checksum: b32d403ece71e042385cc7856385cecf1cd8e144fa74d2f1de40d1e16035dba097bc189715925e79b67bdd1472796ff168d3a90d296356c9c94d272d5b95f3ae
+ languageName: node
+ linkType: hard
+
"postcss-calc@npm:^8.2.3":
version: 8.2.4
resolution: "postcss-calc@npm:8.2.4"
@@ -26891,6 +27317,18 @@ __metadata:
languageName: node
linkType: hard
+"regexp.prototype.flags@npm:^1.5.2":
+ version: 1.5.2
+ resolution: "regexp.prototype.flags@npm:1.5.2"
+ dependencies:
+ call-bind: ^1.0.6
+ define-properties: ^1.2.1
+ es-errors: ^1.3.0
+ set-function-name: ^2.0.1
+ checksum: d7f333667d5c564e2d7a97c56c3075d64c722c9bb51b2b4df6822b2e8096d623a5e63088fb4c83df919b6951ef8113841de8b47de7224872fa6838bc5d8a7d64
+ languageName: node
+ linkType: hard
+
"regexpu-core@npm:^5.3.1":
version: 5.3.2
resolution: "regexpu-core@npm:5.3.2"
@@ -27118,7 +27556,7 @@ __metadata:
languageName: node
linkType: hard
-"resolve@npm:^2.0.0-next.4":
+"resolve@npm:^2.0.0-next.4, resolve@npm:^2.0.0-next.5":
version: 2.0.0-next.5
resolution: "resolve@npm:2.0.0-next.5"
dependencies:
@@ -27153,7 +27591,7 @@ __metadata:
languageName: node
linkType: hard
-"resolve@patch:resolve@^2.0.0-next.4#~builtin":
+"resolve@patch:resolve@^2.0.0-next.4#~builtin, resolve@patch:resolve@^2.0.0-next.5#~builtin":
version: 2.0.0-next.5
resolution: "resolve@patch:resolve@npm%3A2.0.0-next.5#~builtin::version=2.0.0-next.5&hash=c3c19d"
dependencies:
@@ -27584,6 +28022,18 @@ __metadata:
languageName: node
linkType: hard
+"safe-array-concat@npm:^1.1.2":
+ version: 1.1.2
+ resolution: "safe-array-concat@npm:1.1.2"
+ dependencies:
+ call-bind: ^1.0.7
+ get-intrinsic: ^1.2.4
+ has-symbols: ^1.0.3
+ isarray: ^2.0.5
+ checksum: a3b259694754ddfb73ae0663829e396977b99ff21cbe8607f35a469655656da8e271753497e59da8a7575baa94d2e684bea3e10ddd74ba046c0c9b4418ffa0c4
+ languageName: node
+ linkType: hard
+
"safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1":
version: 5.1.2
resolution: "safe-buffer@npm:5.1.2"
@@ -27623,6 +28073,17 @@ __metadata:
languageName: node
linkType: hard
+"safe-regex-test@npm:^1.0.3":
+ version: 1.0.3
+ resolution: "safe-regex-test@npm:1.0.3"
+ dependencies:
+ call-bind: ^1.0.6
+ es-errors: ^1.3.0
+ is-regex: ^1.1.4
+ checksum: 6c7d392ff1ae7a3ae85273450ed02d1d131f1d2c76e177d6b03eb88e6df8fa062639070e7d311802c1615f351f18dc58f9454501c58e28d5ffd9b8f502ba6489
+ languageName: node
+ linkType: hard
+
"safe-regex@npm:^1.1.0":
version: 1.1.0
resolution: "safe-regex@npm:1.1.0"
@@ -27937,6 +28398,20 @@ __metadata:
languageName: node
linkType: hard
+"set-function-length@npm:^1.2.1":
+ version: 1.2.2
+ resolution: "set-function-length@npm:1.2.2"
+ dependencies:
+ define-data-property: ^1.1.4
+ es-errors: ^1.3.0
+ function-bind: ^1.1.2
+ get-intrinsic: ^1.2.4
+ gopd: ^1.0.1
+ has-property-descriptors: ^1.0.2
+ checksum: a8248bdacdf84cb0fab4637774d9fb3c7a8e6089866d04c817583ff48e14149c87044ce683d7f50759a8c50fb87c7a7e173535b06169c87ef76f5fb276dfff72
+ languageName: node
+ linkType: hard
+
"set-function-name@npm:^2.0.0, set-function-name@npm:^2.0.1":
version: 2.0.1
resolution: "set-function-name@npm:2.0.1"
@@ -27948,6 +28423,18 @@ __metadata:
languageName: node
linkType: hard
+"set-function-name@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "set-function-name@npm:2.0.2"
+ dependencies:
+ define-data-property: ^1.1.4
+ es-errors: ^1.3.0
+ functions-have-names: ^1.2.3
+ has-property-descriptors: ^1.0.2
+ checksum: d6229a71527fd0404399fc6227e0ff0652800362510822a291925c9d7b48a1ca1a468b11b281471c34cd5a2da0db4f5d7ff315a61d26655e77f6e971e6d0c80f
+ languageName: node
+ linkType: hard
+
"set-value@npm:^2.0.0, set-value@npm:^2.0.1":
version: 2.0.1
resolution: "set-value@npm:2.0.1"
@@ -28059,6 +28546,18 @@ __metadata:
languageName: node
linkType: hard
+"side-channel@npm:^1.0.6":
+ version: 1.0.6
+ resolution: "side-channel@npm:1.0.6"
+ dependencies:
+ call-bind: ^1.0.7
+ es-errors: ^1.3.0
+ get-intrinsic: ^1.2.4
+ object-inspect: ^1.13.1
+ checksum: bfc1afc1827d712271453e91b7cd3878ac0efd767495fd4e594c4c2afaa7963b7b510e249572bfd54b0527e66e4a12b61b80c061389e129755f34c493aad9b97
+ languageName: node
+ linkType: hard
+
"signal-exit@npm:3.0.7, signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7":
version: 3.0.7
resolution: "signal-exit@npm:3.0.7"
@@ -28756,6 +29255,26 @@ __metadata:
languageName: node
linkType: hard
+"string.prototype.matchall@npm:^4.0.11":
+ version: 4.0.11
+ resolution: "string.prototype.matchall@npm:4.0.11"
+ dependencies:
+ call-bind: ^1.0.7
+ define-properties: ^1.2.1
+ es-abstract: ^1.23.2
+ es-errors: ^1.3.0
+ es-object-atoms: ^1.0.0
+ get-intrinsic: ^1.2.4
+ gopd: ^1.0.1
+ has-symbols: ^1.0.3
+ internal-slot: ^1.0.7
+ regexp.prototype.flags: ^1.5.2
+ set-function-name: ^2.0.2
+ side-channel: ^1.0.6
+ checksum: 6ac6566ed065c0c8489c91156078ca077db8ff64d683fda97ae652d00c52dfa5f39aaab0a710d8243031a857fd2c7c511e38b45524796764d25472d10d7075ae
+ languageName: node
+ linkType: hard
+
"string.prototype.padend@npm:^3.0.0":
version: 3.1.5
resolution: "string.prototype.padend@npm:3.1.5"
@@ -28778,6 +29297,16 @@ __metadata:
languageName: node
linkType: hard
+"string.prototype.repeat@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "string.prototype.repeat@npm:1.0.0"
+ dependencies:
+ define-properties: ^1.1.3
+ es-abstract: ^1.17.5
+ checksum: 95dfc514ed7f328d80a066dabbfbbb1615c3e51490351085409db2eb7cbfed7ea29fdadaf277647fbf9f4a1e10e6dd9e95e78c0fd2c4e6bb6723ea6e59401004
+ languageName: node
+ linkType: hard
+
"string.prototype.trim@npm:^1.2.8":
version: 1.2.8
resolution: "string.prototype.trim@npm:1.2.8"
@@ -28789,6 +29318,18 @@ __metadata:
languageName: node
linkType: hard
+"string.prototype.trim@npm:^1.2.9":
+ version: 1.2.9
+ resolution: "string.prototype.trim@npm:1.2.9"
+ dependencies:
+ call-bind: ^1.0.7
+ define-properties: ^1.2.1
+ es-abstract: ^1.23.0
+ es-object-atoms: ^1.0.0
+ checksum: ea2df6ec1e914c9d4e2dc856fa08228e8b1be59b59e50b17578c94a66a176888f417264bb763d4aac638ad3b3dad56e7a03d9317086a178078d131aa293ba193
+ languageName: node
+ linkType: hard
+
"string.prototype.trimend@npm:^1.0.7":
version: 1.0.7
resolution: "string.prototype.trimend@npm:1.0.7"
@@ -28800,6 +29341,17 @@ __metadata:
languageName: node
linkType: hard
+"string.prototype.trimend@npm:^1.0.8":
+ version: 1.0.8
+ resolution: "string.prototype.trimend@npm:1.0.8"
+ dependencies:
+ call-bind: ^1.0.7
+ define-properties: ^1.2.1
+ es-object-atoms: ^1.0.0
+ checksum: cc3bd2de08d8968a28787deba9a3cb3f17ca5f9f770c91e7e8fa3e7d47f079bad70fadce16f05dda9f261788be2c6e84a942f618c3bed31e42abc5c1084f8dfd
+ languageName: node
+ linkType: hard
+
"string.prototype.trimstart@npm:^1.0.7":
version: 1.0.7
resolution: "string.prototype.trimstart@npm:1.0.7"
@@ -28811,6 +29363,17 @@ __metadata:
languageName: node
linkType: hard
+"string.prototype.trimstart@npm:^1.0.8":
+ version: 1.0.8
+ resolution: "string.prototype.trimstart@npm:1.0.8"
+ dependencies:
+ call-bind: ^1.0.7
+ define-properties: ^1.2.1
+ es-object-atoms: ^1.0.0
+ checksum: df1007a7f580a49d692375d996521dc14fd103acda7f3034b3c558a60b82beeed3a64fa91e494e164581793a8ab0ae2f59578a49896a7af6583c1f20472bce96
+ languageName: node
+ linkType: hard
+
"string_decoder@npm:^1.0.0, string_decoder@npm:^1.1.1, string_decoder@npm:^1.3.0":
version: 1.3.0
resolution: "string_decoder@npm:1.3.0"
@@ -30009,6 +30572,17 @@ __metadata:
languageName: node
linkType: hard
+"typed-array-buffer@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "typed-array-buffer@npm:1.0.2"
+ dependencies:
+ call-bind: ^1.0.7
+ es-errors: ^1.3.0
+ is-typed-array: ^1.1.13
+ checksum: 02ffc185d29c6df07968272b15d5319a1610817916ec8d4cd670ded5d1efe72901541ff2202fcc622730d8a549c76e198a2f74e312eabbfb712ed907d45cbb0b
+ languageName: node
+ linkType: hard
+
"typed-array-byte-length@npm:^1.0.0":
version: 1.0.0
resolution: "typed-array-byte-length@npm:1.0.0"
@@ -30021,6 +30595,19 @@ __metadata:
languageName: node
linkType: hard
+"typed-array-byte-length@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "typed-array-byte-length@npm:1.0.1"
+ dependencies:
+ call-bind: ^1.0.7
+ for-each: ^0.3.3
+ gopd: ^1.0.1
+ has-proto: ^1.0.3
+ is-typed-array: ^1.1.13
+ checksum: f65e5ecd1cf76b1a2d0d6f631f3ea3cdb5e08da106c6703ffe687d583e49954d570cc80434816d3746e18be889ffe53c58bf3e538081ea4077c26a41055b216d
+ languageName: node
+ linkType: hard
+
"typed-array-byte-offset@npm:^1.0.0":
version: 1.0.0
resolution: "typed-array-byte-offset@npm:1.0.0"
@@ -30034,6 +30621,20 @@ __metadata:
languageName: node
linkType: hard
+"typed-array-byte-offset@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "typed-array-byte-offset@npm:1.0.2"
+ dependencies:
+ available-typed-arrays: ^1.0.7
+ call-bind: ^1.0.7
+ for-each: ^0.3.3
+ gopd: ^1.0.1
+ has-proto: ^1.0.3
+ is-typed-array: ^1.1.13
+ checksum: c8645c8794a621a0adcc142e0e2c57b1823bbfa4d590ad2c76b266aa3823895cf7afb9a893bf6685e18454ab1b0241e1a8d885a2d1340948efa4b56add4b5f67
+ languageName: node
+ linkType: hard
+
"typed-array-length@npm:^1.0.4":
version: 1.0.4
resolution: "typed-array-length@npm:1.0.4"
@@ -30045,6 +30646,20 @@ __metadata:
languageName: node
linkType: hard
+"typed-array-length@npm:^1.0.6":
+ version: 1.0.6
+ resolution: "typed-array-length@npm:1.0.6"
+ dependencies:
+ call-bind: ^1.0.7
+ for-each: ^0.3.3
+ gopd: ^1.0.1
+ has-proto: ^1.0.3
+ is-typed-array: ^1.1.13
+ possible-typed-array-names: ^1.0.0
+ checksum: f0315e5b8f0168c29d390ff410ad13e4d511c78e6006df4a104576844812ee447fcc32daab1f3a76c9ef4f64eff808e134528b5b2439de335586b392e9750e5c
+ languageName: node
+ linkType: hard
+
"typedarray-to-buffer@npm:^3.1.5":
version: 3.1.5
resolution: "typedarray-to-buffer@npm:3.1.5"
@@ -31265,6 +31880,19 @@ __metadata:
languageName: node
linkType: hard
+"which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15":
+ version: 1.1.15
+ resolution: "which-typed-array@npm:1.1.15"
+ dependencies:
+ available-typed-arrays: ^1.0.7
+ call-bind: ^1.0.7
+ for-each: ^0.3.3
+ gopd: ^1.0.1
+ has-tostringtag: ^1.0.2
+ checksum: 65227dcbfadf5677aacc43ec84356d17b5500cb8b8753059bb4397de5cd0c2de681d24e1a7bd575633f976a95f88233abfd6549c2105ef4ebd58af8aa1807c75
+ languageName: node
+ linkType: hard
+
"which@npm:^1.2.9":
version: 1.3.1
resolution: "which@npm:1.3.1"
From e2d1a3970dbdd72b749fe02bb342efa1cfb26351 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Tue, 16 Jul 2024 18:58:26 +0530
Subject: [PATCH 041/104] changed sidebar stylings
---
.../ui-elements/src/components/Sidebar/Sidebar.stories.js | 2 ++
.../ui-elements/src/components/Sidebar/Sidebar.styles.js | 7 ++++---
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/packages/ui-elements/src/components/Sidebar/Sidebar.stories.js b/packages/ui-elements/src/components/Sidebar/Sidebar.stories.js
index c56314685..f03ab4857 100644
--- a/packages/ui-elements/src/components/Sidebar/Sidebar.stories.js
+++ b/packages/ui-elements/src/components/Sidebar/Sidebar.stories.js
@@ -19,6 +19,7 @@ export const Default = Template.bind({});
Default.args = {
title: 'Sidebar Title',
iconName: 'menu',
+ style: { width: '350px' },
onClose: () => console.log('Sidebar closed'),
children: (
@@ -36,6 +37,7 @@ export const WithSearch = Template.bind({});
WithSearch.args = {
title: 'Sidebar with Search',
iconName: 'search',
+ style: { width: '350px' },
onClose: () => console.log('Sidebar closed'),
searchProps: { isSearch: true, placeholder: 'Search...' },
children: (
diff --git a/packages/ui-elements/src/components/Sidebar/Sidebar.styles.js b/packages/ui-elements/src/components/Sidebar/Sidebar.styles.js
index 37f3aa459..a60f6a4df 100644
--- a/packages/ui-elements/src/components/Sidebar/Sidebar.styles.js
+++ b/packages/ui-elements/src/components/Sidebar/Sidebar.styles.js
@@ -5,7 +5,7 @@ const useSidebarStyles = () => {
const { theme, colors } = useTheme();
const sidebarContainer = css`
- width: 350px;
+ min-width: 350px;
height: 100%;
box-shadow: ${theme.shadows[2]};
z-index: ${theme.zIndex.general};
@@ -45,8 +45,9 @@ const useSidebarStyles = () => {
const searchContainer = css`
display: flex;
align-items: center;
- justify-content: space-around;
+ justify-content: space-between;
border: 1px solid ${colors.border};
+ padding: 0 0.5rem;
border-radius: ${theme.schemes.radius};
position: relative;
margin: 0 1rem 1rem;
@@ -57,7 +58,7 @@ const useSidebarStyles = () => {
const textInput = css`
border: none;
- flex: none;
+ flex: 1;
padding: none;
&:focus {
outline: none;
From 0b9726ebb2216805314b5ff6bb7044e51be9fab5 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Tue, 16 Jul 2024 19:25:47 +0530
Subject: [PATCH 042/104] add showsidebar state to handle layout properly
---
.../react/src/hooks/useSetExclusiveState.js | 11 +++++-
packages/react/src/store/index.js | 1 +
packages/react/src/store/sidebarStore.js | 8 ++++
.../react/src/views/ChatLayout/ChatLayout.js | 38 ++++++++++---------
.../src/views/ChatLayout/ChatLayout.styles.js | 8 +++-
.../views/RoomMembers/RoomMembers.styles.js | 1 -
6 files changed, 46 insertions(+), 21 deletions(-)
create mode 100644 packages/react/src/store/sidebarStore.js
diff --git a/packages/react/src/hooks/useSetExclusiveState.js b/packages/react/src/hooks/useSetExclusiveState.js
index 23ab5d9e3..9a59fdb41 100644
--- a/packages/react/src/hooks/useSetExclusiveState.js
+++ b/packages/react/src/hooks/useSetExclusiveState.js
@@ -9,9 +9,11 @@ import {
usePinnedMessageStore,
useStarredMessageStore,
useFileStore,
+ useSidebarStore,
} from '../store';
const useSetExclusiveState = () => {
+ const setShowSidebar = useSidebarStore((state) => state.setShowSidebar);
const setShowMembers = useMemberStore((state) => state.setShowMembers);
const setShowSearch = useSearchMessageStore((state) => state.setShowSearch);
const setShowPinned = usePinnedMessageStore((state) => state.setShowPinned);
@@ -55,9 +57,16 @@ const useSetExclusiveState = () => {
);
const setExclusiveState = (activeSetter) => {
+ let isPanelActive = false;
stateSetters.forEach((setter) => {
- setter(setter === activeSetter);
+ if (setter === activeSetter) {
+ isPanelActive = true;
+ setter(true);
+ } else {
+ setter(false);
+ }
});
+ setShowSidebar(isPanelActive);
};
return setExclusiveState;
diff --git a/packages/react/src/store/index.js b/packages/react/src/store/index.js
index 50e0a667c..bddd0bd1d 100644
--- a/packages/react/src/store/index.js
+++ b/packages/react/src/store/index.js
@@ -10,3 +10,4 @@ export { default as useFileStore } from './fileStore';
export { default as useMentionsStore } from './mentionsStore';
export { default as usePinnedMessageStore } from './pinnedMessageStore';
export { default as useStarredMessageStore } from './starredMessageStore';
+export { default as useSidebarStore } from './sidebarStore';
diff --git a/packages/react/src/store/sidebarStore.js b/packages/react/src/store/sidebarStore.js
new file mode 100644
index 000000000..27a1c7f63
--- /dev/null
+++ b/packages/react/src/store/sidebarStore.js
@@ -0,0 +1,8 @@
+import { create } from 'zustand';
+
+const useSidebarStore = create((set) => ({
+ showSidebar: false,
+ setShowSidebar: (showSidebar) => set(() => ({ showSidebar })),
+}));
+
+export default useSidebarStore;
diff --git a/packages/react/src/views/ChatLayout/ChatLayout.js b/packages/react/src/views/ChatLayout/ChatLayout.js
index 43c13f1a1..6243dc0cc 100644
--- a/packages/react/src/views/ChatLayout/ChatLayout.js
+++ b/packages/react/src/views/ChatLayout/ChatLayout.js
@@ -11,6 +11,7 @@ import {
useMentionsStore,
useThreadsMessageStore,
useMemberStore,
+ useSidebarStore,
} from '../../store';
import RoomMembers from '../RoomMembers/RoomMember';
@@ -38,6 +39,7 @@ const ChatLayout = () => {
const { ECOptions } = useRCContext();
const anonymousMode = ECOptions?.anonymousMode;
const showRoles = ECOptions?.anonymousMode;
+ const showSidebar = useSidebarStore((state) => state.showSidebar);
const showMentions = useMentionsStore((state) => state.showMentions);
const showAllFiles = useFileStore((state) => state.showAllFiles);
const showAllThreads = useThreadsMessageStore(
@@ -92,23 +94,25 @@ const ChatLayout = () => {
-
- {showMembers && }
- {showSearch && }
- {showChannelinfo && }
- {showAllThreads && }
- {showAllFiles && }
- {showMentions && }
- {showPinned && }
- {showStarred && }
- {showCurrentUserInfo && }
- {uiKitContextualBarOpen && (
-
- )}
-
+ {showSidebar && (
+
+ {showMembers && }
+ {showSearch && }
+ {showChannelinfo && }
+ {showAllThreads && }
+ {showAllFiles && }
+ {showMentions && }
+ {showPinned && }
+ {showStarred && }
+ {showCurrentUserInfo && }
+ {uiKitContextualBarOpen && (
+
+ )}
+
+ )}
{attachmentWindowOpen ? (
data ? (
diff --git a/packages/react/src/views/ChatLayout/ChatLayout.styles.js b/packages/react/src/views/ChatLayout/ChatLayout.styles.js
index 12a45957b..3afa72649 100644
--- a/packages/react/src/views/ChatLayout/ChatLayout.styles.js
+++ b/packages/react/src/views/ChatLayout/ChatLayout.styles.js
@@ -2,17 +2,21 @@ import { css } from '@emotion/react';
const styles = {
layout: css`
- flex-basis: 100%;
display: flex;
+ height: 100%;
overflow: hidden;
`,
chatMain: css`
display: flex;
+ flex: 1;
flex-direction: column;
- flex-grow: 1;
position: relative;
`,
+
+ sidebar: css`
+ width: 350px;
+ `,
};
export default styles;
diff --git a/packages/react/src/views/RoomMembers/RoomMembers.styles.js b/packages/react/src/views/RoomMembers/RoomMembers.styles.js
index 728fe0e70..8e5e692e4 100644
--- a/packages/react/src/views/RoomMembers/RoomMembers.styles.js
+++ b/packages/react/src/views/RoomMembers/RoomMembers.styles.js
@@ -6,7 +6,6 @@ export const useRoomMemberStyles = () => {
flex-direction: column;
overflow: auto;
width: 100%;
- align-items: center;
justify-content: center;
padding: 0 1rem 1rem;
`;
From e95763220e2474af3e3aa6f7632bed1b97b8139a Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Tue, 16 Jul 2024 19:38:16 +0530
Subject: [PATCH 043/104] sidebar modification
---
packages/ui-elements/src/components/Sidebar/Sidebar.js | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/packages/ui-elements/src/components/Sidebar/Sidebar.js b/packages/ui-elements/src/components/Sidebar/Sidebar.js
index c114b02af..695d640b6 100644
--- a/packages/ui-elements/src/components/Sidebar/Sidebar.js
+++ b/packages/ui-elements/src/components/Sidebar/Sidebar.js
@@ -1,5 +1,6 @@
import React from 'react';
import { Box } from '../Box';
+import { useComponentOverrides } from '../../hooks';
import useSidebarStyles from './Sidebar.styles';
import SidebarHeader from './SidebarHeader';
import SidebarContent from './SidebarContent';
@@ -15,9 +16,14 @@ const Sidebar = ({
style = {},
}) => {
const styles = useSidebarStyles();
+ const { classNames, styleOverrides } = useComponentOverrides('Sidebar');
return (
-
+
{children}
{footer && {footer}}
From fcad6c3456d726e54f3a2c210b6846657d83c9d9 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Tue, 16 Jul 2024 21:59:12 +0530
Subject: [PATCH 044/104] added resizable sidebar
---
packages/layout_editor/package.json | 3 +-
.../src/views/ChatLayout/ChatLayout.jsx | 58 ++++++++++++++-----
.../src/views/ChatLayout/ChatLayout.styles.js | 7 ++-
3 files changed, 48 insertions(+), 20 deletions(-)
diff --git a/packages/layout_editor/package.json b/packages/layout_editor/package.json
index 90dd03b21..ab36ab4fb 100644
--- a/packages/layout_editor/package.json
+++ b/packages/layout_editor/package.json
@@ -14,7 +14,8 @@
"@dnd-kit/sortable": "^8.0.0",
"@embeddedchat/ui-elements": "workspace:^",
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-dom": "^18.2.0",
+ "react-resizable-panels": "^2.0.20"
},
"devDependencies": {
"@emotion/babel-preset-css-prop": "^11.11.0",
diff --git a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
index 0fc1000b0..de62fa66f 100644
--- a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
+++ b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
@@ -1,24 +1,50 @@
-import React from "react";
-import { Box } from "@embeddedchat/ui-elements";
-import ChatBody from "../Chatbody/ChatBody";
-import ChatInput from "../ChatInput/ChatInput";
-import { getChatLayoutStyles } from "./ChatLayout.styles";
-import DemoSidebar from "../DemoSidebar/DemoSidebar";
-import members from "../../data/members.json";
+import React, { useState } from 'react';
+import { Box } from '@embeddedchat/ui-elements';
+import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
+import ChatBody from '../Chatbody/ChatBody';
+import ChatInput from '../ChatInput/ChatInput';
+import { getChatLayoutStyles } from './ChatLayout.styles';
+import DemoSidebar from '../DemoSidebar/DemoSidebar';
+import members from '../../data/members.json';
const ChatLayout = () => {
const styles = getChatLayoutStyles();
+
+ const handleResize = (size) => {
+ const minSize = 26.5;
+ const maxSize = 60;
+ const minWidth = 350;
+ const maxWidth = 796;
+
+ const sidebarWidth =
+ minWidth +
+ ((size - minSize) / (maxSize - minSize)) * (maxWidth - minWidth);
+
+ console.log(sidebarWidth);
+ };
+
return (
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
};
diff --git a/packages/layout_editor/src/views/ChatLayout/ChatLayout.styles.js b/packages/layout_editor/src/views/ChatLayout/ChatLayout.styles.js
index ddfa382d0..d15c43ae4 100644
--- a/packages/layout_editor/src/views/ChatLayout/ChatLayout.styles.js
+++ b/packages/layout_editor/src/views/ChatLayout/ChatLayout.styles.js
@@ -1,9 +1,9 @@
-import { css } from "@emotion/react";
+import { css } from '@emotion/react';
export const getChatLayoutStyles = () => {
const styles = {
layout: css`
- flex-basis: 100%;
+ height: 100%;
display: flex;
overflow: hidden;
`,
@@ -11,7 +11,8 @@ export const getChatLayoutStyles = () => {
chatMain: css`
display: flex;
flex-direction: column;
- flex-grow: 1;
+ height: 100%;
+ flex: 1;
position: relative;
`,
};
From de0b4a06624de6dda8c2f475969e240930bc1b6f Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Tue, 16 Jul 2024 22:03:19 +0530
Subject: [PATCH 045/104] handled menu visibility
---
.../src/components/SortableMenu/Menu.jsx | 46 ++++++++++++-------
1 file changed, 29 insertions(+), 17 deletions(-)
diff --git a/packages/layout_editor/src/components/SortableMenu/Menu.jsx b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
index 37deccd89..7181ff4f0 100644
--- a/packages/layout_editor/src/components/SortableMenu/Menu.jsx
+++ b/packages/layout_editor/src/components/SortableMenu/Menu.jsx
@@ -1,4 +1,4 @@
-import React, { useMemo } from 'react';
+import React, { useMemo, useState } from 'react';
import { css } from '@emotion/react';
import {
Box,
@@ -19,6 +19,7 @@ const Menu = ({
}) => {
const theme = useTheme();
const styles = getMenuStyles(theme);
+ const [isMenuVisible, setIsMenuVisible] = useState(false);
const anchorStyle = useMemo(() => {
const positions = from.split(/\s+/);
@@ -29,27 +30,38 @@ const Menu = ({
return styleAnchor;
}, [from]);
+ const handleMenuVisibility = () => {
+ setIsMenuVisible((prev) => !prev);
+ };
+
return (
-
+
-
-
- {options.map((option, idx) => (
-
- ))}
-
-
+ {isMenuVisible && (
+
+
+ {options.map((option, idx) => (
+
+ ))}
+
+
+ )}
);
};
From 80f475deda6b2b9b5e32027ffda02fcd3112acf2 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Tue, 16 Jul 2024 22:13:34 +0530
Subject: [PATCH 046/104] added slight styles to resize handler
---
.../layout_editor/src/views/ChatLayout/ChatLayout.jsx | 11 ++++++++---
.../src/views/ChatLayout/ChatLayout.styles.js | 2 +-
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
index de62fa66f..7e11e51b9 100644
--- a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
+++ b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
@@ -1,5 +1,5 @@
import React, { useState } from 'react';
-import { Box } from '@embeddedchat/ui-elements';
+import { Box, useTheme } from '@embeddedchat/ui-elements';
import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
import ChatBody from '../Chatbody/ChatBody';
import ChatInput from '../ChatInput/ChatInput';
@@ -8,7 +8,7 @@ import DemoSidebar from '../DemoSidebar/DemoSidebar';
import members from '../../data/members.json';
const ChatLayout = () => {
- const styles = getChatLayoutStyles();
+ const styles = getChatLayoutStyles(useTheme());
const handleResize = (size) => {
const minSize = 26.5;
@@ -33,7 +33,12 @@ const ChatLayout = () => {
-
+
{
+export const getChatLayoutStyles = ({ colors }) => {
const styles = {
layout: css`
height: 100%;
From 45dc92433f75a51fa0f5b32e945d5b3e94055d8c Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Wed, 17 Jul 2024 00:00:08 +0530
Subject: [PATCH 047/104] fixed sidebar height
---
packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
index 7e11e51b9..ae6175f5d 100644
--- a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
+++ b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React from 'react';
import { Box, useTheme } from '@embeddedchat/ui-elements';
import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
import ChatBody from '../Chatbody/ChatBody';
@@ -45,7 +45,7 @@ const ChatLayout = () => {
maxSize={60}
onResize={handleResize}
>
-
+
From 0e67c78ff1a3ea55203d66d9fa5ac2e17b3ea9ea Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Wed, 17 Jul 2024 00:15:48 +0530
Subject: [PATCH 048/104] added theme lab
---
.../layout_editor/src/views/GlobalStyles.jsx | 20 ++++-----
.../layout_editor/src/views/LayoutEditor.jsx | 43 ++++++++++++-------
.../src/views/LayoutEditor.style.js | 10 ++++-
3 files changed, 45 insertions(+), 28 deletions(-)
diff --git a/packages/layout_editor/src/views/GlobalStyles.jsx b/packages/layout_editor/src/views/GlobalStyles.jsx
index 72d9e52f6..ebdc3551f 100644
--- a/packages/layout_editor/src/views/GlobalStyles.jsx
+++ b/packages/layout_editor/src/views/GlobalStyles.jsx
@@ -1,39 +1,39 @@
-import React from "react";
-import { css, Global } from "@emotion/react";
-import { useTheme, alpha } from "@embeddedchat/ui-elements";
+import React from 'react';
+import { css, Global } from '@emotion/react';
+import { useTheme, alpha } from '@embeddedchat/ui-elements';
const useStyles = ({ colors, theme }) => css`
- .ec-embedded-chat * {
+ * {
box-sizing: border-box;
margin: 0;
padding: 0;
}
- .ec-embedded-chat body {
+ body {
font-family: ${theme.typography.default.fontFamily};
font-size: ${theme.typography.default.fontSize}px;
font-weight: ${theme.typography.default.fontWeightRegular};
}
- .ec-embedded-chat a {
+ a {
color: ${colors.foreground};
}
- .ec-embedded-chat ::-webkit-scrollbar {
+ ::-webkit-scrollbar {
width: 4px;
height: 7.7px;
}
- .ec-embedded-chat ::-webkit-scrollbar-thumb {
+ ::-webkit-scrollbar-thumb {
background: ${alpha(colors.primary, 0.5)};
border-radius: 4px;
}
- .ec-embedded-chat ::-webkit-scrollbar-thumb:hover {
+ ::-webkit-scrollbar-thumb:hover {
background: ${colors.primary};
}
- .ec-embedded-chat ::-webkit-scrollbar-button {
+ ::-webkit-scrollbar-button {
display: none;
}
`;
diff --git a/packages/layout_editor/src/views/LayoutEditor.jsx b/packages/layout_editor/src/views/LayoutEditor.jsx
index 5df7bf41d..18ec34b89 100644
--- a/packages/layout_editor/src/views/LayoutEditor.jsx
+++ b/packages/layout_editor/src/views/LayoutEditor.jsx
@@ -1,23 +1,34 @@
-import React, { useState } from "react";
-import DefaultTheme from "../theme/DefaultTheme";
-import { Box, ThemeProvider } from "@embeddedchat/ui-elements";
-import { styles } from "./LayoutEditor.style";
-import ChatLayout from "./ChatLayout/ChatLayout";
-import ChatHeader from "./ChatHeader/ChatHeader";
-import GlobalStyles from "./GlobalStyles";
+import React, { useState } from 'react';
+import DefaultTheme from '../theme/DefaultTheme';
+import { Box, Sidebar, ThemeProvider } from '@embeddedchat/ui-elements';
+import { styles } from './LayoutEditor.style';
+import ChatLayout from './ChatLayout/ChatLayout';
+import ChatHeader from './ChatHeader/ChatHeader';
+import GlobalStyles from './GlobalStyles';
const LayoutEditor = () => {
- const [mode, setMode] = useState("light");
+ const [mode, setMode] = useState('light');
+ const [isThemeLab, setIsThemeLab] = useState(true);
return (
-
-
-
-
-
+
+
+
+
+
+
+
+ {isThemeLab && (
+
+ setIsThemeLab(false)}>
+
+ )}
);
diff --git a/packages/layout_editor/src/views/LayoutEditor.style.js b/packages/layout_editor/src/views/LayoutEditor.style.js
index 7a03f61ca..e91dff9f9 100644
--- a/packages/layout_editor/src/views/LayoutEditor.style.js
+++ b/packages/layout_editor/src/views/LayoutEditor.style.js
@@ -2,15 +2,21 @@ import { css } from '@emotion/react';
export const styles = {
embeddedchat: (theme, dark) => css`
- width: 100%;
- height: 95vh;
+ width: 75%;
+ height: 100vh;
position: relative;
background: ${theme.schemes[dark ? 'dark' : 'light'].background};
color: ${theme.schemes[dark ? 'dark' : 'light'].foreground};
display: flex;
+ flex: 1;
flex-direction: column;
border: ${`1.5px solid ${theme.schemes[dark ? 'dark' : 'light'].border}`};
border-radius: ${theme.schemes.radius};
overflow: hidden;
`,
+
+ layoutEditor: css`
+ display: flex;
+ gap: 0.25rem;
+ `,
};
From 6c3d17518272846809796037424b715fb40f9eef Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Wed, 17 Jul 2024 00:38:10 +0530
Subject: [PATCH 049/104] added start theming btn
---
.../src/views/DemoSidebar/DemoSidebar.jsx | 71 ++++++++++---------
.../views/DemoSidebar/DemoSidebar.styles.js | 10 ++-
.../layout_editor/src/views/LayoutEditor.jsx | 2 +-
3 files changed, 46 insertions(+), 37 deletions(-)
diff --git a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
index 7e549a2b4..f059b327c 100644
--- a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
+++ b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
@@ -1,43 +1,48 @@
-import React from "react";
-import PropTypes from "prop-types";
-import { Box, Icon, Sidebar, Popup } from "@embeddedchat/ui-elements";
-import { css } from "@emotion/react";
-import { getDemoSidebarStyles } from "./DemoSidebar.styles";
+import React from 'react';
+import PropTypes from 'prop-types';
+import { Box, Icon, Sidebar, Popup, Button } from '@embeddedchat/ui-elements';
+import { css } from '@emotion/react';
+import { getDemoSidebarStyles } from './DemoSidebar.styles';
-const DemoSidebar = ({ members, viewType = "Sidebar" }) => {
- const ViewComponent = viewType === "Popup" ? Popup : Sidebar;
+const DemoSidebar = ({ members, viewType = 'Sidebar' }) => {
+ const ViewComponent = viewType === 'Popup' ? Popup : Sidebar;
const styles = getDemoSidebarStyles();
return (
- {members.map((member, index) => (
-
-
-
- {member.status && (
-
- )}
- {member.username}
+
+ {members.map((member, index) => (
+
+
+
+ {member.status && (
+
+ )}
+ {member.username}
+
-
- ))}
+ ))}
+
+
+
+
);
@@ -51,7 +56,7 @@ DemoSidebar.propTypes = {
username: PropTypes.string.isRequired,
})
).isRequired,
- viewType: PropTypes.oneOf(["Sidebar", "Popup"]),
+ viewType: PropTypes.oneOf(['Sidebar', 'Popup']),
};
export default DemoSidebar;
diff --git a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.styles.js b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.styles.js
index e202c9806..32c7e5a8f 100644
--- a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.styles.js
+++ b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.styles.js
@@ -1,14 +1,14 @@
-import { css } from "@emotion/react";
+import { css } from '@emotion/react';
export const getDemoSidebarStyles = () => {
const styles = {
container: css`
display: flex;
+ flex: 1;
flex-direction: column;
overflow: auto;
width: 100%;
- align-items: center;
- justify-content: center;
+ justify-content: space-between;
padding: 0 1rem 1rem;
`,
@@ -25,6 +25,10 @@ export const getDemoSidebarStyles = () => {
margin-right: 0.5rem;
align-self: center;
`,
+
+ btn: css`
+ width: 100%;
+ `,
};
return styles;
diff --git a/packages/layout_editor/src/views/LayoutEditor.jsx b/packages/layout_editor/src/views/LayoutEditor.jsx
index 18ec34b89..0ae3b0c6e 100644
--- a/packages/layout_editor/src/views/LayoutEditor.jsx
+++ b/packages/layout_editor/src/views/LayoutEditor.jsx
@@ -8,7 +8,7 @@ import GlobalStyles from './GlobalStyles';
const LayoutEditor = () => {
const [mode, setMode] = useState('light');
- const [isThemeLab, setIsThemeLab] = useState(true);
+ const [isThemeLab, setIsThemeLab] = useState(false);
return (
From 6f3efd62dad1cecaf0c689894d04dca372ed7fe3 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Wed, 17 Jul 2024 11:28:42 +0530
Subject: [PATCH 050/104] added emoji
---
packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
index f059b327c..dc9d6cd76 100644
--- a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
+++ b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
@@ -41,7 +41,9 @@ const DemoSidebar = ({ members, viewType = 'Sidebar' }) => {
))}
-
+
From d3ca35e39f270002efe050f4d84a99f35baa03e6 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Wed, 17 Jul 2024 12:25:43 +0530
Subject: [PATCH 051/104] changed lint rules
added zustand
added settings icon
added icon to themelab
---
packages/layout_editor/.eslintrc.cjs | 25 ++++++++++---------
packages/layout_editor/package.json | 3 ++-
.../layout_editor/src/store/layoutStore.js | 10 ++++++++
.../src/views/DemoSidebar/DemoSidebar.jsx | 13 ++++++++--
.../views/DemoSidebar/DemoSidebar.styles.js | 7 ++++++
.../layout_editor/src/views/LayoutEditor.jsx | 12 ++++-----
.../src/views/ThemeLab/ThemeLab.jsx | 22 ++++++++++++++++
.../src/views/ThemeLab/ThemeLab.styles.js | 11 ++++++++
.../src/components/Icon/icons/Cog.js | 14 +++++++++++
.../src/components/Icon/icons/index.js | 2 ++
packages/ui-elements/tools/icons-generator.js | 1 +
11 files changed, 98 insertions(+), 22 deletions(-)
create mode 100644 packages/layout_editor/src/store/layoutStore.js
create mode 100644 packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
create mode 100644 packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
create mode 100644 packages/ui-elements/src/components/Icon/icons/Cog.js
diff --git a/packages/layout_editor/.eslintrc.cjs b/packages/layout_editor/.eslintrc.cjs
index bf64d1237..71cc58753 100644
--- a/packages/layout_editor/.eslintrc.cjs
+++ b/packages/layout_editor/.eslintrc.cjs
@@ -2,21 +2,22 @@ module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
- "plugin:react/recommended",
- "plugin:react-hooks/recommended",
- "prettier",
+ 'plugin:react/recommended',
+ 'plugin:react-hooks/recommended',
+ 'prettier',
],
- ignorePatterns: ["dist", ".eslintrc.cjs"],
- parserOptions: { ecmaVersion: "latest", sourceType: "module" },
- settings: { react: { version: "18.2" } },
- plugins: ["react-refresh"],
+ ignorePatterns: ['dist', '.eslintrc.cjs'],
+ parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
+ settings: { react: { version: '18.2' } },
+ plugins: ['react-refresh'],
rules: {
- "react/jsx-no-target-blank": "off",
- "react-refresh/only-export-components": [
- "warn",
+ 'react/jsx-no-target-blank': 'off',
+ 'react-refresh/only-export-components': [
+ 'warn',
{ allowConstantExport: true },
],
- "react/prop-types": "off",
- "react/no-unknown-property": ["error", { ignore: ["css"] }],
+ 'react/prop-types': 'off',
+ 'react/no-unknown-property': ['error', { ignore: ['css'] }],
+ 'no-undef': 'error',
},
};
diff --git a/packages/layout_editor/package.json b/packages/layout_editor/package.json
index ab36ab4fb..b712eb838 100644
--- a/packages/layout_editor/package.json
+++ b/packages/layout_editor/package.json
@@ -24,6 +24,7 @@
"eslint-plugin-react": "^7.34.4",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
- "vite": "^5.1.0"
+ "vite": "^5.1.0",
+ "zustand": "^4.3.8"
}
}
diff --git a/packages/layout_editor/src/store/layoutStore.js b/packages/layout_editor/src/store/layoutStore.js
new file mode 100644
index 000000000..943b4592f
--- /dev/null
+++ b/packages/layout_editor/src/store/layoutStore.js
@@ -0,0 +1,10 @@
+import { create } from 'zustand';
+
+const useLayoutStore = create((set) => ({
+ themeLabOpen: false,
+ setThemeLabOpen: (themeLabOpen) => {
+ set({ themeLabOpen });
+ },
+}));
+
+export default useLayoutStore;
diff --git a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
index dc9d6cd76..117e4c5c1 100644
--- a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
+++ b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.jsx
@@ -3,8 +3,11 @@ import PropTypes from 'prop-types';
import { Box, Icon, Sidebar, Popup, Button } from '@embeddedchat/ui-elements';
import { css } from '@emotion/react';
import { getDemoSidebarStyles } from './DemoSidebar.styles';
+import useLayoutStore from '../../store/layoutStore';
const DemoSidebar = ({ members, viewType = 'Sidebar' }) => {
+ const themeLabOpen = useLayoutStore((state) => state.themeLabOpen);
+ const setThemeLabOpen = useLayoutStore((state) => state.setThemeLabOpen);
const ViewComponent = viewType === 'Popup' ? Popup : Sidebar;
const styles = getDemoSidebarStyles();
return (
@@ -41,8 +44,14 @@ const DemoSidebar = ({ members, viewType = 'Sidebar' }) => {
))}
-
diff --git a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.styles.js b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.styles.js
index 32c7e5a8f..3c27e4980 100644
--- a/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.styles.js
+++ b/packages/layout_editor/src/views/DemoSidebar/DemoSidebar.styles.js
@@ -28,6 +28,13 @@ export const getDemoSidebarStyles = () => {
btn: css`
width: 100%;
+ opacity: 1;
+ transition: all 0.1s;
+ `,
+
+ btnInvisible: css`
+ width: 0;
+ opacity: 0;
`,
};
diff --git a/packages/layout_editor/src/views/LayoutEditor.jsx b/packages/layout_editor/src/views/LayoutEditor.jsx
index 0ae3b0c6e..b94da6958 100644
--- a/packages/layout_editor/src/views/LayoutEditor.jsx
+++ b/packages/layout_editor/src/views/LayoutEditor.jsx
@@ -1,14 +1,16 @@
import React, { useState } from 'react';
import DefaultTheme from '../theme/DefaultTheme';
-import { Box, Sidebar, ThemeProvider } from '@embeddedchat/ui-elements';
+import { Box, ThemeProvider } from '@embeddedchat/ui-elements';
import { styles } from './LayoutEditor.style';
import ChatLayout from './ChatLayout/ChatLayout';
import ChatHeader from './ChatHeader/ChatHeader';
import GlobalStyles from './GlobalStyles';
+import useLayoutStore from '../store/layoutStore';
+import ThemeLab from './ThemeLab/ThemeLab';
const LayoutEditor = () => {
const [mode, setMode] = useState('light');
- const [isThemeLab, setIsThemeLab] = useState(false);
+ const themeLabOpen = useLayoutStore((state) => state.themeLabOpen);
return (
@@ -24,11 +26,7 @@ const LayoutEditor = () => {
- {isThemeLab && (
-
- setIsThemeLab(false)}>
-
- )}
+ {themeLabOpen && }
);
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
new file mode 100644
index 000000000..fed2e26bd
--- /dev/null
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
@@ -0,0 +1,22 @@
+import React from 'react';
+import { Box, MinimalSidebar, SidebarHeader } from '@embeddedchat/ui-elements';
+import useLayoutStore from '../../store/layoutStore';
+import { useThemeLabStyles } from './ThemeLab.styles';
+
+const ThemeLab = () => {
+ const styles = useThemeLabStyles();
+ const setThemeLabOpen = useLayoutStore((state) => state.setThemeLabOpen);
+ return (
+
+
+ setThemeLabOpen(false)}
+ title="Theme Lab"
+ iconName="cog"
+ />
+
+
+ );
+};
+
+export default ThemeLab;
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
new file mode 100644
index 000000000..060103e12
--- /dev/null
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
@@ -0,0 +1,11 @@
+import { css } from '@emotion/react';
+
+export const useThemeLabStyles = () => {
+ const styles = {
+ themeLab: css`
+ display: flex;
+ `,
+ };
+
+ return styles;
+};
diff --git a/packages/ui-elements/src/components/Icon/icons/Cog.js b/packages/ui-elements/src/components/Icon/icons/Cog.js
new file mode 100644
index 000000000..08d027a63
--- /dev/null
+++ b/packages/ui-elements/src/components/Icon/icons/Cog.js
@@ -0,0 +1,14 @@
+import React from 'react';
+
+const Cog = (props) => (
+
+);
+
+export default Cog;
diff --git a/packages/ui-elements/src/components/Icon/icons/index.js b/packages/ui-elements/src/components/Icon/icons/index.js
index 8f0a26de2..77cd6a451 100644
--- a/packages/ui-elements/src/components/Icon/icons/index.js
+++ b/packages/ui-elements/src/components/Icon/icons/index.js
@@ -60,6 +60,7 @@ import Collapse from './ArrowCollapse';
import Arc from './Arc';
import Avatar from './Avatar';
import FormatText from './FormatText';
+import Cog from './Cog';
const icons = {
file: File,
@@ -124,6 +125,7 @@ const icons = {
arc: Arc,
avatar: Avatar,
'format-text': FormatText,
+ cog: Cog,
};
export default icons;
diff --git a/packages/ui-elements/tools/icons-generator.js b/packages/ui-elements/tools/icons-generator.js
index 238cbae34..7dc17fc93 100644
--- a/packages/ui-elements/tools/icons-generator.js
+++ b/packages/ui-elements/tools/icons-generator.js
@@ -45,6 +45,7 @@ const iconsList = [
'at',
'arrow-collapse',
'arrow-expand',
+ 'cog',
];
const svgDirPath = path.join(
From a7dfc108da32d99ce0838c47054680187d52e1cf Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Thu, 18 Jul 2024 00:06:34 +0530
Subject: [PATCH 052/104] added layout and palette section:
---
.../src/views/ThemeLab/ThemeLab.jsx | 32 +++++++++++++++++--
.../src/views/ThemeLab/ThemeLab.styles.js | 14 ++++++--
2 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
index fed2e26bd..a9eb7034f 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
@@ -1,11 +1,19 @@
-import React from 'react';
-import { Box, MinimalSidebar, SidebarHeader } from '@embeddedchat/ui-elements';
+import React, { useState } from 'react';
+import {
+ Box,
+ MinimalSidebar,
+ SidebarContent,
+ SidebarHeader,
+ useTheme,
+} from '@embeddedchat/ui-elements';
import useLayoutStore from '../../store/layoutStore';
import { useThemeLabStyles } from './ThemeLab.styles';
const ThemeLab = () => {
- const styles = useThemeLabStyles();
+ const styles = useThemeLabStyles(useTheme());
const setThemeLabOpen = useLayoutStore((state) => state.setThemeLabOpen);
+ const [paletteActive, setPaletteAction] = useState(true);
+
return (
@@ -14,6 +22,24 @@ const ThemeLab = () => {
title="Theme Lab"
iconName="cog"
/>
+
+
+ setPaletteAction(true)}
+ >
+ Palette
+
+ setPaletteAction(false)}
+ >
+ Layout
+
+
+
);
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
index 060103e12..be731f635 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
@@ -1,9 +1,19 @@
import { css } from '@emotion/react';
-export const useThemeLabStyles = () => {
+export const useThemeLabStyles = ({ colors }) => {
const styles = {
- themeLab: css`
+ sectionContainer: css`
display: flex;
+ align-items: center;
+ justify-content: space-around;
+ `,
+
+ section: css`
+ padding: 0 1rem 0.5rem;
+ cursor: pointer;
+ `,
+ sectionActive: css`
+ border-bottom: 1px solid ${colors.primary};
`,
};
From 39fa617dafc8807a70654c637d7bcf197da30a37 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Thu, 18 Jul 2024 00:16:02 +0530
Subject: [PATCH 053/104] fixed height issue
---
packages/layout_editor/src/views/LayoutEditor.style.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/layout_editor/src/views/LayoutEditor.style.js b/packages/layout_editor/src/views/LayoutEditor.style.js
index e91dff9f9..f34c535b7 100644
--- a/packages/layout_editor/src/views/LayoutEditor.style.js
+++ b/packages/layout_editor/src/views/LayoutEditor.style.js
@@ -3,7 +3,6 @@ import { css } from '@emotion/react';
export const styles = {
embeddedchat: (theme, dark) => css`
width: 75%;
- height: 100vh;
position: relative;
background: ${theme.schemes[dark ? 'dark' : 'light'].background};
color: ${theme.schemes[dark ? 'dark' : 'light'].foreground};
@@ -16,6 +15,7 @@ export const styles = {
`,
layoutEditor: css`
+ height: 100vh;
display: flex;
gap: 0.25rem;
`,
From 5fa7fcfc938e0dafa7209047b657a3b105d6f320 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Thu, 18 Jul 2024 00:18:43 +0530
Subject: [PATCH 054/104] render diff sections
---
.../layout_editor/src/views/ThemeLab/LayoutSetting.jsx | 9 +++++++++
.../layout_editor/src/views/ThemeLab/PaletteSetting.jsx | 9 +++++++++
packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx | 4 ++++
3 files changed, 22 insertions(+)
create mode 100644 packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
create mode 100644 packages/layout_editor/src/views/ThemeLab/PaletteSetting.jsx
diff --git a/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx b/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
new file mode 100644
index 000000000..98186f7a0
--- /dev/null
+++ b/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
@@ -0,0 +1,9 @@
+import React from 'react'
+
+const LayoutSetting = () => {
+ return (
+ LayoutSetting
+ )
+}
+
+export default LayoutSetting
\ No newline at end of file
diff --git a/packages/layout_editor/src/views/ThemeLab/PaletteSetting.jsx b/packages/layout_editor/src/views/ThemeLab/PaletteSetting.jsx
new file mode 100644
index 000000000..60b9057bd
--- /dev/null
+++ b/packages/layout_editor/src/views/ThemeLab/PaletteSetting.jsx
@@ -0,0 +1,9 @@
+import React from 'react'
+
+const PaletteSetting = () => {
+ return (
+ PaletteSetting
+ )
+}
+
+export default PaletteSetting
\ No newline at end of file
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
index a9eb7034f..f0ff3c9f4 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
@@ -8,6 +8,8 @@ import {
} from '@embeddedchat/ui-elements';
import useLayoutStore from '../../store/layoutStore';
import { useThemeLabStyles } from './ThemeLab.styles';
+import PaletteSetting from './PaletteSetting';
+import LayoutSetting from './LayoutSetting';
const ThemeLab = () => {
const styles = useThemeLabStyles(useTheme());
@@ -39,6 +41,8 @@ const ThemeLab = () => {
Layout
+
+ {paletteActive ? : }
From 5a8ec2a7de92af899eb78fc113ceef79b3151d2c Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Thu, 18 Jul 2024 20:00:24 +0530
Subject: [PATCH 055/104] setup sections added select updated yarn lock
---
.../src/views/Message/MessageHeader.jsx | 26 +++----
.../src/views/ThemeLab/LayoutSetting.jsx | 67 +++++++++++++++++--
.../src/views/ThemeLab/PaletteSetting.jsx | 20 ++++--
.../src/views/ThemeLab/ThemeLab.jsx | 4 +-
.../src/views/ThemeLab/ThemeLab.styles.js | 59 +++++++++++++++-
.../StaticSelect/StaticSelect.styles.js | 1 +
6 files changed, 151 insertions(+), 26 deletions(-)
diff --git a/packages/layout_editor/src/views/Message/MessageHeader.jsx b/packages/layout_editor/src/views/Message/MessageHeader.jsx
index a3dadfb37..fca4819e1 100644
--- a/packages/layout_editor/src/views/Message/MessageHeader.jsx
+++ b/packages/layout_editor/src/views/Message/MessageHeader.jsx
@@ -1,17 +1,17 @@
-import React from "react";
-import PropTypes from "prop-types";
-import { format } from "date-fns";
+import React from 'react';
+import PropTypes from 'prop-types';
+import { format } from 'date-fns';
import {
Box,
Icon,
useTheme,
appendClassNames,
-} from "@embeddedchat/ui-elements";
-import { getMessageHeaderStyles } from "./Message.styles";
-import useDisplayNameColor from "../../hooks/useDisplayNameColor";
+} from '@embeddedchat/ui-elements';
+import { getMessageHeaderStyles } from './Message.styles';
+import useDisplayNameColor from '../../hooks/useDisplayNameColor';
-const MessageHeader = ({ message, variantOverrides }) => {
- const displayNameVariant = variantOverrides || "Normal";
+const MessageHeader = ({ message, variantOverrides = 'Normal' }) => {
+ const displayNameVariant = variantOverrides || 'Normal';
const styles = getMessageHeaderStyles(useTheme());
const { colors } = useTheme();
const getDisplayNameColor = useDisplayNameColor();
@@ -21,9 +21,9 @@ const MessageHeader = ({ message, variantOverrides }) => {
{
- {format(new Date(message.ts), "h:mm a")}
+ {format(new Date(message.ts), 'h:mm a')}
{!message.t && (
{message.editedAt && (
{
+ const styles = getLayoutSettings(useTheme());
+
+ const messageViewOptions = [
+ {
+ label: 'Flat',
+ value: 'flat',
+ },
+
+ {
+ label: 'Bubble',
+ value: 'bubble',
+ },
+ ];
+
+ const displayNameOptions = [
+ {
+ label: 'Normal',
+ value: 'normal',
+ },
+
+ {
+ label: 'Colorize',
+ value: 'colorize',
+ },
+ ];
return (
- LayoutSetting
- )
-}
+
+
+ Variants
+
+ Message View
+
+
+
+
+ Display Name
+
+
+
+
+
+ Tool Tray
+
+
+ );
+};
-export default LayoutSetting
\ No newline at end of file
+export default LayoutSetting;
diff --git a/packages/layout_editor/src/views/ThemeLab/PaletteSetting.jsx b/packages/layout_editor/src/views/ThemeLab/PaletteSetting.jsx
index 60b9057bd..e90c584ca 100644
--- a/packages/layout_editor/src/views/ThemeLab/PaletteSetting.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/PaletteSetting.jsx
@@ -1,9 +1,19 @@
-import React from 'react'
+import React from 'react';
+import { Box, useTheme } from '@embeddedchat/ui-elements';
+import { getPaletteSettings } from './ThemeLab.styles';
const PaletteSetting = () => {
+ const styles = getPaletteSettings(useTheme());
return (
- PaletteSetting
- )
-}
+
+
+ Colors
+
+
+ Typography
+
+
+ );
+};
-export default PaletteSetting
\ No newline at end of file
+export default PaletteSetting;
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
index f0ff3c9f4..c01e84d00 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
@@ -7,12 +7,12 @@ import {
useTheme,
} from '@embeddedchat/ui-elements';
import useLayoutStore from '../../store/layoutStore';
-import { useThemeLabStyles } from './ThemeLab.styles';
+import { getThemeLabStyles } from './ThemeLab.styles';
import PaletteSetting from './PaletteSetting';
import LayoutSetting from './LayoutSetting';
const ThemeLab = () => {
- const styles = useThemeLabStyles(useTheme());
+ const styles = getThemeLabStyles(useTheme());
const setThemeLabOpen = useLayoutStore((state) => state.setThemeLabOpen);
const [paletteActive, setPaletteAction] = useState(true);
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
index be731f635..01860f9e8 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
@@ -1,6 +1,6 @@
import { css } from '@emotion/react';
-export const useThemeLabStyles = ({ colors }) => {
+export const getThemeLabStyles = ({ colors }) => {
const styles = {
sectionContainer: css`
display: flex;
@@ -19,3 +19,60 @@ export const useThemeLabStyles = ({ colors }) => {
return styles;
};
+
+export const getPaletteSettings = ({ colors }) => {
+ const styles = {
+ main: css`
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ padding: 0.75rem;
+ `,
+ colorSection: css`
+ padding: 0.5rem;
+ `,
+ typographySection: css`
+ padding: 0.5rem;
+ `,
+ };
+
+ return styles;
+};
+
+export const getLayoutSettings = ({ colors }) => {
+ const styles = {
+ main: css`
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ padding: 0.75rem;
+ padding: 0.75rem;
+ `,
+ variantSection: css`
+ padding: 0.5rem;
+ background-color: ${colors.secondary};
+ border-radius: 0.25rem;
+ `,
+
+ toolSection: css`
+ padding: 0.5rem;
+ `,
+
+ commonSelect: css`
+ display: flex;
+ gap: 1.25rem;
+ justify-content: space-between;
+ padding: 1.25rem 0;
+ `,
+
+ messageView: css`
+ position: relative;
+ `,
+
+ displayName: css`
+ position: relative;
+ `,
+ };
+
+ return styles;
+};
diff --git a/packages/ui-elements/src/components/StaticSelect/StaticSelect.styles.js b/packages/ui-elements/src/components/StaticSelect/StaticSelect.styles.js
index 63df6107e..f0767930c 100644
--- a/packages/ui-elements/src/components/StaticSelect/StaticSelect.styles.js
+++ b/packages/ui-elements/src/components/StaticSelect/StaticSelect.styles.js
@@ -9,6 +9,7 @@ const useStaticSelectStyles = () => {
flex: 1 0 auto;
flex-direction: column;
gap: 0.25rem;
+ background-color: ${colors.background};
min-width: 8rem;
`,
From 970466f3362edc2450e22491b6fdcd11263b2c72 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Thu, 18 Jul 2024 23:49:27 +0530
Subject: [PATCH 056/104] added states
---
packages/layout_editor/src/store/layoutStore.js | 10 ++++++++++
.../src/views/ThemeLab/LayoutSetting.jsx | 11 +++++++++++
.../src/views/ThemeLab/ThemeLab.styles.js | 3 +++
3 files changed, 24 insertions(+)
diff --git a/packages/layout_editor/src/store/layoutStore.js b/packages/layout_editor/src/store/layoutStore.js
index 943b4592f..7810d6bf0 100644
--- a/packages/layout_editor/src/store/layoutStore.js
+++ b/packages/layout_editor/src/store/layoutStore.js
@@ -5,6 +5,16 @@ const useLayoutStore = create((set) => ({
setThemeLabOpen: (themeLabOpen) => {
set({ themeLabOpen });
},
+
+ messageView: 'flat',
+ setMessageView: (messageView) => {
+ set({ messageView });
+ },
+
+ displayName: 'normal',
+ setDisplayName: (displayName) => {
+ set({ displayName });
+ },
}));
export default useLayoutStore;
diff --git a/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx b/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
index 5bef6015a..879e39804 100644
--- a/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
@@ -1,10 +1,19 @@
import React from 'react';
import { Box, useTheme, StaticSelect } from '@embeddedchat/ui-elements';
import { getLayoutSettings } from './ThemeLab.styles';
+import useLayoutStore from '../../store/layoutStore';
const LayoutSetting = () => {
const styles = getLayoutSettings(useTheme());
+ const { messageView, setMessageView, displayName, setDisplayName } =
+ useLayoutStore((state) => ({
+ messageView: state.messageView,
+ setMessageView: state.setMessageView,
+ displayName: state.displayName,
+ setDisplayName: state.setDisplayName,
+ }));
+
const messageViewOptions = [
{
label: 'Flat',
@@ -43,6 +52,7 @@ const LayoutSetting = () => {
zIndex: '1',
}}
placeholder="Choose"
+ value={messageView}
/>
@@ -52,6 +62,7 @@ const LayoutSetting = () => {
options={displayNameOptions}
style={{ position: 'absolute', top: '16px', right: 0 }}
placeholder="Choose"
+ value={displayName}
/>
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
index 01860f9e8..0b5b3db26 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
@@ -45,6 +45,7 @@ export const getLayoutSettings = ({ colors }) => {
height: 100%;
display: flex;
flex-direction: column;
+ justify-content: space-between;
padding: 0.75rem;
padding: 0.75rem;
`,
@@ -56,6 +57,8 @@ export const getLayoutSettings = ({ colors }) => {
toolSection: css`
padding: 0.5rem;
+ background-color: ${colors.secondary};
+ border-radius: 0.25rem;
`,
commonSelect: css`
From b7f1544dda70f81f8b89b6dc413378eefaaa7555 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Fri, 19 Jul 2024 00:14:05 +0530
Subject: [PATCH 057/104] added switch functionality
---
.../Message/BubbleVariant/Bubble.styles.js | 14 ++----
.../src/views/Message/Message.jsx | 47 ++++++++++---------
.../src/views/Message/MessageHeader.jsx | 8 ++--
.../src/views/ThemeLab/LayoutSetting.jsx | 2 +
4 files changed, 38 insertions(+), 33 deletions(-)
diff --git a/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js b/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js
index 137f36390..b90c0f406 100644
--- a/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js
+++ b/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js
@@ -1,9 +1,9 @@
-import { css } from "@emotion/react";
-import { alpha } from "@embeddedchat/ui-elements";
+import { css } from '@emotion/react';
+import { alpha } from '@embeddedchat/ui-elements';
export const bubbleStyles = ({ theme, colors }) => {
const styles = {
- name: "bubble",
+ name: 'bubble',
messageParent: css`
display: flex;
gap: 0.25rem;
@@ -77,8 +77,6 @@ export const bubbleStyles = ({ theme, colors }) => {
`,
toolboxContainer: css`
- display: none;
- .ec-message-body:hover & {
display: flex;
position: absolute;
bottom: calc(100% - 20px);
@@ -173,10 +171,8 @@ export const bubbleStylesMe = (customTheme) => {
`,
toolboxContainerMe: css`
- .ec-message-body:hover & {
- left: auto;
- right: calc(100% - 20px);
- }
+ left: auto;
+ right: calc(100% - 10px);
`,
pinnedContainerMe: css`
diff --git a/packages/layout_editor/src/views/Message/Message.jsx b/packages/layout_editor/src/views/Message/Message.jsx
index 404afb04c..fccf15b1e 100644
--- a/packages/layout_editor/src/views/Message/Message.jsx
+++ b/packages/layout_editor/src/views/Message/Message.jsx
@@ -1,29 +1,32 @@
-import React from "react";
-import PropTypes from "prop-types";
-import { format } from "date-fns";
-import { Box, useTheme } from "@embeddedchat/ui-elements";
-import { Markdown } from "../Markdown";
-import MessageHeader from "./MessageHeader";
-import { MessageBody } from "./MessageBody";
-import { MessageToolbox } from "./MessageToolbox";
-import { MessageDivider } from "./MessageDivider";
-import MessageAvatarContainer from "./MessageAvatarContainer";
-import MessageBodyContainer from "./MessageBodyContainer";
-import { getMessageStyles } from "./Message.styles";
-import useBubbleStyles from "./BubbleVariant/useBubbleStyles";
+import React from 'react';
+import PropTypes from 'prop-types';
+import { format } from 'date-fns';
+import { Box, useTheme } from '@embeddedchat/ui-elements';
+import { Markdown } from '../Markdown';
+import MessageHeader from './MessageHeader';
+import { MessageBody } from './MessageBody';
+import { MessageToolbox } from './MessageToolbox';
+import { MessageDivider } from './MessageDivider';
+import MessageAvatarContainer from './MessageAvatarContainer';
+import MessageBodyContainer from './MessageBodyContainer';
+import { getMessageStyles } from './Message.styles';
+import useBubbleStyles from './BubbleVariant/useBubbleStyles';
+import useLayoutStore from '../../store/layoutStore';
const Message = ({
message,
sequential = false,
lastSequential = false,
newDay = false,
- variantOverrides = "default",
+ variantOverrides = 'default',
}) => {
- const isMe = message.u.username === "spiral_memory";
+ const isMe = message.u.username === 'spiral_memory';
const styles = getMessageStyles(useTheme());
const bubbleStyles = useBubbleStyles(isMe);
const shouldShowHeader = !sequential;
- const variantStyles = variantOverrides === "bubble" ? bubbleStyles : {};
+ const messageView = useLayoutStore((state) => state.messageView);
+ const finalVariant = messageView || variantOverrides;
+ const variantStyles = finalVariant === 'bubble' ? bubbleStyles : {};
return (
<>
@@ -31,7 +34,9 @@ const Message = ({
className="ec-message"
css={[
variantStyles.messageParent || styles.main,
- message._id === "62vhmKJGNoxgvLL7M" && styles.specialMessage,
+ message._id === '62vhmKJGNoxgvLL7M' &&
+ variantOverrides === 'flat' &&
+ styles.specialMessage,
]}
>
@@ -40,7 +45,7 @@ const Message = ({
{shouldShowHeader && (
@@ -59,7 +64,7 @@ const Message = ({
>
- {!message.t && message._id === "62vhmKJGNoxgvLL7M" ? (
+ {!message.t && message._id === '62vhmKJGNoxgvLL7M' ? (
) : (
<>>
@@ -71,7 +76,7 @@ const Message = ({
{newDay && (
- {format(new Date(message.ts), "MMMM d, yyyy")}
+ {format(new Date(message.ts), 'MMMM d, yyyy')}
)}
>
@@ -81,7 +86,7 @@ Message.propTypes = {
message: PropTypes.any,
sequential: PropTypes.bool,
newDay: PropTypes.bool,
- type: PropTypes.oneOf(["thread", "default"]),
+ type: PropTypes.oneOf(['thread', 'default']),
showAvatar: PropTypes.bool,
};
diff --git a/packages/layout_editor/src/views/Message/MessageHeader.jsx b/packages/layout_editor/src/views/Message/MessageHeader.jsx
index fca4819e1..5fdbad0ec 100644
--- a/packages/layout_editor/src/views/Message/MessageHeader.jsx
+++ b/packages/layout_editor/src/views/Message/MessageHeader.jsx
@@ -9,9 +9,11 @@ import {
} from '@embeddedchat/ui-elements';
import { getMessageHeaderStyles } from './Message.styles';
import useDisplayNameColor from '../../hooks/useDisplayNameColor';
+import useLayoutStore from '../../store/layoutStore';
-const MessageHeader = ({ message, variantOverrides = 'Normal' }) => {
- const displayNameVariant = variantOverrides || 'Normal';
+const MessageHeader = ({ message, variantOverrides = 'normal' }) => {
+ const displayName = useLayoutStore((state) => state.displayName);
+ const displayNameVariant = displayName || variantOverrides;
const styles = getMessageHeaderStyles(useTheme());
const { colors } = useTheme();
const getDisplayNameColor = useDisplayNameColor();
@@ -23,7 +25,7 @@ const MessageHeader = ({ message, variantOverrides = 'Normal' }) => {
css={styles.userName}
className={appendClassNames('ec-message-header-username')}
style={
- displayNameVariant === 'Colorize'
+ displayNameVariant === 'colorize'
? { color: getDisplayNameColor(message.u.username) }
: null
}
diff --git a/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx b/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
index 879e39804..48cf662b3 100644
--- a/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
@@ -53,6 +53,7 @@ const LayoutSetting = () => {
}}
placeholder="Choose"
value={messageView}
+ onSelect={setMessageView}
/>
@@ -63,6 +64,7 @@ const LayoutSetting = () => {
style={{ position: 'absolute', top: '16px', right: 0 }}
placeholder="Choose"
value={displayName}
+ onSelect={setDisplayName}
/>
From ec787f1f40a0d4450401f787795ac02a3d6a3f7f Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Fri, 19 Jul 2024 01:09:07 +0530
Subject: [PATCH 058/104] shifted items to global state
---
.../src/store/chatInputItemsStore.js | 10 +
.../src/store/headerItemsStore.js | 10 +
.../src/store/messageItemsStore.js | 20 ++
.../src/views/ChatHeader/ChatHeader.jsx | 188 ++++++++----------
.../src/views/ChatInput/ChatInputToolbar.jsx | 107 +++++-----
.../src/views/Message/MessageToolbox.jsx | 182 ++++++++---------
6 files changed, 263 insertions(+), 254 deletions(-)
create mode 100644 packages/layout_editor/src/store/chatInputItemsStore.js
create mode 100644 packages/layout_editor/src/store/headerItemsStore.js
create mode 100644 packages/layout_editor/src/store/messageItemsStore.js
diff --git a/packages/layout_editor/src/store/chatInputItemsStore.js b/packages/layout_editor/src/store/chatInputItemsStore.js
new file mode 100644
index 000000000..1a4b948bf
--- /dev/null
+++ b/packages/layout_editor/src/store/chatInputItemsStore.js
@@ -0,0 +1,10 @@
+import { create } from 'zustand';
+
+const useChatInputItemsStore = create((set) => ({
+ surfaceItems: ['emoji', 'formatter', 'audio', 'video', 'file'],
+ formatters: ['bold', 'italic', 'strike', 'code', 'multiline'],
+ setSurfaceItems: (items) => set({ surfaceItems: items }),
+ setFormatters: (items) => set({ formatters: items }),
+}));
+
+export default useChatInputItemsStore;
diff --git a/packages/layout_editor/src/store/headerItemsStore.js b/packages/layout_editor/src/store/headerItemsStore.js
new file mode 100644
index 000000000..78593cc1e
--- /dev/null
+++ b/packages/layout_editor/src/store/headerItemsStore.js
@@ -0,0 +1,10 @@
+import { create } from 'zustand';
+
+const useHeaderItemsStore = create((set) => ({
+ surfaceItems: ['minmax', 'close', 'thread', 'mentions', 'starred', 'pinned'],
+ menuItems: ['files', 'members', 'search', 'rInfo', 'logout'],
+ setSurfaceItems: (items) => set({ surfaceItems: items }),
+ setMenuItems: (items) => set({ menuItems: items }),
+}));
+
+export default useHeaderItemsStore;
diff --git a/packages/layout_editor/src/store/messageItemsStore.js b/packages/layout_editor/src/store/messageItemsStore.js
new file mode 100644
index 000000000..f89ac0e88
--- /dev/null
+++ b/packages/layout_editor/src/store/messageItemsStore.js
@@ -0,0 +1,20 @@
+import { create } from 'zustand';
+
+const useMessageItemsStore = create((set) => ({
+ surfaceItems: [
+ 'reaction',
+ 'reply',
+ 'quote',
+ 'star',
+ 'pin',
+ 'edit',
+ 'delete',
+ 'report',
+ ],
+
+ menuItems: [],
+ setSurfaceItems: (items) => set({ surfaceItems: items }),
+ setMenuItems: (items) => set({ menuItems: items }),
+}));
+
+export default useMessageItemsStore;
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
index 4da65a240..f30880b01 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.jsx
@@ -1,8 +1,8 @@
-import React, { useState, useMemo } from "react";
-import { Heading, Box, Icon, useTheme } from "@embeddedchat/ui-elements";
-import { getChatHeaderStyles } from "./ChatHeader.styles";
-import { Menu } from "../../components/SortableMenu";
-import SurfaceItem from "../../components/SurfaceMenu/SurfaceItem";
+import React, { useState, useMemo } from 'react';
+import { Heading, Box, Icon, useTheme } from '@embeddedchat/ui-elements';
+import { getChatHeaderStyles } from './ChatHeader.styles';
+import { Menu } from '../../components/SortableMenu';
+import SurfaceItem from '../../components/SurfaceMenu/SurfaceItem';
import {
DndContext,
closestCenter,
@@ -11,111 +11,106 @@ import {
useSensor,
useSensors,
DragOverlay,
-} from "@dnd-kit/core";
-import { sortableKeyboardCoordinates, arrayMove } from "@dnd-kit/sortable";
-import { createPortal } from "react-dom";
-import MenuItem from "../../components/SortableMenu/MenuItem";
-import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
+} from '@dnd-kit/core';
+import { sortableKeyboardCoordinates, arrayMove } from '@dnd-kit/sortable';
+import { createPortal } from 'react-dom';
+import MenuItem from '../../components/SortableMenu/MenuItem';
+import SurfaceMenu from '../../components/SurfaceMenu/SurfaceMenu';
+import useHeaderItemsStore from '../../store/headerItemsStore';
-const ChatHeader = ({
- optionConfig = {
- surfaceItems: [
- "minmax",
- "close",
- "thread",
- "mentions",
- "starred",
- "pinned",
- ],
- menuItems: ["files", "members", "search", "rInfo", "logout"],
- },
-}) => {
+const ChatHeader = () => {
const styles = getChatHeaderStyles(useTheme());
- const [surfaceItems, setSurfaceItems] = useState(optionConfig.surfaceItems);
- const [menuItems, setMenuItems] = useState(optionConfig.menuItems);
+ const { surfaceItems, menuItems, setSurfaceItems, setMenuItems } =
+ useHeaderItemsStore((state) => ({
+ surfaceItems: state.surfaceItems,
+ menuItems: state.menuItems,
+ setSurfaceItems: state.setSurfaceItems,
+ setMenuItems: state.setMenuItems,
+ }));
+
const [activeSurfaceItem, setActiveSurfaceItem] = useState(null);
const [activeMenuItem, setActiveMenuItem] = useState(null);
- const placeholderSurfaceItem = "placeholder-surface";
- const placeholderMenuItem = "placeholder-menu";
+ const placeholderSurfaceItem = 'placeholder-surface';
+ const placeholderMenuItem = 'placeholder-menu';
const options = useMemo(
() => ({
minmax: {
- label: "Maximize",
- id: "minmax",
+ label: 'Maximize',
+ id: 'minmax',
onClick: () => {},
- iconName: "expand",
+ iconName: 'expand',
visible: true,
},
close: {
- label: "Close",
- id: "close",
+ label: 'Close',
+ id: 'close',
onClick: () => {},
- iconName: "cross",
+ iconName: 'cross',
visible: true,
},
thread: {
- label: "Threads",
- id: "thread",
+ label: 'Threads',
+ id: 'thread',
onClick: () => {},
- iconName: "thread",
+ iconName: 'thread',
visible: true,
},
mentions: {
- label: "Mentions",
- id: "mentions",
+ label: 'Mentions',
+ id: 'mentions',
onClick: () => {},
- iconName: "at",
+ iconName: 'at',
visible: true,
},
starred: {
- label: "Starred Messages",
- id: "starred",
+ label: 'Starred Messages',
+ id: 'starred',
onClick: () => {},
- iconName: "star",
+ iconName: 'star',
visible: true,
},
pinned: {
- label: "Pinned Messages",
- id: "pinned",
+ label: 'Pinned Messages',
+ id: 'pinned',
onClick: () => {},
- iconName: "pin",
+ iconName: 'pin',
visible: true,
},
members: {
- label: "Members",
- id: "members",
+ label: 'Members',
+ id: 'members',
onClick: () => {},
- iconName: "members",
+ iconName: 'members',
visible: true,
},
files: {
- label: "Files",
- id: "files",
+ label: 'Files',
+ id: 'files',
onClick: () => {},
- iconName: "clip",
+ iconName: 'clip',
visible: true,
},
search: {
- label: "Search Messages",
- id: "search",
+ label: 'Search Messages',
+ id: 'search',
onClick: () => {},
- iconName: "magnifier",
+ iconName: 'magnifier',
visible: true,
},
rInfo: {
- label: "Room Information",
- id: "rInfo",
+ label: 'Room Information',
+ id: 'rInfo',
onClick: () => {},
- iconName: "info",
+ iconName: 'info',
visible: true,
},
logout: {
- label: "Logout",
- id: "logout",
+ label: 'Logout',
+ id: 'logout',
onClick: () => {},
- iconName: "reply-directly",
+ iconName: 'reply-directly',
visible: true,
},
}),
@@ -137,7 +132,7 @@ const ChatHeader = ({
return null;
})
.filter((option) => option !== null)
- : [{ id: placeholderMenuItem, label: "No items", icon: "plus" }];
+ : [{ id: placeholderMenuItem, label: 'No items', icon: 'plus' }];
const surfaceOptions =
surfaceItems.length > 0
@@ -154,7 +149,7 @@ const ChatHeader = ({
return null;
})
.filter((option) => option !== null)
- : [{ id: placeholderSurfaceItem, label: "No items", iconName: "plus" }];
+ : [{ id: placeholderSurfaceItem, label: 'No items', iconName: 'plus' }];
const sensors = useSensors(
useSensor(PointerSensor, {
@@ -168,13 +163,13 @@ const ChatHeader = ({
);
const handleDragStart = (event) => {
- if (event.active.data.current?.type === "SurfaceOptions") {
+ if (event.active.data.current?.type === 'SurfaceOptions') {
setActiveSurfaceItem({
id: event.active.id,
iconName: event.active.data.current.icon,
label: event.active.data.current.label,
});
- } else if (event.active.data.current?.type === "MenuOptions") {
+ } else if (event.active.data.current?.type === 'MenuOptions') {
setActiveMenuItem({
id: event.active.id,
icon: event.active.data.current.icon,
@@ -190,61 +185,52 @@ const ChatHeader = ({
if (active?.id !== over?.id) {
if (
- event.active.data.current?.type === "SurfaceOptions" &&
- event.over.data.current?.type === "SurfaceOptions"
+ event.active.data.current?.type === 'SurfaceOptions' &&
+ event.over.data.current?.type === 'SurfaceOptions'
) {
- setSurfaceItems((items) => {
- const oldIndex = items.indexOf(active.id);
- const newIndex = items.indexOf(over.id);
- return arrayMove(items, oldIndex, newIndex);
- });
+ const oldIndex = surfaceItems.indexOf(active.id);
+ const newIndex = surfaceItems.indexOf(over.id);
+ setSurfaceItems(arrayMove(surfaceItems, oldIndex, newIndex));
} else if (
- event.active.data.current?.type === "MenuOptions" &&
- event.over.data.current?.type === "MenuOptions"
+ event.active.data.current?.type === 'MenuOptions' &&
+ event.over.data.current?.type === 'MenuOptions'
) {
- setMenuItems((items) => {
- const oldIndex = items.indexOf(active.id);
- const newIndex = items.indexOf(over.id);
- return arrayMove(items, oldIndex, newIndex);
- });
+ const oldIndex = menuItems.indexOf(active.id);
+ const newIndex = menuItems.indexOf(over.id);
+ setMenuItems(arrayMove(menuItems, oldIndex, newIndex));
} else if (
- event.active.data.current?.type === "SurfaceOptions" &&
- event.over.data.current?.type === "MenuOptions" &&
+ event.active.data.current?.type === 'SurfaceOptions' &&
+ event.over.data.current?.type === 'MenuOptions' &&
active.id !== placeholderSurfaceItem
) {
- setSurfaceItems((items) => items.filter((item) => item !== active.id));
- setMenuItems((items) => {
- const newItems = [
- ...items.filter((item) => item !== placeholderMenuItem),
- active.id,
- ];
- return newItems;
- });
+ setSurfaceItems(surfaceItems.filter((item) => item !== active.id));
+ setMenuItems([
+ ...menuItems.filter((item) => item !== placeholderMenuItem),
+ active.id,
+ ]);
} else if (
- event.active.data.current?.type === "MenuOptions" &&
- event.over.data.current?.type === "SurfaceOptions" &&
+ event.active.data.current?.type === 'MenuOptions' &&
+ event.over.data.current?.type === 'SurfaceOptions' &&
active.id !== placeholderMenuItem
) {
- setMenuItems((items) => items.filter((item) => item !== active.id));
- setSurfaceItems((items) => {
- const newItems = [
- ...items.filter((item) => item !== placeholderSurfaceItem),
- active.id,
- ];
- return newItems;
- });
+ setMenuItems(menuItems.filter((item) => item !== active.id));
+ setSurfaceItems([
+ ...surfaceItems.filter((item) => item !== placeholderSurfaceItem),
+ active.id,
+ ]);
}
}
};
const removeSurfaceItem = (idToRemove) => {
- setSurfaceItems((items) => items.filter((item) => item !== idToRemove));
+ const newSurfaceItems = surfaceItems.filter((item) => item !== idToRemove);
+ setSurfaceItems(newSurfaceItems);
};
const removeMenuItem = (idToRemove) => {
- setMenuItems((items) => items.filter((item) => item !== idToRemove));
+ const newMenuItems = menuItems.filter((item) => item !== idToRemove);
+ setMenuItems(newMenuItems);
};
-
return (
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx b/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
index 49d1d77ac..f594e3a81 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
+++ b/packages/layout_editor/src/views/ChatInput/ChatInputToolbar.jsx
@@ -1,9 +1,10 @@
-import React, { useMemo, useState } from "react";
-import { Box, useTheme } from "@embeddedchat/ui-elements";
-import { getChatInputToolbarStyles } from "./ChatInput.styles";
-import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
-import SurfaceItem from "../../components/SurfaceMenu/SurfaceItem";
-import Formatters from "./Formatters";
+import React, { useMemo, useState } from 'react';
+import { Box, useTheme } from '@embeddedchat/ui-elements';
+import { getChatInputToolbarStyles } from './ChatInput.styles';
+import SurfaceMenu from '../../components/SurfaceMenu/SurfaceMenu';
+import SurfaceItem from '../../components/SurfaceMenu/SurfaceItem';
+import Formatters from './Formatters';
+import useChatInputItemsStore from '../../store/chatInputItemsStore';
import {
DndContext,
closestCenter,
@@ -12,61 +13,62 @@ import {
useSensor,
useSensors,
DragOverlay,
-} from "@dnd-kit/core";
-import { sortableKeyboardCoordinates, arrayMove } from "@dnd-kit/sortable";
-import { createPortal } from "react-dom";
+} from '@dnd-kit/core';
+import { sortableKeyboardCoordinates, arrayMove } from '@dnd-kit/sortable';
+import { createPortal } from 'react-dom';
-const ChatInputToolbar = ({
- optionConfig = {
- surfaceItems: ["emoji", "formatter", "audio", "video", "file"],
- formatters: ["bold", "italic", "strike", "code", "multiline"],
- },
-}) => {
+const ChatInputToolbar = () => {
const styles = getChatInputToolbarStyles(useTheme());
- const [surfaceItems, setSurfaceItems] = useState(optionConfig.surfaceItems);
- const [formatters, setFormatters] = useState(optionConfig.formatters);
+ const { surfaceItems, setSurfaceItems, formatters, setFormatters } =
+ useChatInputItemsStore((state) => ({
+ surfaceItems: state.surfaceItems,
+ setSurfaceItems: state.setSurfaceItems,
+ formatters: state.formatters,
+ setFormatters: state.setFormatters,
+ }));
+
const [activeSurfaceItem, setActiveSurfaceItem] = useState(null);
const [formattersVisible, setFormattersVisible] = useState(false);
- const placeholderSurfaceItem = "placeholder-surface";
+ const placeholderSurfaceItem = 'placeholder-surface';
const options = useMemo(() => {
return {
emoji: {
- label: "Emoji",
- id: "emoji",
+ label: 'Emoji',
+ id: 'emoji',
onClick: () => {},
- iconName: "emoji",
+ iconName: 'emoji',
visible: true,
},
audio: {
- label: "Audio Message",
- id: "audio",
+ label: 'Audio Message',
+ id: 'audio',
onClick: () => {},
- iconName: "mic",
+ iconName: 'mic',
visible: true,
},
video: {
- label: "Video Message",
- id: "video",
+ label: 'Video Message',
+ id: 'video',
onClick: () => {},
- iconName: "video-recorder",
+ iconName: 'video-recorder',
visible: true,
},
file: {
- label: "Upload File",
- id: "file",
+ label: 'Upload File',
+ id: 'file',
onClick: () => {},
- iconName: "attachment",
+ iconName: 'attachment',
visible: true,
},
formatter: {
- label: "Formatter",
- id: "formatter",
+ label: 'Formatter',
+ id: 'formatter',
onClick: () => {
setFormattersVisible((prev) => !prev);
},
- iconName: "format-text",
+ iconName: 'format-text',
visible: true,
},
};
@@ -84,7 +86,7 @@ const ChatInputToolbar = ({
);
const handleDragStart = (event) => {
- if (event.active.data.current?.type === "SurfaceOptions") {
+ if (event.active.data.current?.type === 'SurfaceOptions') {
if (options[event.active.id] !== undefined) {
setFormattersVisible(false);
}
@@ -102,20 +104,20 @@ const ChatInputToolbar = ({
if (active?.id !== over?.id) {
if (
- event.active.data.current?.type === "SurfaceOptions" &&
- event.over.data.current?.type === "SurfaceOptions"
+ event.active.data.current?.type === 'SurfaceOptions' &&
+ event.over.data.current?.type === 'SurfaceOptions'
) {
- setSurfaceItems((items) => {
- const oldIndex = items.indexOf(active.id);
- const newIndex = items.indexOf(over.id);
- return arrayMove(items, oldIndex, newIndex);
- });
+ const oldSurfaceIndex = surfaceItems.indexOf(active.id);
+ const newSurfaceIndex = surfaceItems.indexOf(over.id);
+ setSurfaceItems(
+ arrayMove(surfaceItems, oldSurfaceIndex, newSurfaceIndex)
+ );
- setFormatters((items) => {
- const oldIndex = items.indexOf(active.id);
- const newIndex = items.indexOf(over.id);
- return arrayMove(items, oldIndex, newIndex);
- });
+ const oldFormatterIndex = formatters.indexOf(active.id);
+ const newFormatterIndex = formatters.indexOf(over.id);
+ setFormatters(
+ arrayMove(formatters, oldFormatterIndex, newFormatterIndex)
+ );
}
}
};
@@ -124,7 +126,7 @@ const ChatInputToolbar = ({
return surfaceItems.length > 0
? surfaceItems
.map((item) => {
- if (item === "formatter") {
+ if (item === 'formatter') {
return options.formatter;
}
if (options[item] && options[item].visible) {
@@ -138,17 +140,18 @@ const ChatInputToolbar = ({
return null;
})
.filter((option) => option !== null)
- : [{ id: placeholderSurfaceItem, label: "No items", iconName: "plus" }];
+ : [{ id: placeholderSurfaceItem, label: 'No items', iconName: 'plus' }];
}, [surfaceItems, options]);
const removeSurfaceItem = (idToRemove) => {
- setSurfaceItems((items) => items.filter((item) => item !== idToRemove));
+ const newSurfaceItems = surfaceItems.filter((item) => item !== idToRemove);
+ setSurfaceItems(newSurfaceItems);
};
const removeFormatters = (idToRemove) => {
- setFormatters((items) => items.filter((item) => item !== idToRemove));
+ const newFormatters = formatters.filter((item) => item !== idToRemove);
+ setFormatters(newFormatters);
};
-
return (
,
- document.getElementById("formatter")
+ document.getElementById('formatter')
)}
);
diff --git a/packages/layout_editor/src/views/Message/MessageToolbox.jsx b/packages/layout_editor/src/views/Message/MessageToolbox.jsx
index a4d48cac4..fbad6209c 100644
--- a/packages/layout_editor/src/views/Message/MessageToolbox.jsx
+++ b/packages/layout_editor/src/views/Message/MessageToolbox.jsx
@@ -1,10 +1,10 @@
-import React, { useMemo, useState } from "react";
-import { Box, useTheme } from "@embeddedchat/ui-elements";
-import { Menu } from "../../components/SortableMenu";
-import { getMessageToolboxStyles } from "./Message.styles";
-import SurfaceMenu from "../../components/SurfaceMenu/SurfaceMenu";
-import SurfaceItem from "../../components/SurfaceMenu/SurfaceItem";
-import MenuItem from "../../components/SortableMenu/MenuItem";
+import React, { useMemo, useState } from 'react';
+import { Box, useTheme } from '@embeddedchat/ui-elements';
+import { Menu } from '../../components/SortableMenu';
+import { getMessageToolboxStyles } from './Message.styles';
+import SurfaceMenu from '../../components/SurfaceMenu/SurfaceMenu';
+import SurfaceItem from '../../components/SurfaceMenu/SurfaceItem';
+import MenuItem from '../../components/SortableMenu/MenuItem';
import {
DndContext,
closestCenter,
@@ -13,37 +13,25 @@ import {
useSensor,
useSensors,
DragOverlay,
-} from "@dnd-kit/core";
-import { sortableKeyboardCoordinates, arrayMove } from "@dnd-kit/sortable";
-import { createPortal } from "react-dom";
+} from '@dnd-kit/core';
+import { sortableKeyboardCoordinates, arrayMove } from '@dnd-kit/sortable';
+import { createPortal } from 'react-dom';
+import useMessageItemsStore from '../../store/messageItemsStore';
-export const MessageToolbox = ({
- variantStyles = {},
- optionConfig = {
- surfaceItems: [
- "reaction",
- "reply",
- "quote",
- "star",
- "pin",
- "edit",
- "delete",
- "report",
- ],
-
- menuItems: [],
- },
-
- ...props
-}) => {
+export const MessageToolbox = ({ variantStyles = {}, ...props }) => {
const styles = getMessageToolboxStyles(useTheme());
- const [surfaceItems, setSurfaceItems] = useState(optionConfig.surfaceItems);
- const [menuItems, setMenuItems] = useState(optionConfig.menuItems);
+ const { surfaceItems, menuItems, setSurfaceItems, setMenuItems } =
+ useMessageItemsStore((state) => ({
+ surfaceItems: state.surfaceItems,
+ menuItems: state.menuItems,
+ setSurfaceItems: state.setSurfaceItems,
+ setMenuItems: state.setMenuItems,
+ }));
const [activeSurfaceItem, setActiveSurfaceItem] = useState(null);
const [activeMenuItem, setActiveMenuItem] = useState(null);
- const placeholderSurfaceItem = "placeholder-surface";
- const placeholderMenuItem = "placeholder-menu";
+ const placeholderSurfaceItem = 'placeholder-surface';
+ const placeholderMenuItem = 'placeholder-menu';
const sensors = useSensors(
useSensor(PointerSensor, {
@@ -57,13 +45,13 @@ export const MessageToolbox = ({
);
const handleDragStart = (event) => {
- if (event.active.data.current?.type === "SurfaceOptions") {
+ if (event.active.data.current?.type === 'SurfaceOptions') {
setActiveSurfaceItem({
id: event.active.id,
iconName: event.active.data.current.icon,
label: event.active.data.current.label,
});
- } else if (event.active.data.current?.type === "MenuOptions") {
+ } else if (event.active.data.current?.type === 'MenuOptions') {
setActiveMenuItem({
id: event.active.id,
icon: event.active.data.current.icon,
@@ -79,49 +67,39 @@ export const MessageToolbox = ({
if (active?.id !== over?.id) {
if (
- event.active.data.current?.type === "SurfaceOptions" &&
- event.over.data.current?.type === "SurfaceOptions"
+ event.active.data.current?.type === 'SurfaceOptions' &&
+ event.over.data.current?.type === 'SurfaceOptions'
) {
- setSurfaceItems((items) => {
- const oldIndex = items.indexOf(active.id);
- const newIndex = items.indexOf(over.id);
- return arrayMove(items, oldIndex, newIndex);
- });
+ const oldIndex = surfaceItems.indexOf(active.id);
+ const newIndex = surfaceItems.indexOf(over.id);
+ setSurfaceItems(arrayMove(surfaceItems, oldIndex, newIndex));
} else if (
- event.active.data.current?.type === "MenuOptions" &&
- event.over.data.current?.type === "MenuOptions"
+ event.active.data.current?.type === 'MenuOptions' &&
+ event.over.data.current?.type === 'MenuOptions'
) {
- setMenuItems((items) => {
- const oldIndex = items.indexOf(active.id);
- const newIndex = items.indexOf(over.id);
- return arrayMove(items, oldIndex, newIndex);
- });
+ const oldIndex = menuItems.indexOf(active.id);
+ const newIndex = menuItems.indexOf(over.id);
+ setMenuItems(arrayMove(menuItems, oldIndex, newIndex));
} else if (
- event.active.data.current?.type === "SurfaceOptions" &&
- event.over.data.current?.type === "MenuOptions" &&
+ event.active.data.current?.type === 'SurfaceOptions' &&
+ event.over.data.current?.type === 'MenuOptions' &&
active.id !== placeholderSurfaceItem
) {
- setSurfaceItems((items) => items.filter((item) => item !== active.id));
- setMenuItems((items) => {
- const newItems = [
- ...items.filter((item) => item !== placeholderMenuItem),
- active.id,
- ];
- return newItems;
- });
+ setSurfaceItems(surfaceItems.filter((item) => item !== active.id));
+ setMenuItems([
+ ...menuItems.filter((item) => item !== placeholderMenuItem),
+ active.id,
+ ]);
} else if (
- event.active.data.current?.type === "MenuOptions" &&
- event.over.data.current?.type === "SurfaceOptions" &&
+ event.active.data.current?.type === 'MenuOptions' &&
+ event.over.data.current?.type === 'SurfaceOptions' &&
active.id !== placeholderMenuItem
) {
- setMenuItems((items) => items.filter((item) => item !== active.id));
- setSurfaceItems((items) => {
- const newItems = [
- ...items.filter((item) => item !== placeholderSurfaceItem),
- active.id,
- ];
- return newItems;
- });
+ setMenuItems(menuItems.filter((item) => item !== active.id));
+ setSurfaceItems([
+ ...surfaceItems.filter((item) => item !== placeholderSurfaceItem),
+ active.id,
+ ]);
}
}
};
@@ -129,62 +107,62 @@ export const MessageToolbox = ({
const options = useMemo(
() => ({
reply: {
- label: "Reply in thread",
- id: "reply",
+ label: 'Reply in thread',
+ id: 'reply',
onClick: () => {},
- iconName: "thread",
+ iconName: 'thread',
visible: true,
},
quote: {
- label: "Quote",
- id: "quote",
+ label: 'Quote',
+ id: 'quote',
onClick: () => {},
- iconName: "quote",
+ iconName: 'quote',
visible: true,
},
star: {
- label: "Star",
- id: "star",
+ label: 'Star',
+ id: 'star',
onClick: () => {},
- iconName: "star",
+ iconName: 'star',
visible: true,
},
reaction: {
- label: "Add reaction",
- id: "reaction",
+ label: 'Add reaction',
+ id: 'reaction',
onClick: () => {},
- iconName: "emoji",
+ iconName: 'emoji',
visible: true,
},
pin: {
- label: "Pin",
- id: "pin",
+ label: 'Pin',
+ id: 'pin',
onClick: () => {},
- iconName: "pin",
+ iconName: 'pin',
visible: true,
},
edit: {
- label: "Edit",
- id: "edit",
+ label: 'Edit',
+ id: 'edit',
onClick: () => {},
- iconName: "edit",
+ iconName: 'edit',
visible: true,
},
delete: {
- label: "Delete",
- id: "delete",
+ label: 'Delete',
+ id: 'delete',
onClick: () => {},
- iconName: "trash",
+ iconName: 'trash',
visible: true,
- type: "destructive",
+ type: 'destructive',
},
report: {
- label: "Report",
- id: "report",
+ label: 'Report',
+ id: 'report',
onClick: () => {},
- iconName: "report",
+ iconName: 'report',
visible: true,
- type: "destructive",
+ type: 'destructive',
},
}),
[]
@@ -205,7 +183,7 @@ export const MessageToolbox = ({
return null;
})
.filter((option) => option !== null)
- : [{ id: placeholderMenuItem, label: "No items", icon: "plus" }];
+ : [{ id: placeholderMenuItem, label: 'No items', icon: 'plus' }];
const surfaceOptions =
surfaceItems.length > 0
@@ -223,14 +201,16 @@ export const MessageToolbox = ({
return null;
})
.filter((option) => option !== null)
- : [{ id: placeholderSurfaceItem, label: "No items", iconName: "plus" }];
+ : [{ id: placeholderSurfaceItem, label: 'No items', iconName: 'plus' }];
const removeSurfaceItem = (idToRemove) => {
- setSurfaceItems((items) => items.filter((item) => item !== idToRemove));
+ const newSurfaceItems = surfaceItems.filter((item) => item !== idToRemove);
+ setSurfaceItems(newSurfaceItems);
};
const removeMenuItem = (idToRemove) => {
- setMenuItems((items) => items.filter((item) => item !== idToRemove));
+ const newMenuItems = menuItems.filter((item) => item !== idToRemove);
+ setMenuItems(newMenuItems);
};
return (
@@ -255,9 +235,9 @@ export const MessageToolbox = ({
size="small"
options={menuOptions}
from="bottom"
- tooltip={{ isToolTip: true, position: "top", text: "More" }}
+ tooltip={{ isToolTip: true, position: 'top', text: 'More' }}
useWrapper={false}
- style={{ top: "auto", bottom: `calc(100% + 2px)` }}
+ style={{ top: 'auto', bottom: `calc(100% + 2px)` }}
onRemove={removeMenuItem}
/>
)}
From df2a97346b1b6b31ad6742759f2dd7edf828dc1a Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Fri, 19 Jul 2024 14:11:00 +0530
Subject: [PATCH 059/104] added functionality to restore items
---
.../components/SurfaceMenu/SurfaceItem.jsx | 5 +-
.../src/views/ThemeLab/LayoutSetting.jsx | 133 +++++++++++++++++-
.../src/views/ThemeLab/ThemeLab.styles.js | 12 +-
3 files changed, 145 insertions(+), 5 deletions(-)
diff --git a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
index 72f8d06b1..4a4f47f23 100644
--- a/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
+++ b/packages/layout_editor/src/components/SurfaceMenu/SurfaceItem.jsx
@@ -17,6 +17,7 @@ const SurfaceItem = ({
onClick,
onRemove,
type,
+ cursor = 'grab',
tooltipPosition = 'bottom',
size,
}) => {
@@ -57,11 +58,11 @@ const SurfaceItem = ({
iconSize="small"
color={type}
style={{
- cursor: 'grab',
+ cursor: cursor,
}}
/>
- {id !== 'placeholder-surface' && (
+ {id !== 'placeholder-surface' && onRemove && (
{
diff --git a/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx b/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
index 48cf662b3..bf905e56c 100644
--- a/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
@@ -1,7 +1,9 @@
-import React from 'react';
+import React, { useMemo, useCallback } from 'react';
import { Box, useTheme, StaticSelect } from '@embeddedchat/ui-elements';
import { getLayoutSettings } from './ThemeLab.styles';
import useLayoutStore from '../../store/layoutStore';
+import SurfaceItem from '../../components/SurfaceMenu/SurfaceItem';
+import useHeaderItemsStore from '../../store/headerItemsStore';
const LayoutSetting = () => {
const styles = getLayoutSettings(useTheme());
@@ -37,6 +39,127 @@ const LayoutSetting = () => {
value: 'colorize',
},
];
+
+ const {
+ surfaceItems: headerSurfaceItems,
+ setSurfaceItems: setHeaderSurfaceItems,
+ menuItems: headerMenuItems,
+ } = useHeaderItemsStore((state) => ({
+ surfaceItems: state.surfaceItems,
+ setSurfaceItems: state.setSurfaceItems,
+ menuItems: state.menuItems,
+ }));
+
+ const addHeaderSurfaceItem = useCallback(
+ (id) => {
+ if (!headerSurfaceItems.includes(id) && !headerMenuItems.includes(id)) {
+ setHeaderSurfaceItems([id, ...headerSurfaceItems]);
+ }
+ },
+ [headerMenuItems, headerSurfaceItems, setHeaderSurfaceItems]
+ );
+
+ const headerOptions = useMemo(
+ () => ({
+ minmax: {
+ label: 'Maximize',
+ id: 'minmax',
+ iconName: 'expand',
+ onClick: () => {
+ addHeaderSurfaceItem('minmax');
+ },
+ },
+ close: {
+ label: 'Close',
+ id: 'close',
+ onClick: () => {
+ addHeaderSurfaceItem('close');
+ },
+ iconName: 'cross',
+ },
+ thread: {
+ label: 'Threads',
+ id: 'thread',
+ onClick: () => {
+ addHeaderSurfaceItem('thread');
+ },
+ iconName: 'thread',
+ },
+ mentions: {
+ label: 'Mentions',
+ id: 'mentions',
+ onClick: () => {
+ addHeaderSurfaceItem('mentions');
+ },
+ iconName: 'at',
+ },
+ starred: {
+ label: 'Starred Messages',
+ id: 'starred',
+ onClick: () => {
+ addHeaderSurfaceItem('starred');
+ },
+ iconName: 'star',
+ },
+ pinned: {
+ label: 'Pinned Messages',
+ id: 'pinned',
+ onClick: () => {
+ addHeaderSurfaceItem('pinned');
+ },
+ iconName: 'pin',
+ },
+ members: {
+ label: 'Members',
+ id: 'members',
+ onClick: () => {
+ addHeaderSurfaceItem('members');
+ },
+ iconName: 'members',
+ },
+ files: {
+ label: 'Files',
+ id: 'files',
+ onClick: () => {
+ addHeaderSurfaceItem('files');
+ },
+ iconName: 'clip',
+ },
+ search: {
+ label: 'Search Messages',
+ id: 'search',
+ onClick: () => {
+ addHeaderSurfaceItem('search');
+ },
+ iconName: 'magnifier',
+ },
+ rInfo: {
+ label: 'Room Information',
+ id: 'rInfo',
+ onClick: () => {
+ addHeaderSurfaceItem('rInfo');
+ },
+ iconName: 'info',
+ },
+ logout: {
+ label: 'Logout',
+ id: 'logout',
+ onClick: () => {
+ addHeaderSurfaceItem('logout');
+ },
+ iconName: 'reply-directly',
+ },
+ }),
+ [addHeaderSurfaceItem]
+ );
+
+ const surfaceOptions = Object.keys(headerOptions).map((key) => ({
+ id: headerOptions[key].id,
+ onClick: headerOptions[key].onClick,
+ label: headerOptions[key].label,
+ iconName: headerOptions[key].iconName,
+ }));
+
return (
@@ -71,6 +194,14 @@ const LayoutSetting = () => {
Tool Tray
+
+ Header Items
+
+ {surfaceOptions?.map((item, idx) => (
+
+ ))}
+
+
);
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
index 0b5b3db26..6be962fde 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
@@ -45,8 +45,7 @@ export const getLayoutSettings = ({ colors }) => {
height: 100%;
display: flex;
flex-direction: column;
- justify-content: space-between;
- padding: 0.75rem;
+ gap: 1.5rem;
padding: 0.75rem;
`,
variantSection: css`
@@ -75,6 +74,15 @@ export const getLayoutSettings = ({ colors }) => {
displayName: css`
position: relative;
`,
+
+ headerItems: css`
+ padding: 1.25rem 0;
+ `,
+
+ itemContainer: css`
+ display: flex;
+ padding: 0.5rem 0;
+ `,
};
return styles;
From 074d7e243cf3874b24fb709bb5108a098b0fe3e6 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Fri, 19 Jul 2024 19:41:29 +0530
Subject: [PATCH 060/104] tool tray completed
---
.../src/views/ThemeLab/LayoutSetting.jsx | 285 +++++++++++++++++-
1 file changed, 275 insertions(+), 10 deletions(-)
diff --git a/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx b/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
index bf905e56c..f2fd06d5c 100644
--- a/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
@@ -4,6 +4,8 @@ import { getLayoutSettings } from './ThemeLab.styles';
import useLayoutStore from '../../store/layoutStore';
import SurfaceItem from '../../components/SurfaceMenu/SurfaceItem';
import useHeaderItemsStore from '../../store/headerItemsStore';
+import useMessageItemsStore from '../../store/messageItemsStore';
+import useChatInputItemsStore from '../../store/chatInputItemsStore';
const LayoutSetting = () => {
const styles = getLayoutSettings(useTheme());
@@ -50,6 +52,28 @@ const LayoutSetting = () => {
menuItems: state.menuItems,
}));
+ const {
+ surfaceItems: messageSurfaceItems,
+ setSurfaceItems: setMessageSurfaceItems,
+ menuItems: messageMenuItems,
+ } = useMessageItemsStore((state) => ({
+ surfaceItems: state.surfaceItems,
+ setSurfaceItems: state.setSurfaceItems,
+ menuItems: state.menuItems,
+ }));
+
+ const {
+ surfaceItems: inputSurfaceItems,
+ setSurfaceItems: setInputSurfaceItems,
+ formatters,
+ setFormatters,
+ } = useChatInputItemsStore((state) => ({
+ surfaceItems: state.surfaceItems,
+ setSurfaceItems: state.setSurfaceItems,
+ formatters: state.formatters,
+ setFormatters: state.setFormatters,
+ }));
+
const addHeaderSurfaceItem = useCallback(
(id) => {
if (!headerSurfaceItems.includes(id) && !headerMenuItems.includes(id)) {
@@ -59,6 +83,33 @@ const LayoutSetting = () => {
[headerMenuItems, headerSurfaceItems, setHeaderSurfaceItems]
);
+ const addMessageSurfaceItem = useCallback(
+ (id) => {
+ if (!messageSurfaceItems.includes(id) && !messageMenuItems.includes(id)) {
+ setMessageSurfaceItems([id, ...messageSurfaceItems]);
+ }
+ },
+ [messageMenuItems, messageSurfaceItems, setMessageSurfaceItems]
+ );
+
+ const addInputSurfaceItem = useCallback(
+ (id) => {
+ if (!inputSurfaceItems.includes(id)) {
+ setInputSurfaceItems([id, ...inputSurfaceItems]);
+ }
+ },
+ [inputSurfaceItems, setInputSurfaceItems]
+ );
+
+ const addFormatters = useCallback(
+ (id) => {
+ if (!formatters.includes(id)) {
+ setFormatters([id, ...formatters]);
+ }
+ },
+ [formatters, setFormatters]
+ );
+
const headerOptions = useMemo(
() => ({
minmax: {
@@ -69,14 +120,7 @@ const LayoutSetting = () => {
addHeaderSurfaceItem('minmax');
},
},
- close: {
- label: 'Close',
- id: 'close',
- onClick: () => {
- addHeaderSurfaceItem('close');
- },
- iconName: 'cross',
- },
+
thread: {
label: 'Threads',
id: 'thread',
@@ -149,17 +193,217 @@ const LayoutSetting = () => {
},
iconName: 'reply-directly',
},
+
+ close: {
+ label: 'Close',
+ id: 'close',
+ onClick: () => {
+ addHeaderSurfaceItem('close');
+ },
+ iconName: 'cross',
+ },
}),
[addHeaderSurfaceItem]
);
- const surfaceOptions = Object.keys(headerOptions).map((key) => ({
+ const inputOptions = useMemo(() => {
+ return {
+ emoji: {
+ label: 'Emoji',
+ id: 'emoji',
+ onClick: () => {
+ addInputSurfaceItem('emoji');
+ },
+ iconName: 'emoji',
+ visible: true,
+ },
+ audio: {
+ label: 'Audio Message',
+ id: 'audio',
+ onClick: () => {
+ addInputSurfaceItem('audio');
+ },
+ iconName: 'mic',
+ visible: true,
+ },
+ video: {
+ label: 'Video Message',
+ id: 'video',
+ onClick: () => {
+ addInputSurfaceItem('video');
+ },
+ iconName: 'video-recorder',
+ visible: true,
+ },
+ file: {
+ label: 'Upload File',
+ id: 'file',
+ onClick: () => {
+ addInputSurfaceItem('file');
+ },
+ iconName: 'attachment',
+ visible: true,
+ },
+ formatter: {
+ label: 'Formatter',
+ id: 'formatter',
+ onClick: () => {
+ addInputSurfaceItem('formatter');
+ },
+ iconName: 'format-text',
+ visible: true,
+ },
+ };
+ }, [addInputSurfaceItem]);
+
+ const formatterOptions = useMemo(() => {
+ return {
+ bold: {
+ label: 'Bold',
+ id: 'bold',
+ onClick: () => {
+ addFormatters('bold');
+ },
+ iconName: 'bold',
+ visible: true,
+ },
+ italic: {
+ label: 'Italic',
+ id: 'italic',
+ onClick: () => {
+ addFormatters('italic');
+ },
+ iconName: 'italic',
+ visible: true,
+ },
+ strike: {
+ label: 'Strike',
+ id: 'strike',
+ onClick: () => {
+ addFormatters('strike');
+ },
+ iconName: 'strike',
+ visible: true,
+ },
+ code: {
+ label: 'Code',
+ id: 'code',
+ onClick: () => {
+ addFormatters('code');
+ },
+ iconName: 'code',
+ visible: true,
+ },
+ multiline: {
+ label: 'Multiline',
+ id: 'multiline',
+ onClick: () => {
+ addFormatters('multiline');
+ },
+ iconName: 'multiline',
+ visible: true,
+ },
+ };
+ }, [addFormatters]);
+
+ const messageOptions = useMemo(
+ () => ({
+ reply: {
+ label: 'Reply in thread',
+ id: 'reply',
+ onClick: () => {
+ addMessageSurfaceItem('reply');
+ },
+ iconName: 'thread',
+ },
+ quote: {
+ label: 'Quote',
+ id: 'quote',
+ onClick: () => {
+ addMessageSurfaceItem('quote');
+ },
+ iconName: 'quote',
+ },
+ star: {
+ label: 'Star',
+ id: 'star',
+ onClick: () => {
+ addMessageSurfaceItem('star');
+ },
+ iconName: 'star',
+ },
+ reaction: {
+ label: 'Add reaction',
+ id: 'reaction',
+ onClick: () => {
+ addMessageSurfaceItem('reaction');
+ },
+ iconName: 'emoji',
+ },
+ pin: {
+ label: 'Pin',
+ id: 'pin',
+ onClick: () => {
+ addMessageSurfaceItem('pin');
+ },
+ iconName: 'pin',
+ },
+ edit: {
+ label: 'Edit',
+ id: 'edit',
+ onClick: () => {
+ addMessageSurfaceItem('edit');
+ },
+ iconName: 'edit',
+ },
+ delete: {
+ label: 'Delete',
+ id: 'delete',
+ onClick: () => {
+ addMessageSurfaceItem('delete');
+ },
+ iconName: 'trash',
+ },
+ report: {
+ label: 'Report',
+ id: 'report',
+ onClick: () => {
+ addMessageSurfaceItem('report');
+ },
+ iconName: 'report',
+ },
+ }),
+ [addMessageSurfaceItem]
+ );
+
+ const headerSurfaceOptions = Object.keys(headerOptions).map((key) => ({
id: headerOptions[key].id,
onClick: headerOptions[key].onClick,
label: headerOptions[key].label,
iconName: headerOptions[key].iconName,
}));
+ const messageSurfaceOptions = Object.keys(messageOptions).map((key) => ({
+ id: messageOptions[key].id,
+ onClick: messageOptions[key].onClick,
+ label: messageOptions[key].label,
+ iconName: messageOptions[key].iconName,
+ }));
+
+ const inputSurfaceOptions = Object.keys(inputOptions).map((key) => ({
+ id: inputOptions[key].id,
+ onClick: inputOptions[key].onClick,
+ label: inputOptions[key].label,
+ iconName: inputOptions[key].iconName,
+ }));
+
+ const formatterItems = Object.keys(formatterOptions).map((key) => ({
+ id: formatterOptions[key].id,
+ onClick: formatterOptions[key].onClick,
+ label: formatterOptions[key].label,
+ iconName: formatterOptions[key].iconName,
+ }));
+
return (
@@ -197,7 +441,28 @@ const LayoutSetting = () => {
Header Items
- {surfaceOptions?.map((item, idx) => (
+ {headerSurfaceOptions?.map((item, idx) => (
+
+ ))}
+
+
+ Message Items
+
+ {messageSurfaceOptions?.map((item, idx) => (
+
+ ))}
+
+
+ Input Items
+
+ {inputSurfaceOptions?.map((item, idx) => (
+
+ ))}
+
+
+ Formatter Items
+
+ {formatterItems?.map((item, idx) => (
))}
From 7ca735a9ae140477a6190823a3cd46a0c6a96c1d Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Fri, 19 Jul 2024 19:43:55 +0530
Subject: [PATCH 061/104] fixed stylings
---
packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx | 2 +-
packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
index c01e84d00..20843b421 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
@@ -17,7 +17,7 @@ const ThemeLab = () => {
const [paletteActive, setPaletteAction] = useState(true);
return (
-
+
setThemeLabOpen(false)}
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
index 6be962fde..405ca4684 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
@@ -81,6 +81,7 @@ export const getLayoutSettings = ({ colors }) => {
itemContainer: css`
display: flex;
+ flex-wrap: wrap;
padding: 0.5rem 0;
`,
};
From 6cd849fa2b3e2a5720f80872601da4e227c413bf Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Fri, 19 Jul 2024 23:00:26 +0530
Subject: [PATCH 062/104] added mode shift
---
packages/layout_editor/src/App.jsx | 8 +++-
.../layout_editor/src/theme/DefaultTheme.js | 9 ----
.../src/views/ChatLayout/ChatLayout.jsx | 5 ++-
.../layout_editor/src/views/LayoutEditor.jsx | 34 ++++++---------
.../src/views/LayoutEditor.style.js | 42 +++++++++++--------
.../src/views/ThemeLab/LayoutSetting.jsx | 4 +-
.../src/views/ThemeLab/PaletteSetting.jsx | 35 +++++++++++++++-
.../src/views/ThemeLab/ThemeLab.styles.js | 20 +++++----
8 files changed, 96 insertions(+), 61 deletions(-)
diff --git a/packages/layout_editor/src/App.jsx b/packages/layout_editor/src/App.jsx
index 0e7bcf715..ecf12b6fe 100644
--- a/packages/layout_editor/src/App.jsx
+++ b/packages/layout_editor/src/App.jsx
@@ -1,8 +1,14 @@
import React from 'react';
import LayoutEditor from './views/LayoutEditor';
+import { ThemeProvider } from '@embeddedchat/ui-elements';
+import DefaultTheme from './theme/DefaultTheme';
const App = () => {
- return ;
+ return (
+
+ ;
+
+ );
};
export default App;
diff --git a/packages/layout_editor/src/theme/DefaultTheme.js b/packages/layout_editor/src/theme/DefaultTheme.js
index da20fd7ac..fc12ed9e9 100644
--- a/packages/layout_editor/src/theme/DefaultTheme.js
+++ b/packages/layout_editor/src/theme/DefaultTheme.js
@@ -71,15 +71,6 @@ const DefaultTheme = {
},
},
- breakpoints: {
- xs: 0,
- sm: 600,
- md: 900,
- lg: 1200,
- xl: 1536,
- },
- components: {},
-
typography: {
default: {
fontFamily: "'Times New Roman', serif",
diff --git a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
index ae6175f5d..8835a955f 100644
--- a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
+++ b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
@@ -8,7 +8,9 @@ import DemoSidebar from '../DemoSidebar/DemoSidebar';
import members from '../../data/members.json';
const ChatLayout = () => {
- const styles = getChatLayoutStyles(useTheme());
+ const theme = useTheme();
+ const styles = getChatLayoutStyles(theme);
+ const { colors } = theme;
const handleResize = (size) => {
const minSize = 26.5;
@@ -36,6 +38,7 @@ const ChatLayout = () => {
diff --git a/packages/layout_editor/src/views/LayoutEditor.jsx b/packages/layout_editor/src/views/LayoutEditor.jsx
index b94da6958..106095f90 100644
--- a/packages/layout_editor/src/views/LayoutEditor.jsx
+++ b/packages/layout_editor/src/views/LayoutEditor.jsx
@@ -1,34 +1,26 @@
-import React, { useState } from 'react';
-import DefaultTheme from '../theme/DefaultTheme';
-import { Box, ThemeProvider } from '@embeddedchat/ui-elements';
-import { styles } from './LayoutEditor.style';
+import React from 'react';
+import { Box, useTheme } from '@embeddedchat/ui-elements';
import ChatLayout from './ChatLayout/ChatLayout';
import ChatHeader from './ChatHeader/ChatHeader';
import GlobalStyles from './GlobalStyles';
import useLayoutStore from '../store/layoutStore';
import ThemeLab from './ThemeLab/ThemeLab';
+import { getEditorStyles } from './LayoutEditor.style';
const LayoutEditor = () => {
- const [mode, setMode] = useState('light');
const themeLabOpen = useLayoutStore((state) => state.themeLabOpen);
+ const styles = getEditorStyles(useTheme());
+
return (
-
-
-
-
-
-
-
-
- {themeLabOpen && }
+
+
+
+
+
+
-
+ {themeLabOpen && }
+
);
};
diff --git a/packages/layout_editor/src/views/LayoutEditor.style.js b/packages/layout_editor/src/views/LayoutEditor.style.js
index f34c535b7..61451c36b 100644
--- a/packages/layout_editor/src/views/LayoutEditor.style.js
+++ b/packages/layout_editor/src/views/LayoutEditor.style.js
@@ -1,22 +1,28 @@
import { css } from '@emotion/react';
-export const styles = {
- embeddedchat: (theme, dark) => css`
- width: 75%;
- position: relative;
- background: ${theme.schemes[dark ? 'dark' : 'light'].background};
- color: ${theme.schemes[dark ? 'dark' : 'light'].foreground};
- display: flex;
- flex: 1;
- flex-direction: column;
- border: ${`1.5px solid ${theme.schemes[dark ? 'dark' : 'light'].border}`};
- border-radius: ${theme.schemes.radius};
- overflow: hidden;
- `,
+export const getEditorStyles = ({ theme, colors }) => {
+ const styles = {
+ embeddedchat: css`
+ width: 75%;
+ position: relative;
+ background: ${colors.background};
+ color: ${colors.foreground};
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ border: ${`1.5px solid ${theme.schemes.border}`};
+ border-radius: ${theme.schemes.radius};
+ overflow: hidden;
+ `,
- layoutEditor: css`
- height: 100vh;
- display: flex;
- gap: 0.25rem;
- `,
+ layoutEditor: css`
+ background: ${colors.background};
+ color: ${colors.foreground};
+ height: 100vh;
+ display: flex;
+ gap: 0.25rem;
+ `,
+ };
+
+ return styles;
};
diff --git a/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx b/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
index f2fd06d5c..d92e8eb4b 100644
--- a/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
@@ -408,7 +408,7 @@ const LayoutSetting = () => {
Variants
-
+
Message View
{
/>
-
+
Display Name
{
- const styles = getPaletteSettings(useTheme());
+ const theme = useTheme();
+ const styles = getPaletteSettings(theme);
+
+ const { mode, setMode } = theme;
+
+ const modeOptions = [
+ {
+ label: 'Light',
+ value: 'light',
+ },
+
+ {
+ label: 'Dark',
+ value: 'dark',
+ },
+ ];
+
return (
Colors
+
+ Mode
+
+
Typography
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
index 405ca4684..c093c91c5 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
@@ -26,13 +26,26 @@ export const getPaletteSettings = ({ colors }) => {
height: 100%;
display: flex;
flex-direction: column;
+ gap: 1.5rem;
padding: 0.75rem;
`,
colorSection: css`
padding: 0.5rem;
+ background-color: ${colors.secondary};
+ border-radius: 0.25rem;
`,
typographySection: css`
padding: 0.5rem;
+ background-color: ${colors.secondary};
+ border-radius: 0.25rem;
+ `,
+
+ commonSelect: css`
+ display: flex;
+ gap: 1.25rem;
+ justify-content: space-between;
+ padding: 1.25rem 0;
+ position: relative;
`,
};
@@ -65,13 +78,6 @@ export const getLayoutSettings = ({ colors }) => {
gap: 1.25rem;
justify-content: space-between;
padding: 1.25rem 0;
- `,
-
- messageView: css`
- position: relative;
- `,
-
- displayName: css`
position: relative;
`,
From 0240ab21d8ee1cae87f26fc6a2580caf1bdb11fb Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 01:23:56 +0530
Subject: [PATCH 063/104] added color manager
---
packages/layout_editor/package.json | 1 +
packages/layout_editor/src/App.jsx | 2 +-
.../src/views/ThemeLab/ColorManager.jsx | 86 +++++++++++++++++++
.../src/views/ThemeLab/LayoutSetting.jsx | 24 ++++--
.../src/views/ThemeLab/ThemeLab.jsx | 6 +-
.../src/views/ThemeLab/ThemeLab.styles.js | 27 ++++++
.../{PaletteSetting.jsx => ThemeSetting.jsx} | 21 +++--
7 files changed, 151 insertions(+), 16 deletions(-)
create mode 100644 packages/layout_editor/src/views/ThemeLab/ColorManager.jsx
rename packages/layout_editor/src/views/ThemeLab/{PaletteSetting.jsx => ThemeSetting.jsx} (66%)
diff --git a/packages/layout_editor/package.json b/packages/layout_editor/package.json
index b712eb838..b554c260d 100644
--- a/packages/layout_editor/package.json
+++ b/packages/layout_editor/package.json
@@ -14,6 +14,7 @@
"@dnd-kit/sortable": "^8.0.0",
"@embeddedchat/ui-elements": "workspace:^",
"react": "^18.2.0",
+ "react-color": "^2.19.3",
"react-dom": "^18.2.0",
"react-resizable-panels": "^2.0.20"
},
diff --git a/packages/layout_editor/src/App.jsx b/packages/layout_editor/src/App.jsx
index ecf12b6fe..0163e1a11 100644
--- a/packages/layout_editor/src/App.jsx
+++ b/packages/layout_editor/src/App.jsx
@@ -6,7 +6,7 @@ import DefaultTheme from './theme/DefaultTheme';
const App = () => {
return (
- ;
+
);
};
diff --git a/packages/layout_editor/src/views/ThemeLab/ColorManager.jsx b/packages/layout_editor/src/views/ThemeLab/ColorManager.jsx
new file mode 100644
index 000000000..9842b8181
--- /dev/null
+++ b/packages/layout_editor/src/views/ThemeLab/ColorManager.jsx
@@ -0,0 +1,86 @@
+import React, { useState, useRef, useEffect } from 'react';
+import { Box, useTheme } from '@embeddedchat/ui-elements';
+import { ChromePicker } from 'react-color';
+import { getColorMangerStyles } from './ThemeLab.styles';
+
+const ColorPicker = ({ color, onChange }) => {
+ return (
+ onChange(updatedColor.hsl)}
+ />
+ );
+};
+
+const ColorManager = () => {
+ const { theme, mode } = useTheme();
+ const styles = getColorMangerStyles(theme);
+ const [visiblePicker, setVisiblePicker] = useState(null);
+ const [lightColors, setLightColors] = useState(theme.schemes.light);
+ const [darkColors, setDarkColors] = useState(theme.schemes.dark);
+ const pickerRef = useRef(null);
+
+ const handleColorChange = (key, hsl) => {
+ if (mode === 'light') {
+ setLightColors((prevColors) => ({
+ ...prevColors,
+ [key]: `hsl(${hsl.h}, ${hsl.s * 100}%, ${hsl.l * 100}%)`,
+ }));
+ } else {
+ setDarkColors((prevColors) => ({
+ ...prevColors,
+ [key]: `hsl(${hsl.h}, ${hsl.s * 100}%, ${hsl.l * 100}%)`,
+ }));
+ }
+ };
+
+ const togglePicker = (key) => {
+ setVisiblePicker((prevKey) => (prevKey === key ? null : key));
+ };
+
+ const handleClickOutside = (event) => {
+ if (pickerRef.current && !pickerRef.current.contains(event.target)) {
+ setVisiblePicker(null);
+ }
+ };
+
+ useEffect(() => {
+ document.addEventListener('mousedown', handleClickOutside);
+ return () => {
+ document.removeEventListener('mousedown', handleClickOutside);
+ };
+ }, []);
+
+ const colors = mode === 'light' ? lightColors : darkColors;
+
+ return (
+
+ {Object.entries(colors).map(([key, value]) => (
+
+ {key}:
+ togglePicker(key)}
+ />
+ {visiblePicker === key && (
+
+ handleColorChange(key, newColor)}
+ />
+
+ )}
+
+ ))}
+
+ );
+};
+
+export default ColorManager;
diff --git a/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx b/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
index d92e8eb4b..0eba8d6ea 100644
--- a/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/LayoutSetting.jsx
@@ -409,7 +409,9 @@ const LayoutSetting = () => {
Variants
- Message View
+
+ Message View
+
{
- Display Name
+
+ Display Name
+
{
Tool Tray
- Header Items
+
+ Header Items
+
{headerSurfaceOptions?.map((item, idx) => (
))}
- Message Items
+
+ Message Items
+
{messageSurfaceOptions?.map((item, idx) => (
))}
- Input Items
+
+ Input Items
+
{inputSurfaceOptions?.map((item, idx) => (
))}
- Formatter Items
+
+ Formatter Items
+
{formatterItems?.map((item, idx) => (
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
index 20843b421..e01caf6a6 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
@@ -8,8 +8,8 @@ import {
} from '@embeddedchat/ui-elements';
import useLayoutStore from '../../store/layoutStore';
import { getThemeLabStyles } from './ThemeLab.styles';
-import PaletteSetting from './PaletteSetting';
import LayoutSetting from './LayoutSetting';
+import ThemeSetting from './ThemeSetting';
const ThemeLab = () => {
const styles = getThemeLabStyles(useTheme());
@@ -31,7 +31,7 @@ const ThemeLab = () => {
css={[styles.section, paletteActive && styles.sectionActive]}
onClick={() => setPaletteAction(true)}
>
- Palette
+ Theme
{
- {paletteActive ? : }
+ {paletteActive ? : }
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
index c093c91c5..236f23db2 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
@@ -47,6 +47,12 @@ export const getPaletteSettings = ({ colors }) => {
padding: 1.25rem 0;
position: relative;
`,
+
+ palette: css`
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ `,
};
return styles;
@@ -94,3 +100,24 @@ export const getLayoutSettings = ({ colors }) => {
return styles;
};
+
+export const getColorMangerStyles = () => {
+ const styles = {
+ pickerContainer: css`
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0.5rem 0.25rem;
+ `,
+
+ colorPicker: css`
+ position: absolute;
+ top: 100%;
+ right: 0;
+ z-index: 1;
+ `,
+ };
+
+ return styles;
+};
diff --git a/packages/layout_editor/src/views/ThemeLab/PaletteSetting.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeSetting.jsx
similarity index 66%
rename from packages/layout_editor/src/views/ThemeLab/PaletteSetting.jsx
rename to packages/layout_editor/src/views/ThemeLab/ThemeSetting.jsx
index 4acf122fc..2037048fb 100644
--- a/packages/layout_editor/src/views/ThemeLab/PaletteSetting.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeSetting.jsx
@@ -1,12 +1,13 @@
import React from 'react';
import { Box, StaticSelect, useTheme } from '@embeddedchat/ui-elements';
import { getPaletteSettings } from './ThemeLab.styles';
+import ColorManager from './ColorManager';
-const PaletteSetting = () => {
- const theme = useTheme();
- const styles = getPaletteSettings(theme);
+const ThemeSetting = () => {
+ const themeObject = useTheme();
+ const styles = getPaletteSettings(themeObject);
- const { mode, setMode } = theme;
+ const { mode, setMode } = themeObject;
const modeOptions = [
{
@@ -25,7 +26,9 @@ const PaletteSetting = () => {
Colors
- Mode
+
+ Mode
+
{
onSelect={setMode}
/>
+
+
+ Palette
+
+
+
Typography
@@ -47,4 +56,4 @@ const PaletteSetting = () => {
);
};
-export default PaletteSetting;
+export default ThemeSetting;
From e9477693392bca53b8158744e00b65264d6fa34d Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 12:02:03 +0530
Subject: [PATCH 064/104] added live theme color view
---
.../src/views/ThemeLab/ColorManager.jsx | 49 +++++++++++++------
.../src/views/ThemeLab/ThemeLab.styles.js | 8 +--
.../MessageAggregators/SearchMessages.js | 2 +-
3 files changed, 39 insertions(+), 20 deletions(-)
diff --git a/packages/layout_editor/src/views/ThemeLab/ColorManager.jsx b/packages/layout_editor/src/views/ThemeLab/ColorManager.jsx
index 9842b8181..bf360fa4d 100644
--- a/packages/layout_editor/src/views/ThemeLab/ColorManager.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ColorManager.jsx
@@ -1,7 +1,8 @@
-import React, { useState, useRef, useEffect } from 'react';
+import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react';
import { Box, useTheme } from '@embeddedchat/ui-elements';
import { ChromePicker } from 'react-color';
import { getColorMangerStyles } from './ThemeLab.styles';
+import debounce from 'lodash/debounce';
const ColorPicker = ({ color, onChange }) => {
return (
@@ -14,26 +15,44 @@ const ColorPicker = ({ color, onChange }) => {
};
const ColorManager = () => {
- const { theme, mode } = useTheme();
+ const { theme, mode, setTheme } = useTheme();
const styles = getColorMangerStyles(theme);
const [visiblePicker, setVisiblePicker] = useState(null);
const [lightColors, setLightColors] = useState(theme.schemes.light);
const [darkColors, setDarkColors] = useState(theme.schemes.dark);
const pickerRef = useRef(null);
- const handleColorChange = (key, hsl) => {
- if (mode === 'light') {
- setLightColors((prevColors) => ({
- ...prevColors,
- [key]: `hsl(${hsl.h}, ${hsl.s * 100}%, ${hsl.l * 100}%)`,
- }));
- } else {
- setDarkColors((prevColors) => ({
- ...prevColors,
- [key]: `hsl(${hsl.h}, ${hsl.s * 100}%, ${hsl.l * 100}%)`,
- }));
- }
- };
+ const debouncedSetTheme = useMemo(
+ () =>
+ debounce((newLightColors, newDarkColors) => {
+ const updatedTheme = {
+ ...theme,
+ schemes: {
+ ...theme.schemes,
+ light: newLightColors,
+ dark: newDarkColors,
+ },
+ };
+ setTheme(updatedTheme);
+ }, 300),
+ [theme, setTheme]
+ );
+
+ const handleColorChange = useCallback(
+ (key, hsl) => {
+ const updatedColor = `hsl(${hsl.h}, ${hsl.s * 100}%, ${hsl.l * 100}%)`;
+ if (mode === 'light') {
+ const newLightColors = { ...lightColors, [key]: updatedColor };
+ setLightColors(newLightColors);
+ debouncedSetTheme(newLightColors, darkColors);
+ } else {
+ const newDarkColors = { ...darkColors, [key]: updatedColor };
+ setDarkColors(newDarkColors);
+ debouncedSetTheme(lightColors, newDarkColors);
+ }
+ },
+ [mode, lightColors, darkColors, debouncedSetTheme]
+ );
const togglePicker = (key) => {
setVisiblePicker((prevKey) => (prevKey === key ? null : key));
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
index 236f23db2..162f701f1 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
@@ -31,13 +31,13 @@ export const getPaletteSettings = ({ colors }) => {
`,
colorSection: css`
padding: 0.5rem;
- background-color: ${colors.secondary};
border-radius: 0.25rem;
+ border: 1px solid ${colors.border};
`,
typographySection: css`
padding: 0.5rem;
- background-color: ${colors.secondary};
border-radius: 0.25rem;
+ border: 1px solid ${colors.border};
`,
commonSelect: css`
@@ -69,13 +69,13 @@ export const getLayoutSettings = ({ colors }) => {
`,
variantSection: css`
padding: 0.5rem;
- background-color: ${colors.secondary};
+ border: 1px solid ${colors.border};
border-radius: 0.25rem;
`,
toolSection: css`
padding: 0.5rem;
- background-color: ${colors.secondary};
+ border: 1px solid ${colors.border};
border-radius: 0.25rem;
`,
diff --git a/packages/react/src/views/MessageAggregators/SearchMessages.js b/packages/react/src/views/MessageAggregators/SearchMessages.js
index 5f55cf934..e627921c8 100644
--- a/packages/react/src/views/MessageAggregators/SearchMessages.js
+++ b/packages/react/src/views/MessageAggregators/SearchMessages.js
@@ -1,5 +1,5 @@
import React, { useState, useContext, useEffect } from 'react';
-import { debounce } from 'lodash';
+import debounce from 'lodash/debounce';
import { useComponentOverrides } from '@embeddedchat/ui-elements';
import RCContext from '../../context/RCInstance';
import { MessageAggregator } from './common/MessageAggregator';
From 8185a8a9c097573c2baf28cab2ee02d1c20e894d Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 12:52:04 +0530
Subject: [PATCH 065/104] added lighten to match theme
---
packages/react/src/views/ChatHeader/ChatHeader.styles.js | 4 ++--
packages/react/src/views/ChatInput/ChatInput.styles.js | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/packages/react/src/views/ChatHeader/ChatHeader.styles.js b/packages/react/src/views/ChatHeader/ChatHeader.styles.js
index 09271f7af..656a08675 100644
--- a/packages/react/src/views/ChatHeader/ChatHeader.styles.js
+++ b/packages/react/src/views/ChatHeader/ChatHeader.styles.js
@@ -1,6 +1,6 @@
import { css } from '@emotion/react';
-import { useTheme, darken } from '@embeddedchat/ui-elements';
+import { useTheme, darken, lighten } from '@embeddedchat/ui-elements';
const rowCentreAlign = css`
display: flex;
@@ -25,7 +25,7 @@ const useChatHeaderStyles = () => {
const chatHeaderParent = css`
background-color: ${mode === 'light'
? darken(colors.background, 0.03)
- : colors.secondary};
+ : lighten(colors.background, 1)};
width: 100%;
z-index: ${theme.zIndex.general};
display: flex;
diff --git a/packages/react/src/views/ChatInput/ChatInput.styles.js b/packages/react/src/views/ChatInput/ChatInput.styles.js
index fe6176b42..cd20819cf 100644
--- a/packages/react/src/views/ChatInput/ChatInput.styles.js
+++ b/packages/react/src/views/ChatInput/ChatInput.styles.js
@@ -1,5 +1,5 @@
import { css } from '@emotion/react';
-import { darken, useTheme } from '@embeddedchat/ui-elements';
+import { darken, lighten, useTheme } from '@embeddedchat/ui-elements';
export const useChatInputStyles = () => {
const { theme, colors } = useTheme();
@@ -71,7 +71,7 @@ export const useChatInputFormattingToolbarStyles = () => {
align-items: center;
background-color: ${mode === 'light'
? darken(colors.background, 0.03)
- : colors.secondary};
+ : lighten(colors.background, 1)};
display: flex;
position: relative;
flex-direction: row;
From ad6d1d85c4d30b99dbc0f601741f43933b4d6166 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 12:52:39 +0530
Subject: [PATCH 066/104] added listener to change theme when changed
externally
---
.../src/context/ThemeContextProvider.js | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/packages/ui-elements/src/context/ThemeContextProvider.js b/packages/ui-elements/src/context/ThemeContextProvider.js
index 207a5fb57..084a1a9e4 100644
--- a/packages/ui-elements/src/context/ThemeContextProvider.js
+++ b/packages/ui-elements/src/context/ThemeContextProvider.js
@@ -1,4 +1,4 @@
-import React, { createContext, useMemo, useState } from 'react';
+import React, { createContext, useMemo, useState, useEffect } from 'react';
import DefaultTheme from '../theme/DefaultTheme';
const invertMode = (mode) => (mode === 'light' ? 'dark' : 'light');
@@ -17,6 +17,18 @@ export const ThemeProvider = ({
const colors = theme.schemes?.[mode];
const invertedColors = theme.schemes?.[invertMode(mode)];
+ useEffect(() => {
+ if (initialTheme) {
+ setTheme(initialTheme);
+ }
+ }, [initialTheme]);
+
+ useEffect(() => {
+ if (initialMode) {
+ setMode(initialMode);
+ }
+ }, [initialMode]);
+
const value = useMemo(
() => ({
theme,
From aae1c89788ecf58c7f61b4bd13bad758bc8e76c1 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 13:14:12 +0530
Subject: [PATCH 067/104] fixed some stylings
---
.../src/views/ChatHeader/ChatHeader.styles.js | 8 ++++----
.../src/views/ChatInput/ChatInput.styles.js | 8 ++++----
.../src/views/ThemeLab/ColorManager.jsx | 12 ++++++++++--
.../src/views/ThemeLab/ThemeLab.styles.js | 6 ++++++
4 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js b/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
index 101837e06..1052f066e 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
@@ -1,5 +1,5 @@
-import { css } from "@emotion/react";
-import { darken } from "@embeddedchat/ui-elements";
+import { css } from '@emotion/react';
+import { darken, lighten } from '@embeddedchat/ui-elements';
export const getChatHeaderStyles = ({ theme, mode, colors }) => {
const styles = {
@@ -18,9 +18,9 @@ export const getChatHeaderStyles = ({ theme, mode, colors }) => {
`,
chatHeaderParent: css`
- background-color: ${mode === "light"
+ background-color: ${mode === 'light'
? darken(colors.background, 0.03)
- : colors.secondary};
+ : lighten(colors.background, 1)};
width: 100%;
z-index: ${theme.zIndex.general};
display: flex;
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js b/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
index c38db696c..03d3f2563 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
+++ b/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
@@ -1,5 +1,5 @@
-import { css } from "@emotion/react";
-import { darken } from "@embeddedchat/ui-elements";
+import { css } from '@emotion/react';
+import { darken, lighten } from '@embeddedchat/ui-elements';
export const getChatInputStyles = ({ theme, colors }) => {
const styles = {
@@ -54,9 +54,9 @@ export const getChatInputToolbarStyles = ({ theme, mode, colors }) => {
bottom: 0;
padding: 0.2rem;
align-items: center;
- background-color: ${mode === "light"
+ background-color: ${mode === 'light'
? darken(colors.background, 0.03)
- : colors.secondary};
+ : lighten(colors.background, 1)};
display: flex;
position: relative;
flex-direction: row;
diff --git a/packages/layout_editor/src/views/ThemeLab/ColorManager.jsx b/packages/layout_editor/src/views/ThemeLab/ColorManager.jsx
index bf360fa4d..047bcfbb7 100644
--- a/packages/layout_editor/src/views/ThemeLab/ColorManager.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ColorManager.jsx
@@ -1,4 +1,10 @@
-import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react';
+import React, {
+ useState,
+ useRef,
+ useEffect,
+ useCallback,
+ useMemo,
+} from 'react';
import { Box, useTheme } from '@embeddedchat/ui-elements';
import { ChromePicker } from 'react-color';
import { getColorMangerStyles } from './ThemeLab.styles';
@@ -80,8 +86,10 @@ const ColorManager = () => {
{key}:
{
top: 100%;
right: 0;
z-index: 1;
+
+ .saturation-white,
+ .saturation-black,
+ .hue-horizontal {
+ cursor: pointer;
+ }
`,
};
From 9a49d4edeec31774be076748564dfc72d4ac3ffe Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 14:49:16 +0530
Subject: [PATCH 068/104] added default heading styles when theme is not
present
---
.../src/components/Heading/Heading.js | 40 +++++++++++++++++--
1 file changed, 37 insertions(+), 3 deletions(-)
diff --git a/packages/ui-elements/src/components/Heading/Heading.js b/packages/ui-elements/src/components/Heading/Heading.js
index 2e38ec93b..8cce39bd4 100644
--- a/packages/ui-elements/src/components/Heading/Heading.js
+++ b/packages/ui-elements/src/components/Heading/Heading.js
@@ -1,11 +1,45 @@
import React from 'react';
import { css } from '@emotion/react';
-import useTheme from '../../hooks/useTheme';
+import { useTheme } from '../../hooks';
const Heading = ({ level = 1, children, ...props }) => {
- const { theme } = useTheme();
+ const defaultTypography = {
+ h1: {
+ fontSize: '2rem',
+ fontWeight: 800,
+ lineHeight: 1.5,
+ },
+ h2: {
+ fontSize: '1.5rem',
+ fontWeight: 800,
+ lineHeight: 1.4,
+ },
+ h3: {
+ fontSize: '1.3rem',
+ fontWeight: 400,
+ lineHeight: 1.3,
+ },
+ h4: {
+ fontSize: '1rem',
+ fontWeight: 400,
+ lineHeight: 1.2,
+ },
+ h5: {
+ fontSize: '0.83rem',
+ fontWeight: 400,
+ lineHeight: 1.1,
+ },
+ h6: {
+ fontSize: '0.67rem',
+ fontWeight: 500,
+ lineHeight: 1.0,
+ },
+ };
+
const Tag = `h${level}`;
- const style = theme.typography[Tag];
+ const { theme } = useTheme();
+ const style = { ...defaultTypography[Tag], ...theme.typography[Tag] };
+
return (
Date: Sat, 20 Jul 2024 15:06:02 +0530
Subject: [PATCH 069/104] added default zIndex
---
.../src/components/Menu/Menu.styles.js | 2 +-
.../src/components/Modal/Modal.styles.js | 2 +-
.../src/components/Popup/Popup.styles.js | 2 +-
.../src/components/Sidebar/Sidebar.styles.js | 2 +-
.../components/ToastBar/ToastBar.styles.js | 4 +-
.../src/components/Tooltip/Tooltip.styles.js | 2 +-
.../ui-elements/src/theme/DefaultTheme.js | 40 -------------------
7 files changed, 7 insertions(+), 47 deletions(-)
diff --git a/packages/ui-elements/src/components/Menu/Menu.styles.js b/packages/ui-elements/src/components/Menu/Menu.styles.js
index 49d8e9c8e..131b24e88 100644
--- a/packages/ui-elements/src/components/Menu/Menu.styles.js
+++ b/packages/ui-elements/src/components/Menu/Menu.styles.js
@@ -17,7 +17,7 @@ export const useMenuStyles = () => {
flex-direction: column;
width: fit-content;
height: fit-content;
- z-index: ${theme.zIndex.menu};
+ z-index: ${theme.zIndex?.menu || 1300};
border-radius: 0.2em;
padding: 0.5rem 0;
box-shadow: ${theme.shadows[1]};
diff --git a/packages/ui-elements/src/components/Modal/Modal.styles.js b/packages/ui-elements/src/components/Modal/Modal.styles.js
index cf8a4598b..8ef5b11c1 100644
--- a/packages/ui-elements/src/components/Modal/Modal.styles.js
+++ b/packages/ui-elements/src/components/Modal/Modal.styles.js
@@ -40,7 +40,7 @@ export const useModalBackdropStyles = () => {
position: absolute;
top: 0;
right: 0;
- z-index: ${theme.zIndex.modal};
+ z-index: ${theme.zIndex?.modal || 1500};
background: ${alpha(theme.schemes.common.black, 0.5)};
width: 100%;
height: 100%;
diff --git a/packages/ui-elements/src/components/Popup/Popup.styles.js b/packages/ui-elements/src/components/Popup/Popup.styles.js
index c060c748c..0f3eaf840 100644
--- a/packages/ui-elements/src/components/Popup/Popup.styles.js
+++ b/packages/ui-elements/src/components/Popup/Popup.styles.js
@@ -9,7 +9,7 @@ export const usePopupStyles = () => {
popup: (width, height) => css`
display: flex;
flex-direction: column;
- z-index: ${theme.zIndex.modal};
+ z-index: ${theme.zIndex?.modal || 1500};
box-shadow: ${theme.shadows[2]};
border-radius: ${theme.schemes.radius};
background: ${colors.background};
diff --git a/packages/ui-elements/src/components/Sidebar/Sidebar.styles.js b/packages/ui-elements/src/components/Sidebar/Sidebar.styles.js
index a60f6a4df..84617a076 100644
--- a/packages/ui-elements/src/components/Sidebar/Sidebar.styles.js
+++ b/packages/ui-elements/src/components/Sidebar/Sidebar.styles.js
@@ -8,7 +8,7 @@ const useSidebarStyles = () => {
min-width: 350px;
height: 100%;
box-shadow: ${theme.shadows[2]};
- z-index: ${theme.zIndex.general};
+ z-index: ${theme.zIndex?.sidebar || 1200};
display: flex;
flex-direction: column;
`;
diff --git a/packages/ui-elements/src/components/ToastBar/ToastBar.styles.js b/packages/ui-elements/src/components/ToastBar/ToastBar.styles.js
index 2b047a478..731ea006b 100644
--- a/packages/ui-elements/src/components/ToastBar/ToastBar.styles.js
+++ b/packages/ui-elements/src/components/ToastBar/ToastBar.styles.js
@@ -28,7 +28,7 @@ export const toastbarStyles = {
background-color: ${bgColor};
border-radius: ${theme.schemes.radius};
padding: 0.75em 1em;
- z-index: ${theme.zIndex?.toastbar};
+ z-index: ${theme.zIndex?.toastbar || 1600};
animation: ${animation} ${time}ms ease-in-out forwards;
`,
};
@@ -36,7 +36,7 @@ export const toastbarStyles = {
export const toastBarContainerStyles = {
container: (theme) => css`
position: absolute;
- z-index: ${theme.zIndex.toastbar};
+ z-index: ${theme.zIndex?.toastbar || 1600};
border-radius: ${theme.schemes.radius};
animation: ${animation} ${2000}ms ease-in-out forwards;
`,
diff --git a/packages/ui-elements/src/components/Tooltip/Tooltip.styles.js b/packages/ui-elements/src/components/Tooltip/Tooltip.styles.js
index 4d85246e4..8ca69fbf0 100644
--- a/packages/ui-elements/src/components/Tooltip/Tooltip.styles.js
+++ b/packages/ui-elements/src/components/Tooltip/Tooltip.styles.js
@@ -12,7 +12,7 @@ const useTooltipStyles = (position) => {
padding: 8.5px;
border-radius: ${theme.schemes.radius};
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
- z-index: ${theme.zIndex.tooltip};
+ z-index: ${theme.zIndex?.tooltip || 1400};
font-size: 12.5px;
font-weight: 500;
white-space: nowrap;
diff --git a/packages/ui-elements/src/theme/DefaultTheme.js b/packages/ui-elements/src/theme/DefaultTheme.js
index bcf1ac888..5fa9eb270 100644
--- a/packages/ui-elements/src/theme/DefaultTheme.js
+++ b/packages/ui-elements/src/theme/DefaultTheme.js
@@ -61,46 +61,6 @@ const DefaultTheme = {
},
},
- breakpoints: {
- xs: 0,
- sm: 600,
- md: 900,
- lg: 1200,
- xl: 1536,
- },
- components: {},
-
- typography: {
- default: {
- fontFamily: "'Times New Roman', serif",
- fontSize: 16,
- fontWeightRegular: 400,
- },
- h1: {
- fontSize: '2rem',
- fontWeight: 800,
- },
- h2: {
- fontSize: '1.5rem',
- fontWeight: 800,
- },
- h3: {
- fontSize: '1.3rem',
- fontWeight: 400,
- },
- h4: {
- fontSize: '1rem',
- fontWeight: 400,
- },
- h5: {
- fontSize: '0.83rem',
- fontWeight: 400,
- },
- h6: {
- fontSize: '0.67rem',
- fontWeight: 500,
- },
- },
shadows: [
'none',
'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
From 7da2a05e9c82f2162673891f3ec9ca961fdfca7b Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 15:10:39 +0530
Subject: [PATCH 070/104] removed zIndex from theme in layout editor
---
.../components/SortableMenu/Menu.styles.js | 2 +-
.../layout_editor/src/theme/DefaultTheme.js | 35 +--------
.../src/views/ChatHeader/ChatHeader.styles.js | 2 +-
.../src/views/ChatInput/ChatInput.styles.js | 2 +-
.../layout_editor/src/views/GlobalStyles.jsx | 6 +-
.../Message/BubbleVariant/Bubble.styles.js | 2 +-
.../src/views/Message/Message.styles.js | 4 +-
.../src/views/ThemeLab/FontManager.jsx | 75 +++++++++++++++++++
.../src/views/ThemeLab/ThemeLab.styles.js | 20 ++++-
.../src/views/ThemeLab/ThemeSetting.jsx | 2 +
10 files changed, 103 insertions(+), 47 deletions(-)
create mode 100644 packages/layout_editor/src/views/ThemeLab/FontManager.jsx
diff --git a/packages/layout_editor/src/components/SortableMenu/Menu.styles.js b/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
index 0202e392b..6b16dd691 100644
--- a/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
+++ b/packages/layout_editor/src/components/SortableMenu/Menu.styles.js
@@ -14,7 +14,7 @@ export const getMenuStyles = ({ theme, colors }) => {
flex-direction: column;
width: fit-content;
height: fit-content;
- z-index: ${theme.zIndex.menu};
+ z-index: 1300;
border-radius: 0.2em;
padding: 0.5rem 0;
box-shadow: ${theme.shadows[1]};
diff --git a/packages/layout_editor/src/theme/DefaultTheme.js b/packages/layout_editor/src/theme/DefaultTheme.js
index fc12ed9e9..be1650b8a 100644
--- a/packages/layout_editor/src/theme/DefaultTheme.js
+++ b/packages/layout_editor/src/theme/DefaultTheme.js
@@ -72,50 +72,17 @@ const DefaultTheme = {
},
typography: {
- default: {
+ global: {
fontFamily: "'Times New Roman', serif",
fontSize: 16,
fontWeightRegular: 400,
},
- h1: {
- fontSize: '2rem',
- fontWeight: 800,
- },
- h2: {
- fontSize: '1.5rem',
- fontWeight: 800,
- },
- h3: {
- fontSize: '1.3rem',
- fontWeight: 400,
- },
- h4: {
- fontSize: '1rem',
- fontWeight: 400,
- },
- h5: {
- fontSize: '0.83rem',
- fontWeight: 400,
- },
- h6: {
- fontSize: '0.67rem',
- fontWeight: 500,
- },
},
shadows: [
'none',
'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
],
- zIndex: {
- divider: 1000,
- body: 1100,
- general: 1200,
- menu: 1300,
- tooltip: 1400,
- modal: 1500,
- toastbar: 1600,
- },
};
export default DefaultTheme;
diff --git a/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js b/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
index 1052f066e..570a7e989 100644
--- a/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
+++ b/packages/layout_editor/src/views/ChatHeader/ChatHeader.styles.js
@@ -22,7 +22,7 @@ export const getChatHeaderStyles = ({ theme, mode, colors }) => {
? darken(colors.background, 0.03)
: lighten(colors.background, 1)};
width: 100%;
- z-index: ${theme.zIndex.general};
+ z-index: 1200;
display: flex;
flex-direction: column;
padding: 0.75rem;
diff --git a/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js b/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
index 03d3f2563..92855c1b0 100644
--- a/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
+++ b/packages/layout_editor/src/views/ChatInput/ChatInput.styles.js
@@ -75,7 +75,7 @@ export const getFormatterStyles = ({ theme, colors }) => {
position: absolute;
bottom: 100%;
left: auto;
- z-index: ${theme.zIndex.body + 1};
+ z-index: 1101;
`,
toolbox: css`
diff --git a/packages/layout_editor/src/views/GlobalStyles.jsx b/packages/layout_editor/src/views/GlobalStyles.jsx
index ebdc3551f..dbca8e9af 100644
--- a/packages/layout_editor/src/views/GlobalStyles.jsx
+++ b/packages/layout_editor/src/views/GlobalStyles.jsx
@@ -10,9 +10,9 @@ const useStyles = ({ colors, theme }) => css`
}
body {
- font-family: ${theme.typography.default.fontFamily};
- font-size: ${theme.typography.default.fontSize}px;
- font-weight: ${theme.typography.default.fontWeightRegular};
+ font-family: ${theme.typography.global.fontFamily};
+ font-size: ${theme.typography.global.fontSize}px;
+ font-weight: ${theme.typography.global.fontWeightRegular};
}
a {
diff --git a/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js b/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js
index b90c0f406..0bc6c7ce0 100644
--- a/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js
+++ b/packages/layout_editor/src/views/Message/BubbleVariant/Bubble.styles.js
@@ -81,7 +81,7 @@ export const bubbleStyles = ({ theme, colors }) => {
position: absolute;
bottom: calc(100% - 20px);
left: calc(100% - 20px);
- z-index: ${theme.zIndex.body + 1};
+ z-index: 1101;
}
`,
diff --git a/packages/layout_editor/src/views/Message/Message.styles.js b/packages/layout_editor/src/views/Message/Message.styles.js
index f865d21d6..680062c99 100644
--- a/packages/layout_editor/src/views/Message/Message.styles.js
+++ b/packages/layout_editor/src/views/Message/Message.styles.js
@@ -85,7 +85,7 @@ export const getMessageDividerStyles = ({ theme, colors }) => {
line-height: 1rem;
position: relative;
display: flex;
- z-index: ${theme.zIndex.divider};
+ z-index: 1000;
align-items: center;
margin-top: 0.5rem;
margin-bottom: 0.75rem;
@@ -267,7 +267,7 @@ export const getMessageToolboxStyles = ({ theme, colors }) => {
display: flex;
position: absolute;
bottom: 100%;
- z-index: ${theme.zIndex.body + 1};
+ z-index: 1101;
right: 2rem;
`,
diff --git a/packages/layout_editor/src/views/ThemeLab/FontManager.jsx b/packages/layout_editor/src/views/ThemeLab/FontManager.jsx
new file mode 100644
index 000000000..9c40deee7
--- /dev/null
+++ b/packages/layout_editor/src/views/ThemeLab/FontManager.jsx
@@ -0,0 +1,75 @@
+import React, { useState } from 'react';
+import { Box, StaticSelect, useTheme } from '@embeddedchat/ui-elements';
+import { getFontManagerStyles } from './ThemeLab.styles';
+
+const FontManager = () => {
+ const themeObj = useTheme();
+ const styles = getFontManagerStyles(themeObj);
+
+ const { theme, setTheme } = themeObj;
+
+ const fontFamilyOptions = [
+ { label: 'Arial', value: 'Arial, sans-serif' },
+ { label: 'Arial Black', value: '"Arial Black", Gadget, sans-serif' },
+ { label: 'Comic Sans MS', value: '"Comic Sans MS", cursive, sans-serif' },
+ { label: 'Courier New', value: '"Courier New", Courier, monospace' },
+ { label: 'Georgia', value: 'Georgia, serif' },
+ { label: 'Helvetica', value: 'Helvetica, sans-serif' },
+ { label: 'Impact', value: 'Impact, Charcoal, sans-serif' },
+ { label: 'Lucida Console', value: '"Lucida Console", Monaco, monospace' },
+ {
+ label: 'Lucida Sans Unicode',
+ value: '"Lucida Sans Unicode", "Lucida Grande", sans-serif',
+ },
+ {
+ label: 'Palatino Linotype',
+ value: '"Palatino Linotype", "Book Antiqua", Palatino, serif',
+ },
+ { label: 'Tahoma', value: 'Tahoma, Geneva, sans-serif' },
+ { label: 'Times New Roman', value: "'Times New Roman', serif" },
+ { label: 'Trebuchet MS', value: '"Trebuchet MS", Helvetica, sans-serif' },
+ { label: 'Verdana', value: 'Verdana, Geneva, sans-serif' },
+ { label: 'MS Sans Serif', value: '"MS Sans Serif", Geneva, sans-serif' },
+ { label: 'MS Serif', value: '"MS Serif", "New York", serif' },
+ ];
+
+ const [fontFamily, setFontFamily] = useState(
+ theme.typography.global.fontFamily
+ );
+
+ const handleFontChange = (selectedOption) => {
+ setFontFamily(selectedOption);
+ setTheme({
+ ...theme,
+ typography: {
+ ...theme.typography,
+ global: {
+ ...theme.typography.global,
+ fontFamily: selectedOption,
+ },
+ },
+ });
+ };
+
+ return (
+
+
+ Font Family
+
+
+
+ );
+};
+
+export default FontManager;
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
index 40c2aa1f1..0a56fb8e6 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
@@ -23,11 +23,10 @@ export const getThemeLabStyles = ({ colors }) => {
export const getPaletteSettings = ({ colors }) => {
const styles = {
main: css`
- height: 100%;
display: flex;
flex-direction: column;
gap: 1.5rem;
- padding: 0.75rem;
+ padding: 1.75rem 0.75rem;
`,
colorSection: css`
padding: 0.5rem;
@@ -61,11 +60,10 @@ export const getPaletteSettings = ({ colors }) => {
export const getLayoutSettings = ({ colors }) => {
const styles = {
main: css`
- height: 100%;
display: flex;
flex-direction: column;
gap: 1.5rem;
- padding: 0.75rem;
+ padding: 1.75rem 0.75rem;
`,
variantSection: css`
padding: 0.5rem;
@@ -127,3 +125,17 @@ export const getColorMangerStyles = () => {
return styles;
};
+
+export const getFontManagerStyles = () => {
+ const styles = {
+ commonSelect: css`
+ display: flex;
+ gap: 1.25rem;
+ justify-content: space-between;
+ padding: 1.25rem 0;
+ position: relative;
+ `,
+ };
+
+ return styles;
+};
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeSetting.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeSetting.jsx
index 2037048fb..2df03a0a2 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeSetting.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeSetting.jsx
@@ -2,6 +2,7 @@ import React from 'react';
import { Box, StaticSelect, useTheme } from '@embeddedchat/ui-elements';
import { getPaletteSettings } from './ThemeLab.styles';
import ColorManager from './ColorManager';
+import FontManager from './FontManager';
const ThemeSetting = () => {
const themeObject = useTheme();
@@ -51,6 +52,7 @@ const ThemeSetting = () => {
Typography
+
);
From 4bbfa6053b04fbb57e7f9260b0f91991900e5934 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 15:17:22 +0530
Subject: [PATCH 071/104] removed zIndex from themes
---
packages/react/src/theme/AzureSky.js | 9 ---------
packages/react/src/theme/CurveVariant/AquaBreeze.js | 9 ---------
packages/react/src/theme/CurveVariant/AzureSky.js | 9 ---------
packages/react/src/theme/CurveVariant/BlushCandy.js | 9 ---------
packages/react/src/theme/CurveVariant/PineWhisper.js | 9 ---------
packages/react/src/theme/DefaultTheme.js | 9 ---------
packages/react/src/theme/MintMeadow.js | 9 ---------
packages/react/src/theme/ModernVariant/StormySeas.js | 9 ---------
packages/react/src/theme/RoseEmber.js | 9 ---------
.../react/src/views/ChannelState/ChannelState.styles.js | 2 +-
packages/react/src/views/ChatBody/ChatBody.styles.js | 3 +--
packages/react/src/views/ChatHeader/ChatHeader.styles.js | 2 +-
.../src/views/DynamicHeader/DynamicHeader.styles.js | 5 +----
.../react/src/views/ImageGallery/ImageGallery.styles.js | 4 ++--
.../src/views/Message/BubbleVariant/Bubble.styles.js | 2 +-
packages/react/src/views/Message/Message.styles.js | 4 ++--
.../react/src/views/QuoteMessage/QuoteMessage.styles.js | 2 +-
packages/react/src/views/TypingUsers/TypingUsers.js | 2 +-
18 files changed, 11 insertions(+), 96 deletions(-)
diff --git a/packages/react/src/theme/AzureSky.js b/packages/react/src/theme/AzureSky.js
index c401314cb..f0bee5f73 100644
--- a/packages/react/src/theme/AzureSky.js
+++ b/packages/react/src/theme/AzureSky.js
@@ -108,14 +108,5 @@ const AzureSky = {
'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
],
- zIndex: {
- divider: 1000,
- body: 1100,
- general: 1200,
- menu: 1300,
- tooltip: 1400,
- modal: 1500,
- toastbar: 1600,
- },
};
export default AzureSky;
diff --git a/packages/react/src/theme/CurveVariant/AquaBreeze.js b/packages/react/src/theme/CurveVariant/AquaBreeze.js
index d8af86faf..63f6c4cf5 100644
--- a/packages/react/src/theme/CurveVariant/AquaBreeze.js
+++ b/packages/react/src/theme/CurveVariant/AquaBreeze.js
@@ -121,14 +121,5 @@ const AquaBreeze = {
'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
],
- zIndex: {
- divider: 1000,
- body: 1100,
- general: 1200,
- menu: 1300,
- tooltip: 1400,
- modal: 1500,
- toastbar: 1600,
- },
};
export default AquaBreeze;
diff --git a/packages/react/src/theme/CurveVariant/AzureSky.js b/packages/react/src/theme/CurveVariant/AzureSky.js
index 0374cdb34..618e8a353 100644
--- a/packages/react/src/theme/CurveVariant/AzureSky.js
+++ b/packages/react/src/theme/CurveVariant/AzureSky.js
@@ -121,14 +121,5 @@ const AzureSky = {
'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
],
- zIndex: {
- divider: 1000,
- body: 1100,
- general: 1200,
- menu: 1300,
- tooltip: 1400,
- modal: 1500,
- toastbar: 1600,
- },
};
export default AzureSky;
diff --git a/packages/react/src/theme/CurveVariant/BlushCandy.js b/packages/react/src/theme/CurveVariant/BlushCandy.js
index 63320ca75..a10e03762 100644
--- a/packages/react/src/theme/CurveVariant/BlushCandy.js
+++ b/packages/react/src/theme/CurveVariant/BlushCandy.js
@@ -121,14 +121,5 @@ const BlushCandy = {
'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
],
- zIndex: {
- divider: 1000,
- body: 1100,
- general: 1200,
- menu: 1300,
- tooltip: 1400,
- modal: 1500,
- toastbar: 1600,
- },
};
export default BlushCandy;
diff --git a/packages/react/src/theme/CurveVariant/PineWhisper.js b/packages/react/src/theme/CurveVariant/PineWhisper.js
index 4fef4b054..5a6fc0a4b 100644
--- a/packages/react/src/theme/CurveVariant/PineWhisper.js
+++ b/packages/react/src/theme/CurveVariant/PineWhisper.js
@@ -122,14 +122,5 @@ const PineWhisper = {
'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
],
- zIndex: {
- divider: 1000,
- body: 1100,
- general: 1200,
- menu: 1300,
- tooltip: 1400,
- modal: 1500,
- toastbar: 1600,
- },
};
export default PineWhisper;
diff --git a/packages/react/src/theme/DefaultTheme.js b/packages/react/src/theme/DefaultTheme.js
index bcf1ac888..6c3eeca9e 100644
--- a/packages/react/src/theme/DefaultTheme.js
+++ b/packages/react/src/theme/DefaultTheme.js
@@ -106,15 +106,6 @@ const DefaultTheme = {
'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
],
- zIndex: {
- divider: 1000,
- body: 1100,
- general: 1200,
- menu: 1300,
- tooltip: 1400,
- modal: 1500,
- toastbar: 1600,
- },
};
export default DefaultTheme;
diff --git a/packages/react/src/theme/MintMeadow.js b/packages/react/src/theme/MintMeadow.js
index 86ab676de..4146c9c09 100644
--- a/packages/react/src/theme/MintMeadow.js
+++ b/packages/react/src/theme/MintMeadow.js
@@ -109,15 +109,6 @@ const MintMeadow = {
'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
],
- zIndex: {
- divider: 1000,
- body: 1100,
- general: 1200,
- menu: 1300,
- tooltip: 1400,
- modal: 1500,
- toastbar: 1600,
- },
};
export default MintMeadow;
diff --git a/packages/react/src/theme/ModernVariant/StormySeas.js b/packages/react/src/theme/ModernVariant/StormySeas.js
index ec255446c..13ae3112a 100644
--- a/packages/react/src/theme/ModernVariant/StormySeas.js
+++ b/packages/react/src/theme/ModernVariant/StormySeas.js
@@ -158,14 +158,5 @@ const StormySeas = {
'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
],
- zIndex: {
- divider: 1000,
- body: 1100,
- general: 1200,
- menu: 1300,
- tooltip: 1400,
- modal: 1500,
- toastbar: 1600,
- },
};
export default StormySeas;
diff --git a/packages/react/src/theme/RoseEmber.js b/packages/react/src/theme/RoseEmber.js
index 73ba6cd86..69ced5bc4 100644
--- a/packages/react/src/theme/RoseEmber.js
+++ b/packages/react/src/theme/RoseEmber.js
@@ -109,14 +109,5 @@ const RoseEmber = {
'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
],
- zIndex: {
- divider: 1000,
- body: 1100,
- general: 1200,
- menu: 1300,
- tooltip: 1400,
- modal: 1500,
- toastbar: 1600,
- },
};
export default RoseEmber;
diff --git a/packages/react/src/views/ChannelState/ChannelState.styles.js b/packages/react/src/views/ChannelState/ChannelState.styles.js
index 3f728be0a..b18a82c69 100644
--- a/packages/react/src/views/ChannelState/ChannelState.styles.js
+++ b/packages/react/src/views/ChannelState/ChannelState.styles.js
@@ -6,7 +6,7 @@ const useChannelStateStyles = () => {
const channelStateContainer = css`
font-size: 0.75rem;
padding: 0.2rem 2rem;
- z-index: ${theme.zIndex.general};
+ z-index: 1200;
display: flex;
justify-content: space-between;
`;
diff --git a/packages/react/src/views/ChatBody/ChatBody.styles.js b/packages/react/src/views/ChatBody/ChatBody.styles.js
index 0e7404f08..cc8510da4 100644
--- a/packages/react/src/views/ChatBody/ChatBody.styles.js
+++ b/packages/react/src/views/ChatBody/ChatBody.styles.js
@@ -19,10 +19,9 @@ export const useChatbodyStyles = () => {
};
export const useRecentMessageStyles = () => {
- const { theme } = useTheme();
const button = css`
position: relative;
- z-index: ${theme.zIndex.body};
+ z-index: 1100;
left: 50%;
transform: translateX(-50%);
user-select: none;
diff --git a/packages/react/src/views/ChatHeader/ChatHeader.styles.js b/packages/react/src/views/ChatHeader/ChatHeader.styles.js
index 656a08675..90a0fd2e3 100644
--- a/packages/react/src/views/ChatHeader/ChatHeader.styles.js
+++ b/packages/react/src/views/ChatHeader/ChatHeader.styles.js
@@ -27,7 +27,7 @@ const useChatHeaderStyles = () => {
? darken(colors.background, 0.03)
: lighten(colors.background, 1)};
width: 100%;
- z-index: ${theme.zIndex.general};
+ z-index: 1200;
display: flex;
flex-direction: column;
padding: 0.75rem;
diff --git a/packages/react/src/views/DynamicHeader/DynamicHeader.styles.js b/packages/react/src/views/DynamicHeader/DynamicHeader.styles.js
index 8187a5f31..8ccdcea51 100644
--- a/packages/react/src/views/DynamicHeader/DynamicHeader.styles.js
+++ b/packages/react/src/views/DynamicHeader/DynamicHeader.styles.js
@@ -1,15 +1,12 @@
import { css } from '@emotion/react';
-import { useTheme } from '@embeddedchat/ui-elements';
const useDynamicHeaderStyles = () => {
- const { theme } = useTheme();
-
const container = css`
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
- z-index: ${theme.zIndex.general};
+ z-index: 1200;
padding-block-start: 10px;
`;
diff --git a/packages/react/src/views/ImageGallery/ImageGallery.styles.js b/packages/react/src/views/ImageGallery/ImageGallery.styles.js
index 4b90c8f26..d2cd56485 100644
--- a/packages/react/src/views/ImageGallery/ImageGallery.styles.js
+++ b/packages/react/src/views/ImageGallery/ImageGallery.styles.js
@@ -10,7 +10,7 @@ const useImageGalleryStyles = () => {
left: 0;
width: 100%;
height: 100%;
- z-index: ${theme.zIndex.modal};
+ z-index: 1500;
background-color: ${alpha(theme.schemes.common.black, 0.5)};
`;
@@ -24,7 +24,7 @@ const useImageGalleryStyles = () => {
border-radius: ${theme.schemes.radius};
padding: 8px 16px;
cursor: pointer;
- z-index: ${theme.zIndex.modal + 1};
+ z-index: 1501;
`;
const imageContainer = css`
diff --git a/packages/react/src/views/Message/BubbleVariant/Bubble.styles.js b/packages/react/src/views/Message/BubbleVariant/Bubble.styles.js
index 576d30d2b..dcf49f821 100644
--- a/packages/react/src/views/Message/BubbleVariant/Bubble.styles.js
+++ b/packages/react/src/views/Message/BubbleVariant/Bubble.styles.js
@@ -85,7 +85,7 @@ export const bubbleStyles = (customTheme) => {
position: absolute;
bottom: calc(100% - 20px);
left: calc(100% - 20px);
- z-index: ${theme.zIndex.body + 1};
+ z-index: 1101;
}
`,
diff --git a/packages/react/src/views/Message/Message.styles.js b/packages/react/src/views/Message/Message.styles.js
index f23b4de21..80a7f1553 100644
--- a/packages/react/src/views/Message/Message.styles.js
+++ b/packages/react/src/views/Message/Message.styles.js
@@ -76,7 +76,7 @@ export const useMessageDividerStyles = () => {
line-height: 1rem;
position: relative;
display: flex;
- z-index: ${theme.zIndex.divider};
+ z-index: 1000;
align-items: center;
margin-top: 0.5rem;
margin-bottom: 0.75rem;
@@ -259,7 +259,7 @@ export const useMessageToolboxStyles = () => {
display: flex;
position: absolute;
bottom: 100%;
- z-index: ${theme.zIndex.body + 1};
+ z-index: 1101;
right: 2rem;
}
`;
diff --git a/packages/react/src/views/QuoteMessage/QuoteMessage.styles.js b/packages/react/src/views/QuoteMessage/QuoteMessage.styles.js
index feb494c19..16a0bfc2e 100644
--- a/packages/react/src/views/QuoteMessage/QuoteMessage.styles.js
+++ b/packages/react/src/views/QuoteMessage/QuoteMessage.styles.js
@@ -10,7 +10,7 @@ const useQuoteMessageStyles = () => {
background-color: ${colors.background};
color: ${colors.foreground};
padding: 0.5rem;
- z-index: ${theme.zIndex.general};
+ z-index: 1200;
border: 1px solid ${colors.border};
border-radius: ${theme.schemes.radius};
`;
diff --git a/packages/react/src/views/TypingUsers/TypingUsers.js b/packages/react/src/views/TypingUsers/TypingUsers.js
index b151861d1..db05619ec 100644
--- a/packages/react/src/views/TypingUsers/TypingUsers.js
+++ b/packages/react/src/views/TypingUsers/TypingUsers.js
@@ -51,7 +51,7 @@ export default function TypingUsers() {
height: ${typingUsers.length !== 0 ? '15px' : '0px'};
font-size: 0.75rem;
margin-inline-start: 2.25rem;
- z-index: ${theme.zIndex.general};
+ z-index: 1200;
`}
>
{typingStatusMessage}
From f5844f232ecfa5a9e169066b00bf673f340f427b Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 15:18:04 +0530
Subject: [PATCH 072/104] updated yarn lock
---
yarn.lock | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 63 insertions(+), 1 deletion(-)
diff --git a/yarn.lock b/yarn.lock
index 1a5c60869..f4ee2c319 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3997,6 +3997,15 @@ __metadata:
languageName: node
linkType: hard
+"@icons/material@npm:^0.2.4":
+ version: 0.2.4
+ resolution: "@icons/material@npm:0.2.4"
+ peerDependencies:
+ react: "*"
+ checksum: 24baa360cb83f7e1a9e6784ac11185d57eb895b0efd3070ec915693378330f35ff9feb248f650b9649fa3e1045601286585dc05795a4c734d4849b33900351ee
+ languageName: node
+ linkType: hard
+
"@isaacs/cliui@npm:^8.0.2":
version: 8.0.2
resolution: "@isaacs/cliui@npm:8.0.2"
@@ -21348,8 +21357,11 @@ __metadata:
eslint-plugin-react-hooks: ^4.6.0
eslint-plugin-react-refresh: ^0.4.5
react: ^18.2.0
+ react-color: ^2.19.3
react-dom: ^18.2.0
+ react-resizable-panels: ^2.0.20
vite: ^5.1.0
+ zustand: ^4.3.8
languageName: unknown
linkType: soft
@@ -21875,6 +21887,13 @@ __metadata:
languageName: node
linkType: hard
+"lodash-es@npm:^4.17.15":
+ version: 4.17.21
+ resolution: "lodash-es@npm:4.17.21"
+ checksum: 05cbffad6e2adbb331a4e16fbd826e7faee403a1a04873b82b42c0f22090f280839f85b95393f487c1303c8a3d2a010048bf06151a6cbe03eee4d388fb0a12d2
+ languageName: node
+ linkType: hard
+
"lodash.camelcase@npm:^4.3.0":
version: 4.3.0
resolution: "lodash.camelcase@npm:4.3.0"
@@ -21952,7 +21971,7 @@ __metadata:
languageName: node
linkType: hard
-"lodash@npm:^4.17.13, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:^4.3.0, lodash@npm:^4.7.0":
+"lodash@npm:^4.0.1, lodash@npm:^4.17.13, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:^4.3.0, lodash@npm:^4.7.0":
version: 4.17.21
resolution: "lodash@npm:4.17.21"
checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7
@@ -22275,6 +22294,13 @@ __metadata:
languageName: node
linkType: hard
+"material-colors@npm:^1.2.1":
+ version: 1.2.6
+ resolution: "material-colors@npm:1.2.6"
+ checksum: 72d005ccccb82bab68eef3cd757e802668634fc86976dedb9fc564ce994f2d3258273766b7efecb7404a0031969e2d72201a1b74169763f0a53c0dd8d649209f
+ languageName: node
+ linkType: hard
+
"maxmin@npm:^2.1.0":
version: 2.1.0
resolution: "maxmin@npm:2.1.0"
@@ -26550,6 +26576,23 @@ __metadata:
languageName: node
linkType: hard
+"react-color@npm:^2.19.3":
+ version: 2.19.3
+ resolution: "react-color@npm:2.19.3"
+ dependencies:
+ "@icons/material": ^0.2.4
+ lodash: ^4.17.15
+ lodash-es: ^4.17.15
+ material-colors: ^1.2.1
+ prop-types: ^15.5.10
+ reactcss: ^1.2.0
+ tinycolor2: ^1.4.1
+ peerDependencies:
+ react: "*"
+ checksum: 40b49e1aa2ab27a099cc37a3fa2d5bb906b8def4dbe2d922c0e42365e386d82b03f9b06a2b29a44a51f1e114cef72e61c0ba0740581a128d951936ea4617429b
+ languageName: node
+ linkType: hard
+
"react-colorful@npm:^5.1.2":
version: 5.6.1
resolution: "react-colorful@npm:5.6.1"
@@ -26938,6 +26981,16 @@ __metadata:
languageName: node
linkType: hard
+"react-resizable-panels@npm:^2.0.20":
+ version: 2.0.20
+ resolution: "react-resizable-panels@npm:2.0.20"
+ peerDependencies:
+ react: ^16.14.0 || ^17.0.0 || ^18.0.0
+ react-dom: ^16.14.0 || ^17.0.0 || ^18.0.0
+ checksum: 73f42c826037a5027c4112c5d62ded42c122ca2f62210123954923fb000f9b4ce6b9d329284892046fb8b14036b53abc0c5235ef3ec85e53175c0c73ba70844a
+ languageName: node
+ linkType: hard
+
"react-shallow-renderer@npm:^16.15.0":
version: 16.15.0
resolution: "react-shallow-renderer@npm:16.15.0"
@@ -26986,6 +27039,15 @@ __metadata:
languageName: node
linkType: hard
+"reactcss@npm:^1.2.0":
+ version: 1.2.3
+ resolution: "reactcss@npm:1.2.3"
+ dependencies:
+ lodash: ^4.0.1
+ checksum: c53e386a0881f1477e1cff661f6a6ad4c662230941f3827862193ac30f9b75cdf7bc7b4c7e5ca543d3e4e80fee1a3e9fa0056c206b1c0423726c41773ab3fe45
+ languageName: node
+ linkType: hard
+
"read-cmd-shim@npm:3.0.0":
version: 3.0.0
resolution: "read-cmd-shim@npm:3.0.0"
From 6885ba08ff12c4a6458ddb0596d1cc845cbe69bc Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 15:21:19 +0530
Subject: [PATCH 073/104] rollback to default name
---
packages/layout_editor/src/theme/DefaultTheme.js | 2 +-
packages/layout_editor/src/views/GlobalStyles.jsx | 6 +++---
packages/layout_editor/src/views/ThemeLab/FontManager.jsx | 6 +++---
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/packages/layout_editor/src/theme/DefaultTheme.js b/packages/layout_editor/src/theme/DefaultTheme.js
index be1650b8a..8752e2e4a 100644
--- a/packages/layout_editor/src/theme/DefaultTheme.js
+++ b/packages/layout_editor/src/theme/DefaultTheme.js
@@ -72,7 +72,7 @@ const DefaultTheme = {
},
typography: {
- global: {
+ default: {
fontFamily: "'Times New Roman', serif",
fontSize: 16,
fontWeightRegular: 400,
diff --git a/packages/layout_editor/src/views/GlobalStyles.jsx b/packages/layout_editor/src/views/GlobalStyles.jsx
index dbca8e9af..ebdc3551f 100644
--- a/packages/layout_editor/src/views/GlobalStyles.jsx
+++ b/packages/layout_editor/src/views/GlobalStyles.jsx
@@ -10,9 +10,9 @@ const useStyles = ({ colors, theme }) => css`
}
body {
- font-family: ${theme.typography.global.fontFamily};
- font-size: ${theme.typography.global.fontSize}px;
- font-weight: ${theme.typography.global.fontWeightRegular};
+ font-family: ${theme.typography.default.fontFamily};
+ font-size: ${theme.typography.default.fontSize}px;
+ font-weight: ${theme.typography.default.fontWeightRegular};
}
a {
diff --git a/packages/layout_editor/src/views/ThemeLab/FontManager.jsx b/packages/layout_editor/src/views/ThemeLab/FontManager.jsx
index 9c40deee7..b7c24ae87 100644
--- a/packages/layout_editor/src/views/ThemeLab/FontManager.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/FontManager.jsx
@@ -34,7 +34,7 @@ const FontManager = () => {
];
const [fontFamily, setFontFamily] = useState(
- theme.typography.global.fontFamily
+ theme.typography.default.fontFamily
);
const handleFontChange = (selectedOption) => {
@@ -43,8 +43,8 @@ const FontManager = () => {
...theme,
typography: {
...theme.typography,
- global: {
- ...theme.typography.global,
+ default: {
+ ...theme.typography.default,
fontFamily: selectedOption,
},
},
From c486dbe4aeaa922ea9b3b0aaae53a1558e027cd4 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 15:40:21 +0530
Subject: [PATCH 074/104] added typography ssettings
---
.../src/views/ThemeLab/FontManager.jsx | 102 +++++++++++++++---
.../src/views/ThemeLab/ThemeLab.styles.js | 4 +-
2 files changed, 87 insertions(+), 19 deletions(-)
diff --git a/packages/layout_editor/src/views/ThemeLab/FontManager.jsx b/packages/layout_editor/src/views/ThemeLab/FontManager.jsx
index b7c24ae87..4b7bd4b14 100644
--- a/packages/layout_editor/src/views/ThemeLab/FontManager.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/FontManager.jsx
@@ -5,7 +5,6 @@ import { getFontManagerStyles } from './ThemeLab.styles';
const FontManager = () => {
const themeObj = useTheme();
const styles = getFontManagerStyles(themeObj);
-
const { theme, setTheme } = themeObj;
const fontFamilyOptions = [
@@ -33,11 +32,31 @@ const FontManager = () => {
{ label: 'MS Serif', value: '"MS Serif", "New York", serif' },
];
+ const fontSizeOptions = [
+ { label: 'Small', value: 12 },
+ { label: 'Medium', value: 16 },
+ { label: 'Large', value: 20 },
+ { label: 'Extra Large', value: 24 },
+ ];
+
+ const fontWeightOptions = [
+ { label: 'Light', value: 300 },
+ { label: 'Normal', value: 400 },
+ { label: 'Bold', value: 700 },
+ { label: 'Extra Bold', value: 900 },
+ ];
+
const [fontFamily, setFontFamily] = useState(
theme.typography.default.fontFamily
);
+ const [fontSize, setFontSize] = useState(
+ theme.typography.default.fontSize || '16'
+ );
+ const [fontWeight, setFontWeight] = useState(
+ theme.typography.default.fontWeightRegular || 400
+ );
- const handleFontChange = (selectedOption) => {
+ const handleFontFamilyChange = (selectedOption) => {
setFontFamily(selectedOption);
setTheme({
...theme,
@@ -51,23 +70,72 @@ const FontManager = () => {
});
};
+ const handleFontSizeChange = (selectedOption) => {
+ setFontSize(selectedOption);
+ setTheme({
+ ...theme,
+ typography: {
+ ...theme.typography,
+ default: {
+ ...theme.typography.default,
+ fontSize: selectedOption,
+ },
+ },
+ });
+ };
+
+ const handleFontWeightChange = (selectedOption) => {
+ setFontWeight(selectedOption);
+ setTheme({
+ ...theme,
+ typography: {
+ ...theme.typography,
+ default: {
+ ...theme.typography.default,
+ fontWeightRegular: selectedOption,
+ },
+ },
+ });
+ };
+
return (
-
-
- Font Family
+
+
+
+ Font Family
+
+
+
+
+
+ Font Size
+
+
+
+
+
+ Font Weight
+
+
-
);
};
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
index 0a56fb8e6..4c9d88612 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
@@ -26,7 +26,7 @@ export const getPaletteSettings = ({ colors }) => {
display: flex;
flex-direction: column;
gap: 1.5rem;
- padding: 1.75rem 0.75rem;
+ padding: 1.25rem 0.75rem;
`,
colorSection: css`
padding: 0.5rem;
@@ -63,7 +63,7 @@ export const getLayoutSettings = ({ colors }) => {
display: flex;
flex-direction: column;
gap: 1.5rem;
- padding: 1.75rem 0.75rem;
+ padding: 1.25rem 0.75rem;
`,
variantSection: css`
padding: 0.5rem;
From 8b035c2d33dd083f4d3f95ab0bb3daa55b733f61 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 16:20:32 +0530
Subject: [PATCH 075/104] added generate theme btn
---
packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx | 6 ++++++
.../layout_editor/src/views/ThemeLab/ThemeLab.styles.js | 7 ++++++-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
index e01caf6a6..095214754 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
@@ -1,6 +1,7 @@
import React, { useState } from 'react';
import {
Box,
+ Button,
MinimalSidebar,
SidebarContent,
SidebarHeader,
@@ -43,6 +44,11 @@ const ThemeLab = () => {
{paletteActive ? : }
+
+
+ Generate Theme
+
+
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
index 4c9d88612..09e8497f2 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
@@ -9,12 +9,17 @@ export const getThemeLabStyles = ({ colors }) => {
`,
section: css`
- padding: 0 1rem 0.5rem;
cursor: pointer;
`,
sectionActive: css`
border-bottom: 1px solid ${colors.primary};
`,
+
+ btn: css`
+ border-radius: 0.25rem;
+ border: 1px solid ${colors.border};
+ margin: 0 0.75rem 0.75rem;
+ `,
};
return styles;
From 6521d06f9ccb81c1c71c9b0b92e55bdf8f035981 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 22:00:44 +0530
Subject: [PATCH 076/104] added generated theme to modal
---
packages/layout_editor/package.json | 3 +-
packages/layout_editor/src/App.jsx | 6 +-
.../layout_editor/src/views/GlobalStyles.jsx | 2 +-
.../src/views/ThemeLab/ThemeLab.jsx | 145 ++++++++++---
.../src/views/ThemeLab/ThemeLab.styles.js | 8 +
yarn.lock | 196 +++++++++++++++++-
6 files changed, 324 insertions(+), 36 deletions(-)
diff --git a/packages/layout_editor/package.json b/packages/layout_editor/package.json
index b554c260d..28dea7bc0 100644
--- a/packages/layout_editor/package.json
+++ b/packages/layout_editor/package.json
@@ -16,7 +16,8 @@
"react": "^18.2.0",
"react-color": "^2.19.3",
"react-dom": "^18.2.0",
- "react-resizable-panels": "^2.0.20"
+ "react-resizable-panels": "^2.0.20",
+ "react-syntax-highlighter": "^15.5.0"
},
"devDependencies": {
"@emotion/babel-preset-css-prop": "^11.11.0",
diff --git a/packages/layout_editor/src/App.jsx b/packages/layout_editor/src/App.jsx
index 0163e1a11..62d6c9502 100644
--- a/packages/layout_editor/src/App.jsx
+++ b/packages/layout_editor/src/App.jsx
@@ -1,12 +1,14 @@
import React from 'react';
import LayoutEditor from './views/LayoutEditor';
-import { ThemeProvider } from '@embeddedchat/ui-elements';
+import { ThemeProvider, ToastBarProvider } from '@embeddedchat/ui-elements';
import DefaultTheme from './theme/DefaultTheme';
const App = () => {
return (
-
+
+
+
);
};
diff --git a/packages/layout_editor/src/views/GlobalStyles.jsx b/packages/layout_editor/src/views/GlobalStyles.jsx
index ebdc3551f..2b6bd97e9 100644
--- a/packages/layout_editor/src/views/GlobalStyles.jsx
+++ b/packages/layout_editor/src/views/GlobalStyles.jsx
@@ -21,7 +21,7 @@ const useStyles = ({ colors, theme }) => css`
::-webkit-scrollbar {
width: 4px;
- height: 7.7px;
+ height: 4px;
}
::-webkit-scrollbar-thumb {
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
index 095214754..404d66e75 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
@@ -1,57 +1,140 @@
import React, { useState } from 'react';
import {
Box,
+ Icon,
Button,
MinimalSidebar,
+ Modal,
SidebarContent,
SidebarHeader,
useTheme,
+ useToastBarDispatch,
} from '@embeddedchat/ui-elements';
import useLayoutStore from '../../store/layoutStore';
import { getThemeLabStyles } from './ThemeLab.styles';
import LayoutSetting from './LayoutSetting';
import ThemeSetting from './ThemeSetting';
+import { Light as SyntaxHighlighter } from 'react-syntax-highlighter';
+import { dracula } from 'react-syntax-highlighter/dist/esm/styles/hljs';
const ThemeLab = () => {
const styles = getThemeLabStyles(useTheme());
const setThemeLabOpen = useLayoutStore((state) => state.setThemeLabOpen);
const [paletteActive, setPaletteAction] = useState(true);
+ const [themeModalOpen, setThemeModalOpen] = useState(false);
+ const [generatedTheme, setGeneratedTheme] = useState(null);
+ const { theme } = useTheme();
+ const dispatchToastMessage = useToastBarDispatch();
+
+ const handleThemeGeneration = () => {
+ setThemeModalOpen(true);
+ const themeString = JSON.stringify(theme, null, 2)
+ .replace(/\\n/g, '\n')
+ .replace(/\\"/g, "'");
+ setGeneratedTheme(themeString);
+ };
+
+ const handleCopyToClipboard = () => {
+ if (generatedTheme) {
+ navigator.clipboard
+ .writeText(generatedTheme)
+ .then(() => {
+ dispatchToastMessage({
+ type: 'success',
+ message: 'Theme copied to clipboard.',
+ });
+ })
+ .catch((err) => {
+ dispatchToastMessage({
+ type: 'error',
+ message: 'Copy to clipboard failed.',
+ });
+ });
+ }
+ };
return (
-
-
- setThemeLabOpen(false)}
- title="Theme Lab"
- iconName="cog"
- />
-
-
- setPaletteAction(true)}
- >
- Theme
+ <>
+
+
+ setThemeLabOpen(false)}
+ title="Theme Lab"
+ iconName="cog"
+ />
+
+
+ setPaletteAction(true)}
+ >
+ Theme
+
+ setPaletteAction(false)}
+ >
+ Layout
+
- setPaletteAction(false)}
- >
- Layout
+
+ {paletteActive ? : }
+
+
+ Generate Theme 👀
+
-
+
+
+
- {paletteActive ? : }
-
-
- Generate Theme
-
-
-
-
-
+ {themeModalOpen && (
+ setThemeModalOpen(false)}>
+
+
+
+ Your theme is ready!
+
+ setThemeModalOpen(false)} />
+
+
+
+
+ {generatedTheme}
+
+
+
+
+
+
+ setThemeModalOpen(false)}>
+ Close
+
+
+
+
+ )}
+ >
);
};
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
index 09e8497f2..ff874544c 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
@@ -20,6 +20,14 @@ export const getThemeLabStyles = ({ colors }) => {
border: 1px solid ${colors.border};
margin: 0 0.75rem 0.75rem;
`,
+
+ syntaxBox: css`
+ position: relative;
+ `,
+
+ closeBtn: css`
+ padding: 0.5rem;
+ `,
};
return styles;
diff --git a/yarn.lock b/yarn.lock
index f4ee2c319..0b772473a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1876,6 +1876,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/runtime@npm:^7.3.1":
+ version: 7.24.8
+ resolution: "@babel/runtime@npm:7.24.8"
+ dependencies:
+ regenerator-runtime: ^0.14.0
+ checksum: 6b1e4230580f67a807ad054720812bbefbb024cc2adc1159d050acbb764c4c81c7ac5f7a042c48f578987c5edc2453c71039268df059058e9501fa6023d764b0
+ languageName: node
+ linkType: hard
+
"@babel/template@npm:^7.0.0, @babel/template@npm:^7.20.7, @babel/template@npm:^7.22.15, @babel/template@npm:^7.3.3":
version: 7.22.15
resolution: "@babel/template@npm:7.22.15"
@@ -9516,6 +9525,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/hast@npm:^2.0.0":
+ version: 2.3.10
+ resolution: "@types/hast@npm:2.3.10"
+ dependencies:
+ "@types/unist": ^2
+ checksum: 41531b7fbf590b02452996fc63272479c20a07269e370bd6514982cbcd1819b4b84d3ea620f2410d1b9541a23d08ce2eeb0a592145d05e00e249c3d56700d460
+ languageName: node
+ linkType: hard
+
"@types/html-minifier-terser@npm:^6.0.0":
version: 6.1.0
resolution: "@types/html-minifier-terser@npm:6.1.0"
@@ -9873,7 +9891,7 @@ __metadata:
languageName: node
linkType: hard
-"@types/unist@npm:^2.0.0":
+"@types/unist@npm:^2, @types/unist@npm:^2.0.0":
version: 2.0.10
resolution: "@types/unist@npm:2.0.10"
checksum: e2924e18dedf45f68a5c6ccd6015cd62f1643b1b43baac1854efa21ae9e70505db94290434a23da1137d9e31eb58e54ca175982005698ac37300a1c889f6c4aa
@@ -12980,6 +12998,27 @@ __metadata:
languageName: node
linkType: hard
+"character-entities-legacy@npm:^1.0.0":
+ version: 1.1.4
+ resolution: "character-entities-legacy@npm:1.1.4"
+ checksum: fe03a82c154414da3a0c8ab3188e4237ec68006cbcd681cf23c7cfb9502a0e76cd30ab69a2e50857ca10d984d57de3b307680fff5328ccd427f400e559c3a811
+ languageName: node
+ linkType: hard
+
+"character-entities@npm:^1.0.0":
+ version: 1.2.4
+ resolution: "character-entities@npm:1.2.4"
+ checksum: e1545716571ead57beac008433c1ff69517cd8ca5b336889321c5b8ff4a99c29b65589a701e9c086cda8a5e346a67295e2684f6c7ea96819fe85cbf49bf8686d
+ languageName: node
+ linkType: hard
+
+"character-reference-invalid@npm:^1.0.0":
+ version: 1.1.4
+ resolution: "character-reference-invalid@npm:1.1.4"
+ checksum: 20274574c70e05e2f81135f3b93285536bc8ff70f37f0809b0d17791a832838f1e49938382899ed4cb444e5bbd4314ca1415231344ba29f4222ce2ccf24fea0b
+ languageName: node
+ linkType: hard
+
"chardet@npm:^0.4.0":
version: 0.4.2
resolution: "chardet@npm:0.4.2"
@@ -13417,6 +13456,13 @@ __metadata:
languageName: node
linkType: hard
+"comma-separated-tokens@npm:^1.0.0":
+ version: 1.0.8
+ resolution: "comma-separated-tokens@npm:1.0.8"
+ checksum: 0adcb07174fa4d08cf0f5c8e3aec40a36b5ff0c2c720e5e23f50fe02e6789d1d00a67036c80e0c1e1539f41d3e7f0101b074039dd833b4e4a59031b659d6ca0d
+ languageName: node
+ linkType: hard
+
"command-exists@npm:^1.2.4, command-exists@npm:^1.2.8":
version: 1.2.9
resolution: "command-exists@npm:1.2.9"
@@ -17022,6 +17068,15 @@ __metadata:
languageName: node
linkType: hard
+"fault@npm:^1.0.0":
+ version: 1.0.4
+ resolution: "fault@npm:1.0.4"
+ dependencies:
+ format: ^0.2.0
+ checksum: 5ac610d8b09424e0f2fa8cf913064372f2ee7140a203a79957f73ed557c0e79b1a3d096064d7f40bde8132a69204c1fe25ec23634c05c6da2da2039cff26c4e7
+ languageName: node
+ linkType: hard
+
"faye-websocket@npm:0.11.x":
version: 0.11.4
resolution: "faye-websocket@npm:0.11.4"
@@ -17528,6 +17583,13 @@ __metadata:
languageName: node
linkType: hard
+"format@npm:^0.2.0":
+ version: 0.2.2
+ resolution: "format@npm:0.2.2"
+ checksum: 646a60e1336250d802509cf24fb801e43bd4a70a07510c816fa133aa42cdbc9c21e66e9cc0801bb183c5b031c9d68be62e7fbb6877756e52357850f92aa28799
+ languageName: node
+ linkType: hard
+
"forwarded@npm:0.2.0":
version: 0.2.0
resolution: "forwarded@npm:0.2.0"
@@ -18562,6 +18624,26 @@ __metadata:
languageName: node
linkType: hard
+"hast-util-parse-selector@npm:^2.0.0":
+ version: 2.2.5
+ resolution: "hast-util-parse-selector@npm:2.2.5"
+ checksum: 22ee4afbd11754562144cb3c4f3ec52524dafba4d90ee52512902d17cf11066d83b38f7bdf6ca571bbc2541f07ba30db0d234657b6ecb8ca4631587466459605
+ languageName: node
+ linkType: hard
+
+"hastscript@npm:^6.0.0":
+ version: 6.0.0
+ resolution: "hastscript@npm:6.0.0"
+ dependencies:
+ "@types/hast": ^2.0.0
+ comma-separated-tokens: ^1.0.0
+ hast-util-parse-selector: ^2.0.0
+ property-information: ^5.0.0
+ space-separated-tokens: ^1.0.0
+ checksum: 5e50b85af0d2cb7c17979cb1ddca75d6b96b53019dd999b39e7833192c9004201c3cee6445065620ea05d0087d9ae147a4844e582d64868be5bc6b0232dfe52d
+ languageName: node
+ linkType: hard
+
"he@npm:^1.2.0":
version: 1.2.0
resolution: "he@npm:1.2.0"
@@ -18596,6 +18678,13 @@ __metadata:
languageName: node
linkType: hard
+"highlight.js@npm:^10.4.1, highlight.js@npm:~10.7.0":
+ version: 10.7.3
+ resolution: "highlight.js@npm:10.7.3"
+ checksum: defeafcd546b535d710d8efb8e650af9e3b369ef53e28c3dc7893eacfe263200bba4c5fcf43524ae66d5c0c296b1af0870523ceae3e3104d24b7abf6374a4fea
+ languageName: node
+ linkType: hard
+
"hmac-drbg@npm:^1.0.1":
version: 1.0.1
resolution: "hmac-drbg@npm:1.0.1"
@@ -19380,6 +19469,23 @@ __metadata:
languageName: node
linkType: hard
+"is-alphabetical@npm:^1.0.0":
+ version: 1.0.4
+ resolution: "is-alphabetical@npm:1.0.4"
+ checksum: 6508cce44fd348f06705d377b260974f4ce68c74000e7da4045f0d919e568226dc3ce9685c5a2af272195384df6930f748ce9213fc9f399b5d31b362c66312cb
+ languageName: node
+ linkType: hard
+
+"is-alphanumerical@npm:^1.0.0":
+ version: 1.0.4
+ resolution: "is-alphanumerical@npm:1.0.4"
+ dependencies:
+ is-alphabetical: ^1.0.0
+ is-decimal: ^1.0.0
+ checksum: e2e491acc16fcf5b363f7c726f666a9538dba0a043665740feb45bba1652457a73441e7c5179c6768a638ed396db3437e9905f403644ec7c468fb41f4813d03f
+ languageName: node
+ linkType: hard
+
"is-arguments@npm:^1.0.4, is-arguments@npm:^1.1.1":
version: 1.1.1
resolution: "is-arguments@npm:1.1.1"
@@ -19552,6 +19658,13 @@ __metadata:
languageName: node
linkType: hard
+"is-decimal@npm:^1.0.0":
+ version: 1.0.4
+ resolution: "is-decimal@npm:1.0.4"
+ checksum: ed483a387517856dc395c68403a10201fddcc1b63dc56513fbe2fe86ab38766120090ecdbfed89223d84ca8b1cd28b0641b93cb6597b6e8f4c097a7c24e3fb96
+ languageName: node
+ linkType: hard
+
"is-deflate@npm:^1.0.0":
version: 1.0.0
resolution: "is-deflate@npm:1.0.0"
@@ -19722,6 +19835,13 @@ __metadata:
languageName: node
linkType: hard
+"is-hexadecimal@npm:^1.0.0":
+ version: 1.0.4
+ resolution: "is-hexadecimal@npm:1.0.4"
+ checksum: a452e047587b6069332d83130f54d30da4faf2f2ebaa2ce6d073c27b5703d030d58ed9e0b729c8e4e5b52c6f1dab26781bb77b7bc6c7805f14f320e328ff8cd5
+ languageName: node
+ linkType: hard
+
"is-interactive@npm:^1.0.0":
version: 1.0.0
resolution: "is-interactive@npm:1.0.0"
@@ -21360,6 +21480,7 @@ __metadata:
react-color: ^2.19.3
react-dom: ^18.2.0
react-resizable-panels: ^2.0.20
+ react-syntax-highlighter: ^15.5.0
vite: ^5.1.0
zustand: ^4.3.8
languageName: unknown
@@ -22042,6 +22163,16 @@ __metadata:
languageName: node
linkType: hard
+"lowlight@npm:^1.17.0":
+ version: 1.20.0
+ resolution: "lowlight@npm:1.20.0"
+ dependencies:
+ fault: ^1.0.0
+ highlight.js: ~10.7.0
+ checksum: 14a1815d6bae202ddee313fc60f06d46e5235c02fa483a77950b401d85b4c1e12290145ccd17a716b07f9328bd5864aa2d402b6a819ff3be7c833d9748ff8ba7
+ languageName: node
+ linkType: hard
+
"lru-cache@npm:^10.0.1, lru-cache@npm:^9.1.1 || ^10.0.0":
version: 10.0.3
resolution: "lru-cache@npm:10.0.3"
@@ -25113,6 +25244,20 @@ __metadata:
languageName: node
linkType: hard
+"parse-entities@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "parse-entities@npm:2.0.0"
+ dependencies:
+ character-entities: ^1.0.0
+ character-entities-legacy: ^1.0.0
+ character-reference-invalid: ^1.0.0
+ is-alphanumerical: ^1.0.0
+ is-decimal: ^1.0.0
+ is-hexadecimal: ^1.0.0
+ checksum: 7addfd3e7d747521afac33c8121a5f23043c6973809756920d37e806639b4898385d386fcf4b3c8e2ecf1bc28aac5ae97df0b112d5042034efbe80f44081ebce
+ languageName: node
+ linkType: hard
+
"parse-json@npm:^4.0.0":
version: 4.0.0
resolution: "parse-json@npm:4.0.0"
@@ -26152,6 +26297,20 @@ __metadata:
languageName: node
linkType: hard
+"prismjs@npm:^1.27.0":
+ version: 1.29.0
+ resolution: "prismjs@npm:1.29.0"
+ checksum: 007a8869d4456ff8049dc59404e32d5666a07d99c3b0e30a18bd3b7676dfa07d1daae9d0f407f20983865fd8da56de91d09cb08e6aa61f5bc420a27c0beeaf93
+ languageName: node
+ linkType: hard
+
+"prismjs@npm:~1.27.0":
+ version: 1.27.0
+ resolution: "prismjs@npm:1.27.0"
+ checksum: 85c7f4a3e999073502cc9e1882af01e3709706369ec254b60bff1149eda701f40d02512acab956012dc7e61cfd61743a3a34c1bd0737e8dbacd79141e5698bbc
+ languageName: node
+ linkType: hard
+
"proc-log@npm:^2.0.0, proc-log@npm:^2.0.1":
version: 2.0.1
resolution: "proc-log@npm:2.0.1"
@@ -26300,6 +26459,15 @@ __metadata:
languageName: node
linkType: hard
+"property-information@npm:^5.0.0":
+ version: 5.6.0
+ resolution: "property-information@npm:5.6.0"
+ dependencies:
+ xtend: ^4.0.0
+ checksum: fcf87c6542e59a8bbe31ca0b3255a4a63ac1059b01b04469680288998bcfa97f341ca989566adbb63975f4d85339030b82320c324a511532d390910d1c583893
+ languageName: node
+ linkType: hard
+
"proto-list@npm:~1.2.1":
version: 1.2.4
resolution: "proto-list@npm:1.2.4"
@@ -27020,6 +27188,21 @@ __metadata:
languageName: node
linkType: hard
+"react-syntax-highlighter@npm:^15.5.0":
+ version: 15.5.0
+ resolution: "react-syntax-highlighter@npm:15.5.0"
+ dependencies:
+ "@babel/runtime": ^7.3.1
+ highlight.js: ^10.4.1
+ lowlight: ^1.17.0
+ prismjs: ^1.27.0
+ refractor: ^3.6.0
+ peerDependencies:
+ react: ">= 0.14.0"
+ checksum: c082b48f30f8ba8d0c55ed1d761910630860077c7ff5793c4c912adcb5760df06436ed0ad62be0de28113aac9ad2af55eccd995f8eee98df53382e4ced2072fb
+ languageName: node
+ linkType: hard
+
"react@npm:18.2.0, react@npm:^18.2.0":
version: 18.2.0
resolution: "react@npm:18.2.0"
@@ -27298,6 +27481,17 @@ __metadata:
languageName: node
linkType: hard
+"refractor@npm:^3.6.0":
+ version: 3.6.0
+ resolution: "refractor@npm:3.6.0"
+ dependencies:
+ hastscript: ^6.0.0
+ parse-entities: ^2.0.0
+ prismjs: ~1.27.0
+ checksum: 39b01c4168c77c5c8486f9bf8907bbb05f257f15026057ba5728535815a2d90eed620468a4bfbb2b8ceefbb3ce3931a1be8b17152dbdbc8b0eef92450ff750a2
+ languageName: node
+ linkType: hard
+
"regenerate-unicode-properties@npm:^10.1.0":
version: 10.1.1
resolution: "regenerate-unicode-properties@npm:10.1.1"
From 03da2709109e982b028061789e2783306695468f Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 23:29:12 +0530
Subject: [PATCH 077/104] added layout related settings in theme object
---
.../src/views/ThemeLab/ThemeLab.jsx | 63 +++++++++++++++++--
1 file changed, 58 insertions(+), 5 deletions(-)
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
index 404d66e75..16c9ba4be 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
@@ -16,20 +16,73 @@ import LayoutSetting from './LayoutSetting';
import ThemeSetting from './ThemeSetting';
import { Light as SyntaxHighlighter } from 'react-syntax-highlighter';
import { dracula } from 'react-syntax-highlighter/dist/esm/styles/hljs';
+import useHeaderItemsStore from '../../store/headerItemsStore';
+import useMessageItemsStore from '../../store/messageItemsStore';
+import useChatInputItemsStore from '../../store/chatInputItemsStore';
const ThemeLab = () => {
+ const { theme } = useTheme();
+ const dispatchToastMessage = useToastBarDispatch();
const styles = getThemeLabStyles(useTheme());
const setThemeLabOpen = useLayoutStore((state) => state.setThemeLabOpen);
const [paletteActive, setPaletteAction] = useState(true);
const [themeModalOpen, setThemeModalOpen] = useState(false);
const [generatedTheme, setGeneratedTheme] = useState(null);
- const { theme } = useTheme();
- const dispatchToastMessage = useToastBarDispatch();
+
+ const { surfaceItems: headerSurfaceItems, menuItems: headerMenuItems } =
+ useHeaderItemsStore((state) => ({
+ surfaceItems: state.surfaceItems,
+ menuItems: state.menuItems,
+ }));
+
+ const { surfaceItems: messageSurfaceItems, menuItems: messageMenuItems } =
+ useMessageItemsStore((state) => ({
+ surfaceItems: state.surfaceItems,
+ menuItems: state.menuItems,
+ }));
+
+ const { surfaceItems: inputSurfaceItems, formatters } =
+ useChatInputItemsStore((state) => ({
+ surfaceItems: state.surfaceItems,
+ formatters: state.formatters,
+ }));
const handleThemeGeneration = () => {
setThemeModalOpen(true);
- const themeString = JSON.stringify(theme, null, 2)
- .replace(/\\n/g, '\n')
+ const finalFormatters = inputSurfaceItems.includes('formatter')
+ ? formatters
+ : [];
+ const addedTheme = {
+ ...theme,
+ components: {
+ ChatHeader: {
+ configOverrides: {
+ optionConfig: {
+ surfaceItems: headerSurfaceItems,
+ menuItems: headerMenuItems,
+ },
+ },
+ },
+ MessageToolbox: {
+ configOverrides: {
+ optionConfig: {
+ surfaceItems: messageSurfaceItems,
+ menuItems: messageMenuItems,
+ },
+ },
+ },
+ ChatInputFormattingToolbar: {
+ configOverrides: {
+ optionConfig: {
+ surfaceItems: inputSurfaceItems,
+ formatters: finalFormatters,
+ },
+ },
+ },
+ },
+ };
+ const themeString = JSON.stringify(addedTheme, null, 2)
+ .replace(/"([^"]+)":/g, '$1:')
.replace(/\\"/g, "'");
setGeneratedTheme(themeString);
};
@@ -106,7 +159,7 @@ const ThemeLab = () => {
From abaaff0b36f4cbf02db93158a0a37acfb2dbd84f Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 23:34:54 +0530
Subject: [PATCH 078/104] changed to small case
---
packages/react/src/theme/ModernVariant/StormySeas.js | 2 +-
packages/react/src/views/Message/MessageHeader.js | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/packages/react/src/theme/ModernVariant/StormySeas.js b/packages/react/src/theme/ModernVariant/StormySeas.js
index 13ae3112a..67e1d864c 100644
--- a/packages/react/src/theme/ModernVariant/StormySeas.js
+++ b/packages/react/src/theme/ModernVariant/StormySeas.js
@@ -80,7 +80,7 @@ const StormySeas = {
},
variants: {
- MessageHeader: 'Colorize',
+ MessageHeader: 'colorize',
PinnedMessages: {
viewType: 'Popup',
},
diff --git a/packages/react/src/views/Message/MessageHeader.js b/packages/react/src/views/Message/MessageHeader.js
index 4c9271df5..d622d6dd9 100644
--- a/packages/react/src/views/Message/MessageHeader.js
+++ b/packages/react/src/views/Message/MessageHeader.js
@@ -23,7 +23,7 @@ const MessageHeader = ({
const { styleOverrides, classNames, variantOverrides } =
useComponentOverrides('MessageHeader');
const { ECOptions } = useRCContext();
- const displayNameVariant = variantOverrides || 'Normal';
+ const displayNameVariant = variantOverrides || 'normal';
const styles = useMessageHeaderStyles();
const { colors } = useTheme();
const getDisplayNameColor = useDisplayNameColor();
@@ -85,7 +85,7 @@ const MessageHeader = ({
css={styles.name}
className={appendClassNames('ec-message-header-name')}
style={
- displayNameVariant === 'Colorize'
+ displayNameVariant === 'colorize'
? { color: getDisplayNameColor(message.u.username) }
: null
}
@@ -99,7 +99,7 @@ const MessageHeader = ({
css={styles.userName}
className={appendClassNames('ec-message-header-username')}
style={
- displayNameVariant === 'Colorize'
+ displayNameVariant === 'colorize'
? { color: getDisplayNameColor(message.u.username) }
: null
}
From 360991f0b9c6dff7ca7802532793d589a1c883ad Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 23:35:12 +0530
Subject: [PATCH 079/104] added variant in theme object
---
packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
index 16c9ba4be..a03497fa6 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
@@ -47,6 +47,11 @@ const ThemeLab = () => {
formatters: state.formatters,
}));
+ const { messageView, displayName } = useLayoutStore((state) => ({
+ messageView: state.messageView,
+ displayName: state.displayName,
+ }));
+
const handleThemeGeneration = () => {
setThemeModalOpen(true);
const finalFormatters = inputSurfaceItems.includes('formatter')
@@ -80,6 +85,11 @@ const ThemeLab = () => {
},
},
},
+
+ variants: {
+ Message: messageView,
+ MessageHeader: displayName,
+ },
};
const themeString = JSON.stringify(addedTheme, null, 2)
.replace(/"([^"]+)":/g, '$1:')
From 8722d14ffbcc3c0f86498cee7f1102fe9cf5677b Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 23:49:12 +0530
Subject: [PATCH 080/104] added sidebar customization in theme object
---
packages/layout_editor/src/store/layoutStore.js | 5 +++++
.../src/views/ChatLayout/ChatLayout.jsx | 12 +++++++++---
.../src/views/ThemeLab/ThemeLab.jsx | 16 ++++++++++++----
3 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/packages/layout_editor/src/store/layoutStore.js b/packages/layout_editor/src/store/layoutStore.js
index 7810d6bf0..94f82220d 100644
--- a/packages/layout_editor/src/store/layoutStore.js
+++ b/packages/layout_editor/src/store/layoutStore.js
@@ -15,6 +15,11 @@ const useLayoutStore = create((set) => ({
setDisplayName: (displayName) => {
set({ displayName });
},
+
+ sidebarWidth: '350px',
+ setSidebarWidth: (sidebarWidth) => {
+ set({ sidebarWidth });
+ },
}));
export default useLayoutStore;
diff --git a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
index 8835a955f..0f745e9da 100644
--- a/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
+++ b/packages/layout_editor/src/views/ChatLayout/ChatLayout.jsx
@@ -1,18 +1,24 @@
import React from 'react';
import { Box, useTheme } from '@embeddedchat/ui-elements';
+import debounce from 'lodash/debounce';
import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
import ChatBody from '../Chatbody/ChatBody';
import ChatInput from '../ChatInput/ChatInput';
import { getChatLayoutStyles } from './ChatLayout.styles';
import DemoSidebar from '../DemoSidebar/DemoSidebar';
import members from '../../data/members.json';
+import useLayoutStore from '../../store/layoutStore';
const ChatLayout = () => {
const theme = useTheme();
const styles = getChatLayoutStyles(theme);
const { colors } = theme;
- const handleResize = (size) => {
+ const { setSidebarWidth } = useLayoutStore((state) => ({
+ setSidebarWidth: state.setSidebarWidth,
+ }));
+
+ const handleResize = debounce((size) => {
const minSize = 26.5;
const maxSize = 60;
const minWidth = 350;
@@ -22,8 +28,8 @@ const ChatLayout = () => {
minWidth +
((size - minSize) / (maxSize - minSize)) * (maxWidth - minWidth);
- console.log(sidebarWidth);
- };
+ setSidebarWidth(`${sidebarWidth}px`);
+ }, 100);
return (
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
index a03497fa6..0ec8bb188 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
@@ -47,10 +47,13 @@ const ThemeLab = () => {
formatters: state.formatters,
}));
- const { messageView, displayName } = useLayoutStore((state) => ({
- messageView: state.messageView,
- displayName: state.displayName,
- }));
+ const { messageView, displayName, sidebarWidth } = useLayoutStore(
+ (state) => ({
+ messageView: state.messageView,
+ displayName: state.displayName,
+ sidebarWidth: state.sidebarWidth,
+ })
+ );
const handleThemeGeneration = () => {
setThemeModalOpen(true);
@@ -60,6 +63,11 @@ const ThemeLab = () => {
const addedTheme = {
...theme,
components: {
+ Sidebar: {
+ styleOverrides: {
+ width: sidebarWidth,
+ },
+ },
ChatHeader: {
configOverrides: {
optionConfig: {
From 9e4e3926a4ddae18991f4f8484062b7ae4d527db Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sat, 20 Jul 2024 23:57:30 +0530
Subject: [PATCH 081/104] extracted theme generation logic
---
.../src/hooks/useThemeGenerator.js | 92 +++++++++++++++++++
.../src/views/ThemeLab/ThemeLab.jsx | 84 +----------------
2 files changed, 97 insertions(+), 79 deletions(-)
create mode 100644 packages/layout_editor/src/hooks/useThemeGenerator.js
diff --git a/packages/layout_editor/src/hooks/useThemeGenerator.js b/packages/layout_editor/src/hooks/useThemeGenerator.js
new file mode 100644
index 000000000..5bf3ce524
--- /dev/null
+++ b/packages/layout_editor/src/hooks/useThemeGenerator.js
@@ -0,0 +1,92 @@
+import { useState } from 'react';
+import { useTheme } from '@embeddedchat/ui-elements';
+import useLayoutStore from '../store/layoutStore';
+import useHeaderItemsStore from '../store/headerItemsStore';
+import useMessageItemsStore from '../store/messageItemsStore';
+import useChatInputItemsStore from '../store/chatInputItemsStore';
+
+const useThemeGenerator = () => {
+ const { theme } = useTheme();
+ const [generatedTheme, setGeneratedTheme] = useState(null);
+
+ const { surfaceItems: headerSurfaceItems, menuItems: headerMenuItems } =
+ useHeaderItemsStore((state) => ({
+ surfaceItems: state.surfaceItems,
+ menuItems: state.menuItems,
+ }));
+
+ const { surfaceItems: messageSurfaceItems, menuItems: messageMenuItems } =
+ useMessageItemsStore((state) => ({
+ surfaceItems: state.surfaceItems,
+ menuItems: state.menuItems,
+ }));
+
+ const { surfaceItems: inputSurfaceItems, formatters } =
+ useChatInputItemsStore((state) => ({
+ surfaceItems: state.surfaceItems,
+ formatters: state.formatters,
+ }));
+
+ const { messageView, displayName, sidebarWidth } = useLayoutStore(
+ (state) => ({
+ messageView: state.messageView,
+ displayName: state.displayName,
+ sidebarWidth: state.sidebarWidth,
+ })
+ );
+
+ const generateTheme = () => {
+ const finalFormatters = inputSurfaceItems.includes('formatter')
+ ? formatters
+ : [];
+ const addedTheme = {
+ ...theme,
+ components: {
+ Sidebar: {
+ styleOverrides: {
+ width: sidebarWidth,
+ },
+ },
+ ChatHeader: {
+ configOverrides: {
+ optionConfig: {
+ surfaceItems: headerSurfaceItems,
+ menuItems: headerMenuItems,
+ },
+ },
+ },
+ MessageToolbox: {
+ configOverrides: {
+ optionConfig: {
+ surfaceItems: messageSurfaceItems,
+ menuItems: messageMenuItems,
+ },
+ },
+ },
+ ChatInputFormattingToolbar: {
+ configOverrides: {
+ optionConfig: {
+ surfaceItems: inputSurfaceItems,
+ formatters: finalFormatters,
+ },
+ },
+ },
+ },
+ variants: {
+ Message: messageView,
+ MessageHeader: displayName,
+ },
+ };
+ const themeString = JSON.stringify(addedTheme, null, 2)
+ .replace(/"([^"]+)":/g, '$1:')
+ .replace(/\\"/g, "'");
+ setGeneratedTheme(themeString);
+ };
+
+ return {
+ generatedTheme,
+ generateTheme,
+ };
+};
+
+export default useThemeGenerator;
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
index 0ec8bb188..e79eba74b 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
@@ -7,102 +7,28 @@ import {
Modal,
SidebarContent,
SidebarHeader,
- useTheme,
useToastBarDispatch,
+ useTheme,
} from '@embeddedchat/ui-elements';
-import useLayoutStore from '../../store/layoutStore';
+import useThemeGenerator from '../../hooks/useThemeGenerator';
import { getThemeLabStyles } from './ThemeLab.styles';
import LayoutSetting from './LayoutSetting';
import ThemeSetting from './ThemeSetting';
import { Light as SyntaxHighlighter } from 'react-syntax-highlighter';
import { dracula } from 'react-syntax-highlighter/dist/esm/styles/hljs';
-import useHeaderItemsStore from '../../store/headerItemsStore';
-import useMessageItemsStore from '../../store/messageItemsStore';
-import useChatInputItemsStore from '../../store/chatInputItemsStore';
+import useLayoutStore from '../../store/layoutStore';
const ThemeLab = () => {
- const { theme } = useTheme();
+ const { generatedTheme, generateTheme } = useThemeGenerator();
const dispatchToastMessage = useToastBarDispatch();
const styles = getThemeLabStyles(useTheme());
const setThemeLabOpen = useLayoutStore((state) => state.setThemeLabOpen);
const [paletteActive, setPaletteAction] = useState(true);
const [themeModalOpen, setThemeModalOpen] = useState(false);
- const [generatedTheme, setGeneratedTheme] = useState(null);
-
- const { surfaceItems: headerSurfaceItems, menuItems: headerMenuItems } =
- useHeaderItemsStore((state) => ({
- surfaceItems: state.surfaceItems,
- menuItems: state.menuItems,
- }));
-
- const { surfaceItems: messageSurfaceItems, menuItems: messageMenuItems } =
- useMessageItemsStore((state) => ({
- surfaceItems: state.surfaceItems,
- menuItems: state.menuItems,
- }));
-
- const { surfaceItems: inputSurfaceItems, formatters } =
- useChatInputItemsStore((state) => ({
- surfaceItems: state.surfaceItems,
- formatters: state.formatters,
- }));
-
- const { messageView, displayName, sidebarWidth } = useLayoutStore(
- (state) => ({
- messageView: state.messageView,
- displayName: state.displayName,
- sidebarWidth: state.sidebarWidth,
- })
- );
const handleThemeGeneration = () => {
+ generateTheme();
setThemeModalOpen(true);
- const finalFormatters = inputSurfaceItems.includes('formatter')
- ? formatters
- : [];
- const addedTheme = {
- ...theme,
- components: {
- Sidebar: {
- styleOverrides: {
- width: sidebarWidth,
- },
- },
- ChatHeader: {
- configOverrides: {
- optionConfig: {
- surfaceItems: headerSurfaceItems,
- menuItems: headerMenuItems,
- },
- },
- },
- MessageToolbox: {
- configOverrides: {
- optionConfig: {
- surfaceItems: messageSurfaceItems,
- menuItems: messageMenuItems,
- },
- },
- },
- ChatInputFormattingToolbar: {
- configOverrides: {
- optionConfig: {
- surfaceItems: inputSurfaceItems,
- formatters: finalFormatters,
- },
- },
- },
- },
-
- variants: {
- Message: messageView,
- MessageHeader: displayName,
- },
- };
- const themeString = JSON.stringify(addedTheme, null, 2)
- .replace(/"([^"]+)":/g, '$1:')
- .replace(/\\"/g, "'");
- setGeneratedTheme(themeString);
};
const handleCopyToClipboard = () => {
From ec1492137285674d4cffbd53dd8e502211a965b1 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 21 Jul 2024 12:07:46 +0530
Subject: [PATCH 082/104] added theme in ec settings
---
packages/rc-app/endpoints/AuthTokenEndpoint.ts | 8 +++-----
packages/rc-app/endpoints/InfoEndpoint.ts | 3 +++
packages/rc-app/settings/settings.ts | 11 +++++++++++
3 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/packages/rc-app/endpoints/AuthTokenEndpoint.ts b/packages/rc-app/endpoints/AuthTokenEndpoint.ts
index 70b31759d..589b58948 100644
--- a/packages/rc-app/endpoints/AuthTokenEndpoint.ts
+++ b/packages/rc-app/endpoints/AuthTokenEndpoint.ts
@@ -46,11 +46,9 @@ export class AuthTokenEndpoint extends ApiEndpoint {
},
headers: {
...(await this.generateHeaders(read, "POST")),
- "Set-Cookie": [
- `ec-token=${token}; Max-Age=${
- 24 * 60 * 60
- }; Path=/; HttpOnly; SameSite=None; Secure`,
- ],
+ "Set-Cookie": `ec-token=${token}; Max-Age=${
+ 24 * 60 * 60
+ }; Path=/; HttpOnly; SameSite=None; Secure`,
},
};
}
diff --git a/packages/rc-app/endpoints/InfoEndpoint.ts b/packages/rc-app/endpoints/InfoEndpoint.ts
index 2f5e8c1d8..9eee1d8d4 100644
--- a/packages/rc-app/endpoints/InfoEndpoint.ts
+++ b/packages/rc-app/endpoints/InfoEndpoint.ts
@@ -47,6 +47,7 @@ export class InfoEndpoint extends ApiEndpoint {
hideHeader,
secure,
dark,
+ theme,
] = await getEnvironmentValues(readEnvironment, {
serviceName: "custom-oauth-name",
client_id: "client-id",
@@ -65,6 +66,7 @@ export class InfoEndpoint extends ApiEndpoint {
hideHeader: "hide-header",
secure: "secure",
dark: "dark",
+ theme: "theme",
});
const [redirect_uri, allowedOrigins] = await Promise.all([
@@ -97,6 +99,7 @@ export class InfoEndpoint extends ApiEndpoint {
hideHeader,
secure,
dark,
+ theme,
},
},
};
diff --git a/packages/rc-app/settings/settings.ts b/packages/rc-app/settings/settings.ts
index 2ef3b53f4..3f0e7e2bf 100644
--- a/packages/rc-app/settings/settings.ts
+++ b/packages/rc-app/settings/settings.ts
@@ -212,4 +212,15 @@ export const propSettings: ISetting[] = [
public: false,
packageValue: false,
},
+
+ {
+ id: "theme",
+ i18nLabel: "Custom Theme",
+ i18nDescription:
+ "Define a custom theme for remotely styling EmbeddedChat. This allows you to customize the appearance and behavior of the chat interface.",
+ type: SettingType.CODE,
+ required: false,
+ public: false,
+ packageValue: "",
+ },
];
From fd274eb962beb5d5d55dac8a60027e74c3f07212 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 21 Jul 2024 12:36:03 +0530
Subject: [PATCH 083/104] added theme parsing
---
packages/react/package.json | 1 +
packages/react/src/lib/overrideECProps.js | 22 +++++++++++++++++++++-
yarn.lock | 1 +
3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/packages/react/package.json b/packages/react/package.json
index 476cbf026..86af08529 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -95,6 +95,7 @@
"date-fns": "^2.30.0",
"emoji-picker-react": "^4.4.9",
"emoji-toolkit": "^7.0.1",
+ "json5": "^2.2.3",
"normalize.css": "^8.0.1",
"prop-types": "^15.8.1",
"swiper": "^11.1.0",
diff --git a/packages/react/src/lib/overrideECProps.js b/packages/react/src/lib/overrideECProps.js
index 00c9b0f7b..2660b8903 100644
--- a/packages/react/src/lib/overrideECProps.js
+++ b/packages/react/src/lib/overrideECProps.js
@@ -1,13 +1,33 @@
+import JSON5 from 'json5';
+
export const overrideECProps = (prevConfig, remoteConfig) => {
if (!remoteConfig || Object.keys(remoteConfig).length === 0) {
return prevConfig;
}
+ const parseThemeString = (str) => {
+ try {
+ return JSON5.parse(str);
+ } catch (e) {
+ console.error('Failed to parse theme: ', e);
+ return null;
+ }
+ };
+
const updatedConfig = {
...prevConfig,
...Object.keys(remoteConfig).reduce((acc, key) => {
if (remoteConfig[key] !== '') {
- acc[key] = remoteConfig[key];
+ if (key === 'theme') {
+ const parsedTheme = parseThemeString(remoteConfig[key]);
+ if (parsedTheme) {
+ acc[key] = parsedTheme;
+ } else {
+ acc[key] = prevConfig[key];
+ }
+ } else {
+ acc[key] = remoteConfig[key];
+ }
}
return acc;
}, {}),
diff --git a/yarn.lock b/yarn.lock
index 0b772473a..f26dc0fd0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2491,6 +2491,7 @@ __metadata:
eslint-plugin-storybook: ^0.6.12
identity-obj-proxy: ^3.0.0
jest: ^27.5.1
+ json5: ^2.2.3
lint-staged: ^12.4.2
normalize.css: ^8.0.1
npm-run-all: ^4.1.5
From b0414f6a72985ddc7fb4ca8a86004b1e10af289d Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 21 Jul 2024 13:11:36 +0530
Subject: [PATCH 084/104] removed running prebuild to allow running apps while
building
---
packages/react/package.json | 2 +-
packages/ui-elements/package.json | 2 +-
packages/ui-kit/package.json | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/packages/react/package.json b/packages/react/package.json
index 86af08529..6a2c98d89 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -13,7 +13,7 @@
],
"scripts": {
"prebuild": "rimraf dist",
- "build": "yarn prebuild && rollup -c --context=window --environment NODE_ENV:production",
+ "build": "rollup -c --context=window --environment NODE_ENV:production",
"watch": "rollup -c --watch --context=window",
"test:lint": "eslint src/**/*.js",
"format": "prettier --write 'src/' ",
diff --git a/packages/ui-elements/package.json b/packages/ui-elements/package.json
index ed205907f..f8e41b8c0 100644
--- a/packages/ui-elements/package.json
+++ b/packages/ui-elements/package.json
@@ -14,7 +14,7 @@
],
"scripts": {
"prebuild": "rimraf dist",
- "build": "yarn prebuild && rollup -c --context=window --environment NODE_ENV:production",
+ "build": "rollup -c --context=window --environment NODE_ENV:production",
"watch": "rollup -c --watch --context=window",
"test:lint": "eslint src/**/*.js",
"format": "prettier --write 'src/' ",
diff --git a/packages/ui-kit/package.json b/packages/ui-kit/package.json
index f9c84254b..9d9ddb0d8 100644
--- a/packages/ui-kit/package.json
+++ b/packages/ui-kit/package.json
@@ -14,7 +14,7 @@
],
"scripts": {
"prebuild": "rimraf dist",
- "build": "yarn prebuild && rollup -c --context=window --environment NODE_ENV:production",
+ "build": "rollup -c --context=window --environment NODE_ENV:production",
"watch": "rollup -c --watch --context=window",
"test:lint": "eslint src/**/*.js",
"format": "prettier --write 'src/' ",
From dec8ba7b9e29c40665205e1d43efb867eda35c63 Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 21 Jul 2024 15:54:41 +0530
Subject: [PATCH 085/104] updated docs
added dependency
---
packages/{react => }/docs/authentication.md | 4 +-
packages/docs/ec_rc_setup.md | 31 ++++
packages/docs/embeddedchat_dev.md | 163 ++++++++++++++++++
packages/docs/embeddedchat_setup.md | 162 +++++++++++++++++
packages/docs/layout_editor.md | 58 +++++++
packages/{react => }/docs/theming.md | 148 ++++++++--------
.../{react => }/docs/theming_technical.md | 2 +-
packages/docs/ui-elements.md | 95 ++++++++++
packages/layout_editor/README.md | 60 ++++++-
packages/layout_editor/package.json | 1 +
.../src/views/ThemeLab/ThemeLab.jsx | 6 +-
.../src/views/ThemeLab/ThemeLab.styles.js | 6 +
packages/react/README.md | 4 +-
packages/ui-elements/README.md | 95 ++++++++++
.../src/components/Heading/Heading.js | 5 +-
yarn.lock | 3 +-
16 files changed, 751 insertions(+), 92 deletions(-)
rename packages/{react => }/docs/authentication.md (97%)
create mode 100644 packages/docs/ec_rc_setup.md
create mode 100644 packages/docs/embeddedchat_dev.md
create mode 100644 packages/docs/embeddedchat_setup.md
create mode 100644 packages/docs/layout_editor.md
rename packages/{react => }/docs/theming.md (73%)
rename packages/{react => }/docs/theming_technical.md (99%)
create mode 100644 packages/docs/ui-elements.md
create mode 100644 packages/ui-elements/README.md
diff --git a/packages/react/docs/authentication.md b/packages/docs/authentication.md
similarity index 97%
rename from packages/react/docs/authentication.md
rename to packages/docs/authentication.md
index 5bae0ae21..7bbba4a02 100644
--- a/packages/react/docs/authentication.md
+++ b/packages/docs/authentication.md
@@ -72,7 +72,7 @@ auth: {
This method leverages the OAuth configuration established in Rocket.Chat, ensuring a streamlined authentication process.
-For instructions on installing the EmbeddedChat RC app on your Rocket.Chat server, refer to the [EmbeddedChat RC App installation guide](../../rc-app/README.md).
+For instructions on installing the EmbeddedChat RC app on your Rocket.Chat server, refer to the [EmbeddedChat RC App installation guide](ec_rc_setup.md).
Certainly! Here are the instructions to enable OAuth login in the EmbeddedChat RC app, without using sub-bullets:
@@ -118,8 +118,6 @@ Currently, EmbeddedChat supports two modes for enabling auto-login. After the us
Here’s a concise explanation of how it operates: after logging in, the token is transferred to the EmbeddedChat RC app, where it is set as an HTTP-only cookie. During auto-login, EmbeddedChat makes a request that includes cookies managed by the browser to the RC app endpoint. The RC app retrieves the token and sends it back, which EmbeddedChat then forwards to the `/api/v1/login` endpoint of the Rocket.chat server for authentication. This functionality is fully integrated into the EmbeddedChat app, presented here for technical insight.
-To install the EmbeddedChat RC app on your Rocket.Chat server, please refer to the [EmbeddedChat RC App installation guide](../../rc-app/README.md).
-
## Integrating with EmbeddedChat
When integrating any of these authentication methods into `EmbeddedChat`, ensure to include the `auth` prop containing the desired configuration, and set the `secure` prop to true to activate the HTTP-Only cookie.
diff --git a/packages/docs/ec_rc_setup.md b/packages/docs/ec_rc_setup.md
new file mode 100644
index 000000000..51523fa54
--- /dev/null
+++ b/packages/docs/ec_rc_setup.md
@@ -0,0 +1,31 @@
+# Embedded Chat: A staple in excellent customer service
+
+An easy-to-use, full-stack component (React.js + backend behaviors) for embedding Rocket.Chat into your web app.
+
+![ec-demo-image](https://github.com/RocketChat/EmbeddedChat/assets/78961432/b85c7b8a-65e2-4a90-a843-f4072c942ac0)
+
+## EmbeddedChat RC App
+
+This monorepo hosts an RC app designed to enhance EmbeddedChat functionalities. It facilitates remote configuration of EmbeddedChat settings, implements secure login (storing the resume token as an HTTP-only cookie), and help integrates Rocket.Chat OAuth login capabilities.
+
+### Installation
+
+To install this application, follow these steps:
+
+1. Clone the repository to your local machine:
+
+ ```
+ git clone https://github.com/RocketChat/EmbeddedChat.git
+ ```
+
+2. Navigate to the `packages/rc-app` directory.
+
+3. Open a command prompt and execute the following command:
+
+ ```
+ rc-apps deploy --url host_url --username your_username --password your_password
+ ```
+
+Ensure to substitute `host_url`, `your_username`, and `your_password` with your Rocket.Chat server's URL, username, and password respectively.
+
+Note: A Rocket.Chat server setup is required. If you haven't set up one yet, refer to this [link](https://developer.rocket.chat/open-source-projects/server/server-environment-setup) for instructions.
\ No newline at end of file
diff --git a/packages/docs/embeddedchat_dev.md b/packages/docs/embeddedchat_dev.md
new file mode 100644
index 000000000..445039da9
--- /dev/null
+++ b/packages/docs/embeddedchat_dev.md
@@ -0,0 +1,163 @@
+Embedded Chat: A staple in excellent customer service
+
+![image](https://github.com/RocketChat/EmbeddedChat/assets/78961432/574be6b4-d2f7-4bea-a7b1-4c6e840d8e22)
+
+An easy-to-use, full-stack component (React.js + backend behaviors) for embedding Rocket.Chat into your web app.
+
+_EmbeddedChat is a full-stack React component designed to integrate Rocket.Chat into your web app. It is fully configurable, extensible, and flexible, offering various preconfigured designs, multiple login options, and more. The component is tightly integrated with the Rocket.Chat server using the Rocket.Chat SDK, and its entire UI is built using custom components._
+
+![ec-demo-image](https://github.com/RocketChat/EmbeddedChat/assets/78961432/b85c7b8a-65e2-4a90-a843-f4072c942ac0)
+
+
+
+## Installation and Usage
+
+Installation and usage documentation could be found here [EmbeddedChat installation and usage](embeddedchat_setup.md)
+
+## Development
+
+### Local Setup
+
+To develop and test `EmbeddedChat`, you need a local instance of the Rocket.Chat server. Follow the guide in the [Rocket.Chat Developer Docs](https://developer.rocket.chat/v1/docs/server-environment-setup) for setting up a Rocket.Chat development environment.
+
+Ensure that the "Enable CORS" option is turned on in your Rocket.Chat server. You can find it under Administration > Settings > General > REST API > Enable CORS. This setting must be enabled to access the app's functionality.
+
+#### Prerequisites
+
+- **Node.js**: Version 16.19.0 is required. Use [Node Version Manager (NVM)](https://github.com/nvm-sh/nvm) for easy switching between Node.js versions.
+
+ To install and use the correct Node.js version, execute the following commands with the specific version number:
+
+ ```bash
+ nvm install
+ nvm use
+ ```
+
+ Replace `` with the required Node.js version
+
+- **Yarn Workspaces**: Ensure Yarn workspaces are enabled. If not, run:
+
+ ```bash
+ corepack enable
+ ```
+
+#### Install Dependencies
+
+Install all necessary dependencies by navigating to the root directory of `EmbeddedChat` and running:
+
+```bash
+yarn
+```
+
+#### Build Packages
+
+After installing dependencies, build the packages (`auth`, `api`, and `react`) by running the following command in the root directory:
+
+```bash
+yarn build
+```
+
+#### Starting Storybook for React
+
+Navigate to the `react` package directory and start Storybook with the following commands:
+
+```bash
+cd packages/react
+yarn storybook
+```
+
+Storybook should now be operational. Experiment with `EmbeddedChat` and its components, observing real-time changes in Storybook.
+
+### Custom Rocket Chat Server Configuration
+
+By default, Storybook connects to `http://localhost:3000`. To use a different Rocket Chat server:
+
+Create a `.env` file in the `packages/react` directory.
+
+Set the `STORYBOOK_RC_HOST` variable:
+
+```bash
+STORYBOOK_RC_HOST=
+```
+
+Alternatively, run this command in the `packages/react` directory:
+
+```bash
+STORYBOOK_RC_HOST= yarn storybook
+```
+
+### Package Development Overview
+
+The project uses a monorepo structure with three key packages: `react`, `auth`, and `api`. Each package fulfills a vital role in the application:
+
+#### React Package Development
+
+The `react` package serves as the main frontend component, having all UI elements and views. It interfaces with the `auth` and `api` packages to manage interactions with the Rocket.Chat server, including API calls and authentication.
+
+To develop and test changes in the `react` package:
+
+1. Navigate to the directory of the `react` package:
+
+```bash
+cd packages/react
+```
+
+2. Start Storybook to view live changes:
+
+```bash
+yarn storybook
+```
+
+#### Auth Package Development
+
+To develop and test changes in the `auth` package:
+
+1. Navigate to the `auth` package directory:
+
+ ```bash
+ cd packages/auth
+ ```
+
+2. Start the development server:
+
+ ```bash
+ yarn dev
+ ```
+
+#### API Package Development
+
+For development in the `api` package:
+
+1. Navigate to the `api` package directory:
+
+ ```bash
+ cd packages/api
+ ```
+
+2. Start the development server:
+
+ ```bash
+ yarn dev
+ ```
+
+**Development Workflow Notes:**
+
+- The `react` package relies on the `api` package. After making changes to the `api`, rebuild it using `yarn build` in `packages/api`, and then restart the React project.
+
+- Similarly, the `api` package depends on the `auth` package. After making changes to `auth`, rebuild it using `yarn build` in `packages/auth`, and then restart the `api` development environment.
+
+This structured approach facilitates cohesive development and integration across all components of the application.
+
+### Conclusion
+
+This environment offers a complete setup for developing and testing the `EmbeddedChat` component, alongside its `api` and `auth` packages. Feel free to explore and enhance the capabilities of `EmbeddedChat`!
+
+### Contributors
+
+
+
+
diff --git a/packages/docs/embeddedchat_setup.md b/packages/docs/embeddedchat_setup.md
new file mode 100644
index 000000000..27794abb2
--- /dev/null
+++ b/packages/docs/embeddedchat_setup.md
@@ -0,0 +1,162 @@
+# Embedded Chat: A staple in excellent customer service
+
+An easy-to-use, full-stack component (React.js + backend behaviors) for embedding Rocket.Chat into your web app.
+
+![ec-demo-image](https://github.com/RocketChat/EmbeddedChat/assets/78961432/b85c7b8a-65e2-4a90-a843-f4072c942ac0)
+
+
+## Installation
+
+```bash
+npm install @embeddedchat/react
+# or
+yarn add @embeddedchat/react
+```
+
+## Importing the Component
+
+Import the `EmbeddedChat` component into your file:
+
+```javascript
+import { EmbeddedChat } from '@embeddedchat/react';
+```
+
+## Basic Usage
+
+To use the `EmbeddedChat` component, include it in your component's render method or return statement. Here's a basic example:
+
+```jsx
+
+```
+
+## Props
+
+EmbeddedChat supports various props that are used to customize different aspects of this component. A brief description of all the supported props is listed as follows:
+
+- `isClosable` (boolean): If `true`, the chat window can be closed. Defaults to `false`.
+- `setClosableState` (function): Callback for handling the closable state.
+- `width` (string): Width of the chat window. Defaults to `'100%'`.
+- `height` (string): Height of the chat window. Defaults to `'95vh'`.
+- `host` (string): URL of your RocketChat server.
+- `roomId` (string): ID of the chat room. Defaults to `GENERAL`.
+- `channelName` (string): Fallback channel name for the chat. Defaults to `general`.
+- `anonymousMode` (boolean): Enables anonymous mode. Defaults to `false`.
+- `toastBarPosition` (string): Position of the toast bar. Defaults to `'bottom right'`.
+- `showRoles` (boolean): Displays user roles. Defaults to `false`.
+- `showAvatar` (boolean): Shows user avatars. Defaults to `true`.
+- `showUsername` (boolean): Displays the user's username. Defaults to `false`.
+- `showName` (boolean): Displays the user's name. Defaults to `true`.
+- `enableThreads` (boolean): Enables chat threads. Defaults to `false`.
+- `theme` (object): Theme object for styling.
+- `className` (string): Additional CSS class for styling.
+- `style` (object): Inline styles for the chat window.
+- `hideHeader` (boolean): Hides the chat header. Defaults to `false`.
+- `auth` (object): Authentication configuration.
+- `secure` (boolean): Uses HTTP-only cookies for authentication. Defaults to `false`.
+- `dark` (boolean): Enables dark mode in the application. Defaults to `false`.
+- `remoteOpt` (boolean): Allows props override remotely using `EmbeddedChat RC App`. Defaults to `false`.
+
+## Understanding Prop Functionality
+
+This section of the guide aims to provide a detailed explanation of these props. However, props such as `width`, `height`, `host`, `channelName`, `showRoles`, `showAvatar`, `showUsername`, `showName`, `className`, `style`, `hideHeader`, and `dark` are straightforward and will not receive detailed discussion here.
+
+- ### Managing the Closable State
+
+ When integrating EmbeddedChat, developers have the flexibility to control its visibility. They can utilize their internal state management to achieve this. EmbeddedChat supports a function to manage this state and provides a close icon for executing the close functionality.
+
+ To enable the closable feature, set `isClosable` to `true` and provide a `setClosableState` function to handle the open and close states of the chat window.
+
+ ```jsx
+
+ ```
+
+ This setup allows seamless integration of EmbeddedChat with custom control over its visibility.
+
+- ### Obtaining Room ID
+
+ By default, EmbeddedChat uses the 'GENERAL' channel as its default channel in a Rocket.Chat server. However, EmbeddedChat can be integrated into any channel within your workspace, provided you have the roomId of the desired room. To retrieve the roomId for your specified room, execute the following curl command. This API call accepts the roomName parameter and returns detailed information about the room, including its unique ID:
+
+ ```bash
+ curl --request GET \
+ --url 'http://your-rocketchat-server.com/api/v1/rooms.info?roomName=channelName' \
+ --header 'X-Auth-Token: auth-token' \
+ --header 'X-User-Id: user-id' \
+ --header 'accept: application/json'
+ ```
+
+ For a comprehensive guide on retrieving room information, consult the Rocket.Chat API documentation: [Get Room Information](https://developer.rocket.chat/apidocs/get-room-information).
+
+ Once you obtain the roomId, provide it as the value for the `roomId` prop to connect to the corresponding room.
+
+ ```jsx
+
+ ```
+
+- ### Anonymous Mode
+
+ Rocket.Chat allows users to view messages in read-only mode without logging in. This setting can be enabled by navigating to Workspace settings > Accounts > Allow Anonymous Read. Once this setting is activated, EmbeddedChat can also display channel messages in read-only mode without requiring a login. To enable this feature, pass `anonymousMode` as true in the props.
+
+ ```jsx
+
+ ```
+
+- ### Enabling Threads
+
+ Threads allow users to discuss a specific message separately, preventing the main channel from being cluttered with numerous messages and providing a dedicated space for focused discussions. By default, this setting is enabled, but it can be disabled by passing `enableThreads` as false.
+
+ ```jsx
+
+ ```
+
+- ### Theming and Customization
+
+ EmbeddedChat supports various design variants, style overrides, and many other customization features. To tailor it to your needs, you can pass a `theme` object to customize the appearance according to your application's design:
+
+ ```jsx
+
+ ```
+
+ However, the `theme` object must follow a specific format. For detailed information on theming EmbeddedChat, refer to [theming.md](theming.md).
+
+ In Storybook, demonstrations of different themes and variants are provided in the 'Design Variants' section.
+
+- ### Authentication Guide
+
+ Embedded Chat supports various methods for logging into a Rocket.Chat server. These include three primary methods:
+
+ 1. **Token-Based Authentication**: This can be either a personal access token or a service-specific access token.
+ 2. **Login Credentials**: Using a valid username/email and password.
+ 3. **OAuth Authentication**: Uses the OAuth configuration set up in Rocket.Chat. [This method requires installing the EmbeddedChat RC App on the Rocket.Chat server]
+
+ #### Storing the `ec-token` for Auto Login
+
+ After completing the login, a resume token, referred to as `ec-token`, is used for auto login. There are currently two supported methods to store this token:
+
+ 1. **Local Storage**: Store the `ec-token` in the browser's local storage.
+ 2. **HTTP-Only Cookie**: Store the `ec-token` as an HTTP-only cookie. [This method requires the installation of the EmbeddedChat RC App on the Rocket.Chat server]
+
+ For a detailed guide on using each of these authentication methods with the `auth` and `secure` props, refer to the [authentication.md](authentication.md) file.
+
+## Development
+
+Follow this [EmbeddedChat Readme](https://github.com/RocketChat/EmbeddedChat) to setup EmbeddedChat for development.
+
+## Conclusion
+
+The `EmbeddedChat` component offers a flexible and feature-rich solution for integrating RocketChat into your application. Customize it according to your needs to enhance your app's chat functionality.
diff --git a/packages/docs/layout_editor.md b/packages/docs/layout_editor.md
new file mode 100644
index 000000000..5a587f0a5
--- /dev/null
+++ b/packages/docs/layout_editor.md
@@ -0,0 +1,58 @@
+# Embedded Chat: A Staple in Excellent Customer Service
+
+An easy-to-use, full-stack component (React.js + backend behaviors) for embedding Rocket.Chat into your web app.
+
+![ec-demo-image](https://github.com/RocketChat/EmbeddedChat/assets/78961432/b85c7b8a-65e2-4a90-a843-f4072c942ac0)
+
+## Layout Editor
+
+![image](https://github.com/user-attachments/assets/a42a66af-d8c0-4d3a-aa1a-71f91b07310e)
+
+We offer a layout editor that lets you customize the design and appearance of the EmbeddedChat component in real time. Features include:
+
+- **ChatHeader Options**: Add, remove, or reorder various options.
+- **MessageToolbox Options**: Tailor toolbox settings.
+- **ChatInputFormatting Toolbar Options**: Adjust input toolbar settings.
+- **Drag-and-Drop**: Easily switch and reorder menu and surface items.
+- **Resizable Sidebar**: Adjust the sidebar by dragging.
+- **Theme Lab**: Customize layout and theme settings, including palette colors and typography.
+
+### Theme Lab
+
+In the Theme Lab, you can:
+
+- **Customize Palette Colors**: Adjust colors for both light and dark modes.
+- **Font Settings**: Modify font-related settings.
+- **Layout Customization**: Change layout variants and display names, and restore deleted options.
+
+Once satisfied with your changes, click the "Generate Theme" button to create a theme object.
+
+![image](https://github.com/user-attachments/assets/88ab51b6-aac6-41cc-b911-38378ed61e12)
+
+### Integration
+
+To apply your custom theme:
+
+```jsx
+
+```
+
+Alternatively, you can paste the theme object into the Theme settings of the EmbeddedChat RC App. Note: These settings will only take effect if the `remoteOpt` prop is set to `true` when configuring EmbeddedChat.
+
+### Development
+
+Clone the repo, navigate to `packages/layout_editor`, then run:
+
+```bash
+yarn dev # Start server
+yarn build # Build for production
+yarn preview # Preview build
+```
+
+### Additional Resources
+
+- For installation instructions of the EmbeddedChat RC App, visit [this guide](ec_rc_setup.md).
+- For detailed prop usage, refer to [this guide](embeddedchat_setup.md).
diff --git a/packages/react/docs/theming.md b/packages/docs/theming.md
similarity index 73%
rename from packages/react/docs/theming.md
rename to packages/docs/theming.md
index 2c2119d59..a4e3a4fd9 100644
--- a/packages/react/docs/theming.md
+++ b/packages/docs/theming.md
@@ -24,64 +24,64 @@ where `myCustomTheme` must adhere to a specific format. The default theme object
```jsx
const DefaultTheme = {
schemes: {
- radius: '0.2rem',
+ radius: "0.2rem",
common: {
- black: 'hsl(0, 100%, 0%)',
- white: 'hsl(0, 100%, 100%)',
+ black: "hsl(0, 100%, 0%)",
+ white: "hsl(0, 100%, 100%)",
},
light: {
- background: 'hsl(0, 0%, 100%)',
- foreground: 'hsl(240, 10%, 3.9%)',
- card: 'hsl(0, 0%, 100%)',
- cardForeground: 'hsl(240, 10%, 3.9%)',
- popover: 'hsl(0, 0%, 100%)',
- popoverForeground: 'hsl(240, 10%, 3.9%)',
- primary: 'hsl(240, 5.9%, 10%)',
- primaryForeground: 'hsl(0, 0%, 98%)',
- secondary: 'hsl(240, 4.8%, 95.9%)',
- secondaryForeground: 'hsl(240, 5.9%, 10%)',
- muted: 'hsl(240, 4.8%, 95.9%)',
- mutedForeground: 'hsl(240, 3.8%, 46.1%)',
- accent: 'hsl(240, 4.8%, 95.9%)',
- accentForeground: 'hsl(240, 5.9%, 10%)',
- destructive: 'hsl(0, 84.2%, 60.2%)',
- destructiveForeground: 'hsl(0, 0%, 98%)',
- border: 'hsl(240, 5.9%, 90%)',
- input: 'hsl(240, 5.9%, 90%)',
- ring: 'hsl(240, 5.9%, 10%)',
- warning: 'hsl(38, 92%, 50%)',
- warningForeground: 'hsl(48, 96%, 89%)',
- success: 'hsl(91, 60.4%, 81.2%)',
- successForeground: 'hsl(90, 61.1%, 14.1%)',
- info: 'hsl(214, 76.4%, 50.2%)',
- infoForeground: 'hsl(214.3, 77.8%, 92.9%)',
+ background: "hsl(0, 0%, 100%)",
+ foreground: "hsl(240, 10%, 3.9%)",
+ card: "hsl(0, 0%, 100%)",
+ cardForeground: "hsl(240, 10%, 3.9%)",
+ popover: "hsl(0, 0%, 100%)",
+ popoverForeground: "hsl(240, 10%, 3.9%)",
+ primary: "hsl(240, 5.9%, 10%)",
+ primaryForeground: "hsl(0, 0%, 98%)",
+ secondary: "hsl(240, 4.8%, 95.9%)",
+ secondaryForeground: "hsl(240, 5.9%, 10%)",
+ muted: "hsl(240, 4.8%, 95.9%)",
+ mutedForeground: "hsl(240, 3.8%, 46.1%)",
+ accent: "hsl(240, 4.8%, 95.9%)",
+ accentForeground: "hsl(240, 5.9%, 10%)",
+ destructive: "hsl(0, 84.2%, 60.2%)",
+ destructiveForeground: "hsl(0, 0%, 98%)",
+ border: "hsl(240, 5.9%, 90%)",
+ input: "hsl(240, 5.9%, 90%)",
+ ring: "hsl(240, 5.9%, 10%)",
+ warning: "hsl(38, 92%, 50%)",
+ warningForeground: "hsl(48, 96%, 89%)",
+ success: "hsl(91, 60.4%, 81.2%)",
+ successForeground: "hsl(90, 61.1%, 14.1%)",
+ info: "hsl(214, 76.4%, 50.2%)",
+ infoForeground: "hsl(214.3, 77.8%, 92.9%)",
},
dark: {
- background: 'hsl(240, 10%, 3.9%)',
- foreground: 'hsl(0, 0%, 98%)',
- card: 'hsl(240, 10%, 3.9%)',
- cardForeground: 'hsl(0, 0%, 98%)',
- popover: 'hsl(240, 10%, 3.9%)',
- popoverForeground: 'hsl(0, 0%, 98%)',
- primary: 'hsl(0, 0%, 98%)',
- primaryForeground: 'hsl(240, 5.9%, 10%)',
- secondary: 'hsl(240, 3.7%, 15.9%)',
- secondaryForeground: 'hsl(0, 0%, 98%)',
- muted: 'hsl(240, 3.7%, 15.9%)',
- mutedForeground: 'hsl(240, 5%, 64.9%)',
- accent: 'hsl(240, 3.7%, 15.9%)',
- accentForeground: 'hsl(0, 0%, 98%)',
- destructive: 'hsl(0, 62.8%, 30.6%)',
- destructiveForeground: 'hsl(0, 0%, 98%)',
- border: 'hsl(240, 3.7%, 15.9%)',
- input: 'hsl(240, 3.7%, 15.9%)',
- ring: 'hsl(240, 4.9%, 83.9%)',
- warning: 'hsl(48, 96%, 89%)',
- warningForeground: 'hsl(38, 92%, 50%)',
- success: 'hsl(90, 61.1%, 14.1%)',
- successForeground: 'hsl(90, 60%, 90.2%)',
- info: 'hsl(214.3, 77.8%, 92.9%)',
- infoForeground: 'hsl(214.4, 75.8%, 19.4%)',
+ background: "hsl(240, 10%, 3.9%)",
+ foreground: "hsl(0, 0%, 98%)",
+ card: "hsl(240, 10%, 3.9%)",
+ cardForeground: "hsl(0, 0%, 98%)",
+ popover: "hsl(240, 10%, 3.9%)",
+ popoverForeground: "hsl(0, 0%, 98%)",
+ primary: "hsl(0, 0%, 98%)",
+ primaryForeground: "hsl(240, 5.9%, 10%)",
+ secondary: "hsl(240, 3.7%, 15.9%)",
+ secondaryForeground: "hsl(0, 0%, 98%)",
+ muted: "hsl(240, 3.7%, 15.9%)",
+ mutedForeground: "hsl(240, 5%, 64.9%)",
+ accent: "hsl(240, 3.7%, 15.9%)",
+ accentForeground: "hsl(0, 0%, 98%)",
+ destructive: "hsl(0, 62.8%, 30.6%)",
+ destructiveForeground: "hsl(0, 0%, 98%)",
+ border: "hsl(240, 3.7%, 15.9%)",
+ input: "hsl(240, 3.7%, 15.9%)",
+ ring: "hsl(240, 4.9%, 83.9%)",
+ warning: "hsl(48, 96%, 89%)",
+ warningForeground: "hsl(38, 92%, 50%)",
+ success: "hsl(90, 61.1%, 14.1%)",
+ successForeground: "hsl(90, 60%, 90.2%)",
+ info: "hsl(214.3, 77.8%, 92.9%)",
+ infoForeground: "hsl(214.4, 75.8%, 19.4%)",
},
},
@@ -104,45 +104,35 @@ const DefaultTheme = {
fontWeightRegular: 400,
},
h1: {
- fontSize: '2rem',
+ fontSize: "2rem",
fontWeight: 800,
},
h2: {
- fontSize: '1.5rem',
+ fontSize: "1.5rem",
fontWeight: 800,
},
h3: {
- fontSize: '1.3rem',
+ fontSize: "1.3rem",
fontWeight: 400,
},
h4: {
- fontSize: '1rem',
+ fontSize: "1rem",
fontWeight: 400,
},
h5: {
- fontSize: '0.83rem',
+ fontSize: "0.83rem",
fontWeight: 400,
},
h6: {
- fontSize: '0.67rem',
+ fontSize: "0.67rem",
fontWeight: 500,
},
},
shadows: [
- 'none',
- 'rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px',
- 'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
+ "none",
+ "rgba(17, 17, 26, 0.05) 0px 1px 0px, rgba(17, 17, 26, 0.1) 0px 0px 8px",
+ "rgba(100, 100, 111, 0.2) 0px 7px 29px 0px",
],
- zIndex: {
- divider: 1000,
- body: 1100,
- general: 1200,
- menu: 1300,
-
- tooltip: 1400,
- modal: 1500,
- toastbar: 1600,
- },
};
```
@@ -158,8 +148,6 @@ const DefaultTheme = {
- The `shadows` key currently includes two shadows used in the app. You can give different colors or styles to these shadows as needed. If more shadows are added, the source code will also need to be modified to reflect those changes.
-- The `zIndex` key controls the stacking of different components in the application. It is recommended not to change these values unless necessary. If a requirement arises, adjustments can be made accordingly.
-
### Understanding to the `components` key
The `components` key/object allows you to customize specific components by applying custom styles, adding custom classes, or modifying certain configurations.
@@ -239,10 +227,16 @@ Similarly, for `MessageToolbox`, the supported options are:
],
```
-For the `ChatInputFormattingToolbar` component, the supported options are:
+For the `ChatInputFormattingToolbar` component, the supported options in `surfaceItems` are:
+
+```jsx
+["emoji", "formatter", "audio", "video", "file"];
+```
+
+Additionally, all formatters can be reordered or removed by passing a `formatter` array in the `optionConfig`, as demonstrated below:
```jsx
-['emoji', 'formatter', 'audio', 'video', 'file'],
+formatters: ["bold", "italic", "strike", "code", "multiline"];
```
Note: In `ChatInputFormattingToolbar`, `menuItems` is not supported as all options will be displayed directly on the surface, and none will be inside a menu.
@@ -285,7 +279,7 @@ To enable the colorize variant for the `MessageHeader` component, use the follow
```jsx
variants: {
- MessageHeader: 'Colorize',
+ MessageHeader: 'colorize',
}
```
diff --git a/packages/react/docs/theming_technical.md b/packages/docs/theming_technical.md
similarity index 99%
rename from packages/react/docs/theming_technical.md
rename to packages/docs/theming_technical.md
index 523eb8bb5..20a608c1f 100644
--- a/packages/react/docs/theming_technical.md
+++ b/packages/docs/theming_technical.md
@@ -166,7 +166,7 @@ const displayNameVariant = variantOverrides || 'Normal';
css={styles.userName}
className={appendClassNames('ec-message-header-username', classNames)}
style={
- displayNameVariant === 'Colorize'
+ displayNameVariant === 'colorize'
? { color: getDisplayNameColor(message.u.username) }
: null
}
diff --git a/packages/docs/ui-elements.md b/packages/docs/ui-elements.md
new file mode 100644
index 000000000..cdb6c8a4b
--- /dev/null
+++ b/packages/docs/ui-elements.md
@@ -0,0 +1,95 @@
+# Embedded Chat: A Staple in Excellent Customer Service
+
+The Embedded Chat component is an easy-to-use, full-stack solution for integrating Rocket.Chat into your web application. It combines React.js with backend behaviors for a seamless chat experience.
+
+![Embedded Chat Demo](https://github.com/RocketChat/EmbeddedChat/assets/78961432/b85c7b8a-65e2-4a90-a843-f4072c942ac0)
+
+## UI Elements
+
+This component is part of a monorepo, specifically within the `packages/react` project, which houses the main EmbeddedChat Component.
+
+![image](https://github.com/user-attachments/assets/2fd76929-ce43-4bb3-8ea8-3a7318468923)
+
+### Development
+
+To develop and view the components:
+
+1. Clone the repository.
+2. Navigate to `packages/layout_editor`.
+3. Run the following commands:
+
+ ```bash
+ yarn build # To build the component library
+ yarn storybook # To view the components in real-time
+ ```
+
+### Installation
+
+To install the component library, run:
+
+```bash
+yarn add @embeddedchat/ui-elements
+```
+
+This library offers a range of UI components, including `Box`, `Input`, `StaticSelect`, `MultiSelect`, and more. For a complete list of available components, please refer to the Storybook.
+
+You can import components using the following syntax:
+
+````jsx
+import {
+ Box,
+ Heading,
+ Icon,
+ Menu,
+ useToastBarDispatch,
+ useComponentOverrides,
+} from '@embeddedchat/ui-elements';
+
+### Theming
+
+By default, the component uses a standard theme. You can apply a custom theme and mode by importing `ThemeProvider` from `@embeddedchat/ui-elements` and using it as follows:
+
+```jsx
+import { ThemeProvider } from "@embeddedchat/ui-elements";
+
+
+
+;
+````
+
+Supported modes are `'light'` and `'dark'`. Ensure that the `theme` prop is provided with the correct format.
+
+The library also includes a `useTheme` hook for managing the theme and mode:
+
+```jsx
+import { useTheme } from "@embeddedchat/ui-elements";
+
+const { theme, mode, setTheme, setMode } = useTheme();
+```
+
+The `useTheme` hook provides:
+
+- `theme`: The current theme object.
+- `mode`: The current mode (`'light'` or `'dark'`).
+- `setTheme`: A function to update the theme dynamically.
+- `setMode`: A function to toggle between `'light'` and `'dark'` modes.
+
+`setTheme` allows you to change the theme on-the-fly, while `setMode` lets you switch between light and dark modes. This flexibility is useful for dynamically adjusting the appearance of your application based on user preferences or other conditions.
+
+You can use this hook to style your components with the provided theme. `useTheme()` also provides `colors` and `invertedColors`, simplifying color management. `colors` will automatically adjust according to the mode, while `invertedColors` provides colors for the alternate mode.
+
+Additionally, the library offers `darken` and `lighten` functions to dynamically adjust color brightness:
+
+```jsx
+import { darken, lighten } from "@embeddedchat/ui-elements";
+```
+
+These functions can be used as follows:
+
+```jsx
+background-color: ${mode === 'light'
+ ? darken(colors.background, 0.03)
+ : lighten(colors.background, 1)};
+```
+
+This hook allows you to dynamically switch modes or themes as needed. The `theme` object must adhere to a specific format, as outlined in the EmbeddedChat `react` project [Readme.md](theming.md).
diff --git a/packages/layout_editor/README.md b/packages/layout_editor/README.md
index f768e33fc..690a7d8bf 100644
--- a/packages/layout_editor/README.md
+++ b/packages/layout_editor/README.md
@@ -1,8 +1,58 @@
-# React + Vite
+# Embedded Chat: A Staple in Excellent Customer Service
-This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
+An easy-to-use, full-stack component (React.js + backend behaviors) for embedding Rocket.Chat into your web app.
-Currently, two official plugins are available:
+![ec-demo-image](https://github.com/RocketChat/EmbeddedChat/assets/78961432/b85c7b8a-65e2-4a90-a843-f4072c942ac0)
-- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
-- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
+## Layout Editor
+
+![image](https://github.com/user-attachments/assets/a42a66af-d8c0-4d3a-aa1a-71f91b07310e)
+
+We offer a layout editor that lets you customize the design and appearance of the EmbeddedChat component in real time. Features include:
+
+- **ChatHeader Options**: Add, remove, or reorder various options.
+- **MessageToolbox Options**: Tailor toolbox settings.
+- **ChatInputFormatting Toolbar Options**: Adjust input toolbar settings.
+- **Drag-and-Drop**: Easily switch and reorder menu and surface items.
+- **Resizable Sidebar**: Adjust the sidebar by dragging.
+- **Theme Lab**: Customize layout and theme settings, including palette colors and typography.
+
+### Theme Lab
+
+In the Theme Lab, you can:
+
+- **Customize Palette Colors**: Adjust colors for both light and dark modes.
+- **Font Settings**: Modify font-related settings.
+- **Layout Customization**: Change layout variants and display names, and restore deleted options.
+
+Once satisfied with your changes, click the "Generate Theme" button to create a theme object.
+
+![image](https://github.com/user-attachments/assets/88ab51b6-aac6-41cc-b911-38378ed61e12)
+
+### Integration
+
+To apply your custom theme:
+
+```jsx
+
+```
+
+Alternatively, you can paste the theme object into the Theme settings of the EmbeddedChat RC App. Note: These settings will only take effect if the `remoteOpt` prop is set to `true` when configuring EmbeddedChat.
+
+### Development
+
+Clone the repo, navigate to `packages/layout_editor`, then run:
+
+```bash
+yarn dev # Start server
+yarn build # Build for production
+yarn preview # Preview build
+```
+
+### Additional Resources
+
+- For installation instructions of the EmbeddedChat RC App, visit [this guide](../rc-app/README.md).
+- For detailed prop usage, refer to [this guide](../react/README.md).
diff --git a/packages/layout_editor/package.json b/packages/layout_editor/package.json
index 28dea7bc0..9d035a4c7 100644
--- a/packages/layout_editor/package.json
+++ b/packages/layout_editor/package.json
@@ -12,6 +12,7 @@
"dependencies": {
"@dnd-kit/core": "^6.1.0",
"@dnd-kit/sortable": "^8.0.0",
+ "@embeddedchat/markups": "workspace:^",
"@embeddedchat/ui-elements": "workspace:^",
"react": "^18.2.0",
"react-color": "^2.19.3",
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
index e79eba74b..74af0374a 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.jsx
@@ -95,8 +95,10 @@ const ThemeLab = () => {
setThemeModalOpen(false)}>
-
- Your theme is ready!
+
+
+ Your theme is ready!
+
setThemeModalOpen(false)} />
diff --git a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
index ff874544c..adb4986a7 100644
--- a/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
+++ b/packages/layout_editor/src/views/ThemeLab/ThemeLab.styles.js
@@ -28,6 +28,12 @@ export const getThemeLabStyles = ({ colors }) => {
closeBtn: css`
padding: 0.5rem;
`,
+
+ modalTitle: css`
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ `,
};
return styles;
diff --git a/packages/react/README.md b/packages/react/README.md
index f8a72877b..5478d4bf3 100644
--- a/packages/react/README.md
+++ b/packages/react/README.md
@@ -132,7 +132,7 @@ This section of the guide aims to provide a detailed explanation of these props.
/>
```
- However, the `theme` object must follow a specific format. For detailed information on theming EmbeddedChat, refer to [theming.md](docs/theming.md).
+ However, the `theme` object must follow a specific format. For detailed information on theming EmbeddedChat, refer to [theming.md](../docs/theming.md).
In Storybook, demonstrations of different themes and variants are provided in the 'Design Variants' section.
@@ -151,7 +151,7 @@ This section of the guide aims to provide a detailed explanation of these props.
1. **Local Storage**: Store the `ec-token` in the browser's local storage.
2. **HTTP-Only Cookie**: Store the `ec-token` as an HTTP-only cookie. [This method requires the installation of the EmbeddedChat RC App on the Rocket.Chat server]
- For a detailed guide on using each of these authentication methods with the `auth` and `secure` props, refer to the [authentication.md](docs/authentication.md) file.
+ For a detailed guide on using each of these authentication methods with the `auth` and `secure` props, refer to the [authentication.md](../docs/authentication.md) file.
## Development
diff --git a/packages/ui-elements/README.md b/packages/ui-elements/README.md
new file mode 100644
index 000000000..5a17e4a48
--- /dev/null
+++ b/packages/ui-elements/README.md
@@ -0,0 +1,95 @@
+# Embedded Chat: A Staple in Excellent Customer Service
+
+The Embedded Chat component is an easy-to-use, full-stack solution for integrating Rocket.Chat into your web application. It combines React.js with backend behaviors for a seamless chat experience.
+
+![Embedded Chat Demo](https://github.com/RocketChat/EmbeddedChat/assets/78961432/b85c7b8a-65e2-4a90-a843-f4072c942ac0)
+
+## UI Elements
+
+This component is part of a monorepo, specifically within the `packages/react` project, which houses the main EmbeddedChat Component.
+
+![image](https://github.com/user-attachments/assets/2fd76929-ce43-4bb3-8ea8-3a7318468923)
+
+### Development
+
+To develop and view the components:
+
+1. Clone the repository.
+2. Navigate to `packages/layout_editor`.
+3. Run the following commands:
+
+ ```bash
+ yarn build # To build the component library
+ yarn storybook # To view the components in real-time
+ ```
+
+### Installation
+
+To install the component library, run:
+
+```bash
+yarn add @embeddedchat/ui-elements
+```
+
+This library offers a range of UI components, including `Box`, `Input`, `StaticSelect`, `MultiSelect`, and more. For a complete list of available components, please refer to the Storybook.
+
+You can import components using the following syntax:
+
+````jsx
+import {
+ Box,
+ Heading,
+ Icon,
+ Menu,
+ useToastBarDispatch,
+ useComponentOverrides,
+} from '@embeddedchat/ui-elements';
+
+### Theming
+
+By default, the component uses a standard theme. You can apply a custom theme and mode by importing `ThemeProvider` from `@embeddedchat/ui-elements` and using it as follows:
+
+```jsx
+import { ThemeProvider } from "@embeddedchat/ui-elements";
+
+
+
+;
+````
+
+Supported modes are `'light'` and `'dark'`. Ensure that the `theme` prop is provided with the correct format.
+
+The library also includes a `useTheme` hook for managing the theme and mode:
+
+```jsx
+import { useTheme } from "@embeddedchat/ui-elements";
+
+const { theme, mode, setTheme, setMode } = useTheme();
+```
+
+The `useTheme` hook provides:
+
+- `theme`: The current theme object.
+- `mode`: The current mode (`'light'` or `'dark'`).
+- `setTheme`: A function to update the theme dynamically.
+- `setMode`: A function to toggle between `'light'` and `'dark'` modes.
+
+`setTheme` allows you to change the theme on-the-fly, while `setMode` lets you switch between light and dark modes. This flexibility is useful for dynamically adjusting the appearance of your application based on user preferences or other conditions.
+
+You can use this hook to style your components with the provided theme. `useTheme()` also provides `colors` and `invertedColors`, simplifying color management. `colors` will automatically adjust according to the mode, while `invertedColors` provides colors for the alternate mode.
+
+Additionally, the library offers `darken` and `lighten` functions to dynamically adjust color brightness:
+
+```jsx
+import { darken, lighten } from "@embeddedchat/ui-elements";
+```
+
+These functions can be used as follows:
+
+```jsx
+background-color: ${mode === 'light'
+ ? darken(colors.background, 0.03)
+ : lighten(colors.background, 1)};
+```
+
+This hook allows you to dynamically switch modes or themes as needed. The `theme` object must adhere to a specific format, as outlined in the EmbeddedChat `react` project [Readme.md](../docs/theming.md).
diff --git a/packages/ui-elements/src/components/Heading/Heading.js b/packages/ui-elements/src/components/Heading/Heading.js
index 8cce39bd4..541be8fb9 100644
--- a/packages/ui-elements/src/components/Heading/Heading.js
+++ b/packages/ui-elements/src/components/Heading/Heading.js
@@ -38,7 +38,10 @@ const Heading = ({ level = 1, children, ...props }) => {
const Tag = `h${level}`;
const { theme } = useTheme();
- const style = { ...defaultTypography[Tag], ...theme.typography[Tag] };
+ const style = {
+ ...defaultTypography[Tag],
+ ...(theme.typography?.[Tag] || {}),
+ };
return (
Date: Sun, 21 Jul 2024 16:15:03 +0530
Subject: [PATCH 086/104] add all doc reference
---
README.md | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/README.md b/README.md
index 63000a1fe..59b58af26 100644
--- a/README.md
+++ b/README.md
@@ -156,6 +156,24 @@ This structured approach facilitates cohesive development and integration across
This environment offers a complete setup for developing and testing the `EmbeddedChat` component, alongside its `api` and `auth` packages. Feel free to explore and enhance the capabilities of `EmbeddedChat`!
+## References
+
+- Embedded Chat Development: [EC Development](packages/docs/embeddedchat_dev.md) – Explore development techniques for Embedded Chat.
+
+- Embedded Chat Setup: [Setup Instructions](packages/docs/embeddedchat_setup.md) – Start setting up Embedded Chat in your app.
+
+- UI Elements: [Setup & Dev Guide](packages/docs/ui-elements.md) – Integration and customization of UI elements.
+
+- Layout Editor: [Using the Editor](packages/docs/layout_editor.md) – Customize the chat interface with the layout editor.
+
+- EmbeddedChat RC Setup: [Setup Instructions](packages/docs/ec_rc_setup.md) – Guide for setting up Embedded Chat RC App.
+
+- Authentication: [Guide](packages/docs/authentication.md) – Configure and manage authentication for Embedded Chat.
+
+- Theming Guide: [Guide](packages/docs/theming.md) – Guide to theming options and customization.
+
+- Theming Technical: [Technical Overview](packages/docs/theming_technical.md) – Technical aspects of theming.
+
### Contributors
From 85c802a4e39b3129a0b8895b7798ae855e67b53b Mon Sep 17 00:00:00 2001
From: Zishan Ahmad
Date: Sun, 21 Jul 2024 21:31:39 +0530
Subject: [PATCH 087/104] changed layout editor title
---
packages/layout_editor/index.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/layout_editor/index.html b/packages/layout_editor/index.html
index e4b78eae1..328655b40 100644
--- a/packages/layout_editor/index.html
+++ b/packages/layout_editor/index.html
@@ -4,7 +4,7 @@
- Vite + React + TS
+ EmbeddedChat Layout Designer
From 790061318523cbd61a777ec6e4565ca240298f9d Mon Sep 17 00:00:00 2001
From: Devansh Kansagra <125076549+devanshkansagra@users.noreply.github.com>
Date: Mon, 26 Aug 2024 15:26:50 +0530
Subject: [PATCH 088/104] FEAT: Added support to deploy monorepos to github
pages (#615)
* Added support to deploy monorepos to github pages
* Changed the branch
* Added Environment variable
* Move files to build folder instead of copying it
* Removed the redundant checkout code from deploy workflow
* Removed deploy workflow and added official deploy-pages action of github to deploy monorepo to github pages
* Added STORYBOOK_RC_HOST env variable
* Added layout_editor in build-deploy workflow
* Created docs site for EmbeddedChat Docs
* Update docs README.md
* Removed copyright from footer
* Removed docusaurus images and svgs
* Switched to yarn from npm
* Made the changes that were reviewed
* removed unnecessary text from theming
* Added github-pages environment
* Changed the workflow
* Changed the content permission to write
---
.github/workflows/deploy.yml | 81 +
lerna.json | 3 +-
package.json | 3 +-
packages/docs/.gitignore | 20 +
packages/docs/.yarn/install-state.gz | Bin 0 -> 1076029 bytes
packages/docs/README.md | 25 +
packages/docs/babel.config.js | 3 +
packages/docs/blog/EmbeddedChat-2022.md | 157 +
packages/docs/blog/EmbeddedChat-2023.md | 237 +
packages/docs/blog/EmbeddedChat-2024.md | 204 +
.../Development/dev_launch.md} | 21 +-
.../Development}/theming_technical.md | 9 +-
.../{ => docs/Development}/ui-elements.md | 15 +-
.../docs/{ => docs/Usage}/authentication.md | 10 +-
packages/docs/docs/Usage/ec_rc_setup.md | 35 +
.../{ => docs/Usage}/embeddedchat_setup.md | 6 +-
.../docs/{ => docs/Usage}/layout_editor.md | 10 +-
packages/docs/{ => docs/Usage}/theming.md | 10 +-
packages/docs/docs/introduction.md | 27 +
packages/docs/docusaurus.config.js | 133 +
packages/docs/ec_rc_setup.md | 31 -
packages/docs/package.json | 44 +
packages/docs/sidebars.js | 46 +
packages/docs/src/assets/EC-Logo.png | Bin 0 -> 157851 bytes
packages/docs/src/assets/app.png | Bin 0 -> 26547 bytes
packages/docs/src/assets/easy.png | Bin 0 -> 18625 bytes
packages/docs/src/assets/pencil.png | Bin 0 -> 9796 bytes
.../src/components/HomepageFeatures/index.js | 68 +
.../HomepageFeatures/styles.module.css | 11 +
packages/docs/src/css/custom.css | 30 +
packages/docs/src/pages/index.js | 48 +
packages/docs/src/pages/index.module.css | 23 +
packages/docs/src/pages/markdown-page.md | 7 +
packages/docs/static/.nojekyll | 0
packages/docs/static/img/EC-Logo.png | Bin 0 -> 157851 bytes
packages/docs/static/img/favicon.ico | Bin 0 -> 157851 bytes
packages/docs/yarn.lock | 11762 ++++++++++++++++
packages/layout_editor/vite.config.ts | 1 +
38 files changed, 13000 insertions(+), 80 deletions(-)
create mode 100644 .github/workflows/deploy.yml
create mode 100644 packages/docs/.gitignore
create mode 100644 packages/docs/.yarn/install-state.gz
create mode 100644 packages/docs/README.md
create mode 100644 packages/docs/babel.config.js
create mode 100644 packages/docs/blog/EmbeddedChat-2022.md
create mode 100644 packages/docs/blog/EmbeddedChat-2023.md
create mode 100644 packages/docs/blog/EmbeddedChat-2024.md
rename packages/docs/{embeddedchat_dev.md => docs/Development/dev_launch.md} (79%)
rename packages/docs/{ => docs/Development}/theming_technical.md (96%)
rename packages/docs/{ => docs/Development}/ui-elements.md (86%)
rename packages/docs/{ => docs/Usage}/authentication.md (96%)
create mode 100644 packages/docs/docs/Usage/ec_rc_setup.md
rename packages/docs/{ => docs/Usage}/embeddedchat_setup.md (97%)
rename packages/docs/{ => docs/Usage}/layout_editor.md (89%)
rename packages/docs/{ => docs/Usage}/theming.md (97%)
create mode 100644 packages/docs/docs/introduction.md
create mode 100644 packages/docs/docusaurus.config.js
delete mode 100644 packages/docs/ec_rc_setup.md
create mode 100644 packages/docs/package.json
create mode 100644 packages/docs/sidebars.js
create mode 100644 packages/docs/src/assets/EC-Logo.png
create mode 100644 packages/docs/src/assets/app.png
create mode 100644 packages/docs/src/assets/easy.png
create mode 100644 packages/docs/src/assets/pencil.png
create mode 100644 packages/docs/src/components/HomepageFeatures/index.js
create mode 100644 packages/docs/src/components/HomepageFeatures/styles.module.css
create mode 100644 packages/docs/src/css/custom.css
create mode 100644 packages/docs/src/pages/index.js
create mode 100644 packages/docs/src/pages/index.module.css
create mode 100644 packages/docs/src/pages/markdown-page.md
create mode 100644 packages/docs/static/.nojekyll
create mode 100644 packages/docs/static/img/EC-Logo.png
create mode 100644 packages/docs/static/img/favicon.ico
create mode 100644 packages/docs/yarn.lock
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
new file mode 100644
index 000000000..de66ccd85
--- /dev/null
+++ b/.github/workflows/deploy.yml
@@ -0,0 +1,81 @@
+name: Build and Publish Storybook to GitHub Pages
+
+on:
+ push:
+ branches:
+ - develop
+
+permissions:
+ contents: write
+ pages: write
+ id-token: write
+
+env:
+ STORYBOOK_RC_HOST: "https://demo.qa.rocket.chat"
+
+jobs:
+ build-and-deploy:
+ runs-on: ubuntu-latest
+ environment:
+ name: github-pages
+ url: "https://rocketchat.github.io/EmbeddedChat/"
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: "16.19.0"
+
+ - name: Install Dependencies
+ run: yarn
+
+ - name: Build Storybook
+ run: yarn build:storybook
+ working-directory: packages/react
+
+ - name: Build UI-Elements
+ run: yarn build:storybook
+ working-directory: packages/ui-elements
+
+ - name: Build Layout Editor
+ run: npm run build
+ working-directory: packages/layout_editor
+
+ - name: Setup Node.js for Docs
+ uses: actions/setup-node@v4
+ with:
+ node-version: "18.x"
+
+ - name: "Install dependencies for docs"
+ run: yarn install
+ working-directory: packages/docs/
+
+ - name: Build Docs
+ run: yarn build
+ working-directory: packages/docs
+
+ - name: Prepare Build Folder
+ run: |
+ mkdir -p build
+ mkdir -p build/ui-elements
+ mkdir -p build/layout_editor
+ mkdir -p build/docs
+
+ mv -v packages/react/storybook-static/* build/
+ mv -v packages/ui-elements/storybook-static/* build/ui-elements/
+ mv -v packages/layout_editor/dist/* build/layout_editor/
+ mv -v packages/docs/build/* build/docs/
+
+ - name: Deploy to GitHub Pages
+ uses: crazy-max/ghaction-github-pages@v2
+ with:
+ target_branch: gh-deploy
+ build_dir: build/
+ commit_message: "Deploy to Github Pages"
+ jekyll: false
+ keep_history: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/lerna.json b/lerna.json
index bbd0e6162..d3c0c2035 100644
--- a/lerna.json
+++ b/lerna.json
@@ -3,7 +3,8 @@
"useWorkspaces": true,
"version": "0.0.0",
"packages": [
- "packages/*"
+ "packages/*",
+ "!packages/docs"
],
"npmClient": "yarn"
}
diff --git a/package.json b/package.json
index 8ece6278c..dc3d3f204 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,8 @@
"description": "Integrate RocketChat into any React based web app using this extensible, robust component library",
"packageManager": "yarn@3.6.4",
"workspaces": [
- "packages/*"
+ "packages/*",
+ "!packages/docs"
],
"scripts": {
"preinstall": "node scripts/node-check.js",
diff --git a/packages/docs/.gitignore b/packages/docs/.gitignore
new file mode 100644
index 000000000..b2d6de306
--- /dev/null
+++ b/packages/docs/.gitignore
@@ -0,0 +1,20 @@
+# Dependencies
+/node_modules
+
+# Production
+/build
+
+# Generated files
+.docusaurus
+.cache-loader
+
+# Misc
+.DS_Store
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
diff --git a/packages/docs/.yarn/install-state.gz b/packages/docs/.yarn/install-state.gz
new file mode 100644
index 0000000000000000000000000000000000000000..1f543b7313c13e8e5dffe3c58455ccb461185c01
GIT binary patch
literal 1076029
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