@cometchat/skills-cli 2.4.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -37
- package/dist/index.js +1690 -12609
- package/dist/utils/error-dictionary.js +0 -69
- package/package.json +10 -12
- package/dist/registry/schemas/config.schema.json +0 -119
- package/dist/registry/schemas/template.schema.json +0 -142
- package/dist/registry/v6/experiences/1-conversation-list/astro.template.json +0 -89
- package/dist/registry/v6/experiences/1-conversation-list/nextjs-pages.template.json +0 -83
- package/dist/registry/v6/experiences/1-conversation-list/nextjs.template.json +0 -83
- package/dist/registry/v6/experiences/1-conversation-list/react-router.template.json +0 -102
- package/dist/registry/v6/experiences/1-conversation-list/reactjs-dedicated-route.template.json +0 -81
- package/dist/registry/v6/experiences/1-conversation-list/reactjs.template.json +0 -86
- package/dist/registry/v6/experiences/1-conversation-list/templates/astro/ChatApp.css.tpl +0 -43
- package/dist/registry/v6/experiences/1-conversation-list/templates/astro/ChatApp.tsx.tpl +0 -86
- package/dist/registry/v6/experiences/1-conversation-list/templates/astro/CometChatSelector.tsx.tpl +0 -40
- package/dist/registry/v6/experiences/1-conversation-list/templates/astro/chat.astro.tpl +0 -17
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs/CometChatNoSSR.css.tpl +0 -43
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs/CometChatNoSSR.tsx.tpl +0 -86
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs/CometChatSelector.tsx.tpl +0 -41
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs/chat-page.tsx.tpl +0 -11
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs-pages/CometChatNoSSR.css.tpl +0 -43
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs-pages/CometChatNoSSR.tsx.tpl +0 -88
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs-pages/CometChatSelector.tsx.tpl +0 -41
- package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs-pages/chat-page.tsx.tpl +0 -15
- package/dist/registry/v6/experiences/1-conversation-list/templates/react-router/CometChat-route.tsx.tpl +0 -22
- package/dist/registry/v6/experiences/1-conversation-list/templates/react-router/CometChatNoSSR.css.tpl +0 -43
- package/dist/registry/v6/experiences/1-conversation-list/templates/react-router/CometChatNoSSR.tsx.tpl +0 -87
- package/dist/registry/v6/experiences/1-conversation-list/templates/react-router/CometChatSelector.tsx.tpl +0 -40
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs/App.css.tpl +0 -40
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs/App.tsx.tpl +0 -55
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs/CometChatSelector.tsx.tpl +0 -40
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs/main.tsx.tpl +0 -46
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs-dedicated-route/ChatPage.tsx.tpl +0 -87
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs-dedicated-route/CometChatMessenger.css.tpl +0 -20
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs-dedicated-route/CometChatMessenger.tsx.tpl +0 -54
- package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs-dedicated-route/CometChatSelector.tsx.tpl +0 -40
- package/dist/registry/v6/experiences/2-one-to-one/astro.template.json +0 -81
- package/dist/registry/v6/experiences/2-one-to-one/nextjs.template.json +0 -77
- package/dist/registry/v6/experiences/2-one-to-one/react-router.template.json +0 -93
- package/dist/registry/v6/experiences/2-one-to-one/reactjs-dedicated-route.template.json +0 -75
- package/dist/registry/v6/experiences/2-one-to-one/reactjs.template.json +0 -80
- package/dist/registry/v6/experiences/2-one-to-one/templates/astro/ChatApp.css.tpl +0 -21
- package/dist/registry/v6/experiences/2-one-to-one/templates/astro/ChatApp.tsx.tpl +0 -66
- package/dist/registry/v6/experiences/2-one-to-one/templates/astro/chat.astro.tpl +0 -17
- package/dist/registry/v6/experiences/2-one-to-one/templates/nextjs/CometChatNoSSR.css.tpl +0 -21
- package/dist/registry/v6/experiences/2-one-to-one/templates/nextjs/CometChatNoSSR.tsx.tpl +0 -66
- package/dist/registry/v6/experiences/2-one-to-one/templates/nextjs/chat-page.tsx.tpl +0 -11
- package/dist/registry/v6/experiences/2-one-to-one/templates/react-router/CometChat-route.tsx.tpl +0 -21
- package/dist/registry/v6/experiences/2-one-to-one/templates/react-router/CometChatNoSSR.css.tpl +0 -21
- package/dist/registry/v6/experiences/2-one-to-one/templates/react-router/CometChatNoSSR.tsx.tpl +0 -67
- package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs/App.css.tpl +0 -4
- package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs/App.tsx.tpl +0 -44
- package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs/main.tsx.tpl +0 -46
- package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs-dedicated-route/ChatPage.tsx.tpl +0 -84
- package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs-dedicated-route/CometChatMessenger.css.tpl +0 -9
- package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs-dedicated-route/CometChatMessenger.tsx.tpl +0 -43
- package/dist/registry/v6/experiences/3-tab-based/astro.template.json +0 -93
- package/dist/registry/v6/experiences/3-tab-based/nextjs.template.json +0 -90
- package/dist/registry/v6/experiences/3-tab-based/react-router.template.json +0 -105
- package/dist/registry/v6/experiences/3-tab-based/reactjs-dedicated-route.template.json +0 -89
- package/dist/registry/v6/experiences/3-tab-based/reactjs.template.json +0 -93
- package/dist/registry/v6/experiences/3-tab-based/templates/astro/ChatApp.css.tpl +0 -39
- package/dist/registry/v6/experiences/3-tab-based/templates/astro/ChatApp.tsx.tpl +0 -93
- package/dist/registry/v6/experiences/3-tab-based/templates/astro/CometChatTabs.css.tpl +0 -43
- package/dist/registry/v6/experiences/3-tab-based/templates/astro/CometChatTabs.tsx.tpl +0 -72
- package/dist/registry/v6/experiences/3-tab-based/templates/astro/chat.astro.tpl +0 -17
- package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/CometChatNoSSR.css.tpl +0 -39
- package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/CometChatNoSSR.tsx.tpl +0 -93
- package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/CometChatTabs.css.tpl +0 -43
- package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/CometChatTabs.tsx.tpl +0 -73
- package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/chat-page.tsx.tpl +0 -11
- package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChat-route.tsx.tpl +0 -21
- package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChatNoSSR.css.tpl +0 -39
- package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChatNoSSR.tsx.tpl +0 -94
- package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChatTabs.css.tpl +0 -43
- package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChatTabs.tsx.tpl +0 -72
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/App.css.tpl +0 -7
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/App.tsx.tpl +0 -62
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/CometChatTabs.css.tpl +0 -43
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/CometChatTabs.tsx.tpl +0 -72
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/main.tsx.tpl +0 -46
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs-dedicated-route/ChatPage.tsx.tpl +0 -84
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs-dedicated-route/CometChatMessenger.css.tpl +0 -11
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs-dedicated-route/CometChatMessenger.tsx.tpl +0 -61
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs-dedicated-route/CometChatTabs.css.tpl +0 -43
- package/dist/registry/v6/experiences/3-tab-based/templates/reactjs-dedicated-route/CometChatTabs.tsx.tpl +0 -72
- package/dist/registry/v6/features/catalog.json +0 -526
- package/dist/registry/v6/production/astro/cometchat-token.ts.tpl +0 -86
- package/dist/registry/v6/production/astro.template.json +0 -51
- package/dist/registry/v6/production/nextjs/route.ts.tpl +0 -79
- package/dist/registry/v6/production/nextjs.template.json +0 -50
- package/dist/registry/v6/production/react-router/api.cometchat-token.ts.tpl +0 -73
- package/dist/registry/v6/production/react-router.template.json +0 -58
- package/dist/registry/v6/user-mgmt/astro/cometchat-user.ts.tpl +0 -164
- package/dist/registry/v6/user-mgmt/astro.template.json +0 -33
- package/dist/registry/v6/user-mgmt/nextjs/route.ts.tpl +0 -212
- package/dist/registry/v6/user-mgmt/nextjs.template.json +0 -57
- package/dist/registry/v6/user-mgmt/react-router/api.cometchat-user.ts.tpl +0 -176
- package/dist/registry/v6/user-mgmt/react-router.template.json +0 -40
- package/dist/registry/v6/widget/astro/CometChatWidget.css.tpl +0 -105
- package/dist/registry/v6/widget/astro/CometChatWidget.tsx.tpl +0 -88
- package/dist/registry/v6/widget/astro.template.json +0 -38
- package/dist/registry/v6/widget/nextjs/CometChatWidget.css.tpl +0 -105
- package/dist/registry/v6/widget/nextjs/CometChatWidget.tsx.tpl +0 -88
- package/dist/registry/v6/widget/nextjs.template.json +0 -40
- package/dist/registry/v6/widget/react-router/CometChatWidget.css.tpl +0 -105
- package/dist/registry/v6/widget/react-router/CometChatWidget.tsx.tpl +0 -98
- package/dist/registry/v6/widget/react-router.template.json +0 -36
- package/dist/registry/v6/widget/reactjs/CometChatWidget.css.tpl +0 -105
- package/dist/registry/v6/widget/reactjs/CometChatWidget.tsx.tpl +0 -89
- package/dist/registry/v6/widget/reactjs.template.json +0 -36
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
// Pages Router has no RSC boundary — no `"use client"` directive needed.
|
|
2
|
-
// This file is rendered ONLY on the client because src/pages/chat.tsx
|
|
3
|
-
// imports it via next/dynamic with { ssr: false }.
|
|
4
|
-
import React, { useEffect, useState } from "react";
|
|
5
|
-
import {
|
|
6
|
-
CometChatMessageComposer,
|
|
7
|
-
CometChatMessageHeader,
|
|
8
|
-
CometChatMessageList,
|
|
9
|
-
CometChatUIKit,
|
|
10
|
-
UIKitSettingsBuilder,
|
|
11
|
-
} from "@cometchat/chat-uikit-react";
|
|
12
|
-
import { CometChat } from "@cometchat/chat-sdk-javascript";
|
|
13
|
-
import { CometChatSelector } from "./CometChatSelector";
|
|
14
|
-
// css-variables.css is imported in src/styles/globals.css — do NOT import it here
|
|
15
|
-
import "./CometChatNoSSR.css";
|
|
16
|
-
|
|
17
|
-
const COMETCHAT_CONSTANTS = {
|
|
18
|
-
APP_ID: process.env.{{ENV_PREFIX}}COMETCHAT_APP_ID!,
|
|
19
|
-
REGION: process.env.{{ENV_PREFIX}}COMETCHAT_REGION!,
|
|
20
|
-
AUTH_KEY: process.env.{{ENV_PREFIX}}COMETCHAT_AUTH_KEY!,
|
|
21
|
-
};
|
|
22
|
-
const UID = "{{LOGIN_UID}}";
|
|
23
|
-
|
|
24
|
-
const CometChatNoSSR: React.FC = () => {
|
|
25
|
-
const [user, setUser] = useState<CometChat.User | undefined>();
|
|
26
|
-
const [error, setError] = useState<string | null>(null);
|
|
27
|
-
const [selectedUser, setSelectedUser] = useState<CometChat.User | undefined>();
|
|
28
|
-
const [selectedGroup, setSelectedGroup] = useState<CometChat.Group | undefined>();
|
|
29
|
-
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
const settings = new UIKitSettingsBuilder()
|
|
32
|
-
.setAppId(COMETCHAT_CONSTANTS.APP_ID)
|
|
33
|
-
.setRegion(COMETCHAT_CONSTANTS.REGION)
|
|
34
|
-
.setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY)
|
|
35
|
-
.subscribePresenceForAllUsers()
|
|
36
|
-
.build();
|
|
37
|
-
|
|
38
|
-
CometChatUIKit.init(settings)?.then(() => {
|
|
39
|
-
CometChatUIKit.getLoggedinUser().then((u) => {
|
|
40
|
-
if (!u) {
|
|
41
|
-
CometChatUIKit.login(UID)
|
|
42
|
-
.then(setUser)
|
|
43
|
-
.catch((e: unknown) => setError(String(e)));
|
|
44
|
-
} else {
|
|
45
|
-
setUser(u);
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
}).catch((e: unknown) => setError(String(e)));
|
|
49
|
-
}, []);
|
|
50
|
-
|
|
51
|
-
if (error) return <div style={{ color: "red", padding: 16, fontFamily: "monospace" }}>{error}</div>;
|
|
52
|
-
if (!user) return null;
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<div className="conversations-with-messages">
|
|
56
|
-
<div className="conversations-wrapper">
|
|
57
|
-
<CometChatSelector
|
|
58
|
-
onSelectorItemClicked={(activeItem) => {
|
|
59
|
-
const item =
|
|
60
|
-
activeItem instanceof CometChat.Conversation
|
|
61
|
-
? activeItem.getConversationWith()
|
|
62
|
-
: activeItem;
|
|
63
|
-
if (item instanceof CometChat.User) {
|
|
64
|
-
setSelectedUser(item);
|
|
65
|
-
setSelectedGroup(undefined);
|
|
66
|
-
} else if (item instanceof CometChat.Group) {
|
|
67
|
-
setSelectedUser(undefined);
|
|
68
|
-
setSelectedGroup(item);
|
|
69
|
-
}
|
|
70
|
-
}}
|
|
71
|
-
/>
|
|
72
|
-
</div>
|
|
73
|
-
{selectedUser || selectedGroup ? (
|
|
74
|
-
<div className="messages-wrapper">
|
|
75
|
-
{selectedUser && <CometChatMessageHeader user={selectedUser} />}
|
|
76
|
-
{selectedGroup && <CometChatMessageHeader group={selectedGroup} />}
|
|
77
|
-
{selectedUser && <CometChatMessageList user={selectedUser} />}
|
|
78
|
-
{selectedGroup && <CometChatMessageList group={selectedGroup} />}
|
|
79
|
-
{selectedUser && <CometChatMessageComposer user={selectedUser} />}
|
|
80
|
-
{selectedGroup && <CometChatMessageComposer group={selectedGroup} />}
|
|
81
|
-
</div>
|
|
82
|
-
) : (
|
|
83
|
-
<div className="empty-conversation">Select a conversation to start chatting</div>
|
|
84
|
-
)}
|
|
85
|
-
</div>
|
|
86
|
-
);
|
|
87
|
-
};
|
|
88
|
-
export default CometChatNoSSR;
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { useEffect, useState } from "react";
|
|
3
|
-
import type { CometChat } from "@cometchat/chat-sdk-javascript";
|
|
4
|
-
import {
|
|
5
|
-
CometChatConversations,
|
|
6
|
-
CometChatUIKitLoginListener,
|
|
7
|
-
} from "@cometchat/chat-uikit-react";
|
|
8
|
-
|
|
9
|
-
interface SelectorProps {
|
|
10
|
-
onSelectorItemClicked?: (
|
|
11
|
-
input: CometChat.Conversation | CometChat.User | CometChat.Group,
|
|
12
|
-
type: string
|
|
13
|
-
) => void;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const CometChatSelector = ({
|
|
17
|
-
onSelectorItemClicked = () => {},
|
|
18
|
-
}: SelectorProps) => {
|
|
19
|
-
const [loggedInUser, setLoggedInUser] = useState<CometChat.User | null>(null);
|
|
20
|
-
const [activeConversation, setActiveConversation] = useState<
|
|
21
|
-
CometChat.Conversation | undefined
|
|
22
|
-
>();
|
|
23
|
-
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
setLoggedInUser(CometChatUIKitLoginListener.getLoggedInUser());
|
|
26
|
-
}, []);
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<>
|
|
30
|
-
{loggedInUser && (
|
|
31
|
-
<CometChatConversations
|
|
32
|
-
activeConversation={activeConversation}
|
|
33
|
-
onItemClick={(e) => {
|
|
34
|
-
setActiveConversation(e);
|
|
35
|
-
onSelectorItemClicked(e, "updateSelectedItem");
|
|
36
|
-
}}
|
|
37
|
-
/>
|
|
38
|
-
)}
|
|
39
|
-
</>
|
|
40
|
-
);
|
|
41
|
-
};
|
package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs-pages/chat-page.tsx.tpl
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// Pages Router auto-routes this file to /chat. The CometChat SDK uses
|
|
2
|
-
// browser-only globals (WebSocket, IndexedDB, etc.) so we MUST disable
|
|
3
|
-
// SSR for the chat component via next/dynamic with { ssr: false }.
|
|
4
|
-
// This mirrors the App Router pattern where CometChatNoSSR has a
|
|
5
|
-
// `"use client"` directive — Pages Router achieves the same isolation
|
|
6
|
-
// at the import site instead of with a directive.
|
|
7
|
-
import dynamic from "next/dynamic";
|
|
8
|
-
|
|
9
|
-
const CometChatNoSSR = dynamic(() => import("../cometchat/CometChatNoSSR"), {
|
|
10
|
-
ssr: false,
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
export default function ChatPage() {
|
|
14
|
-
return <CometChatNoSSR />;
|
|
15
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import React, { lazy, Suspense, useEffect, useState } from "react";
|
|
2
|
-
|
|
3
|
-
// Lazy-load the CometChat component so it never executes during SSR
|
|
4
|
-
const CometChatNoSSR = lazy(() => import("../cometchat/CometChatNoSSR"));
|
|
5
|
-
|
|
6
|
-
export default function CometChatRoute() {
|
|
7
|
-
const [mounted, setMounted] = useState(false);
|
|
8
|
-
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
setMounted(true);
|
|
11
|
-
}, []);
|
|
12
|
-
|
|
13
|
-
if (!mounted) {
|
|
14
|
-
return <div style={{ padding: 16 }}>Loading…</div>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<Suspense fallback={<div style={{ padding: 16 }}>Loading…</div>}>
|
|
19
|
-
<CometChatNoSSR />
|
|
20
|
-
</Suspense>
|
|
21
|
-
);
|
|
22
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
.conversations-with-messages {
|
|
2
|
-
display: flex;
|
|
3
|
-
height: 100vh;
|
|
4
|
-
width: 100%;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
.conversations-wrapper {
|
|
8
|
-
height: 100%;
|
|
9
|
-
width: 480px;
|
|
10
|
-
overflow: hidden;
|
|
11
|
-
display: flex;
|
|
12
|
-
flex-direction: column;
|
|
13
|
-
flex-shrink: 0;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.conversations-wrapper > .cometchat {
|
|
17
|
-
overflow: hidden;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.messages-wrapper {
|
|
21
|
-
flex: 1;
|
|
22
|
-
min-width: 0;
|
|
23
|
-
height: 100%;
|
|
24
|
-
display: flex;
|
|
25
|
-
flex-direction: column;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.empty-conversation {
|
|
29
|
-
height: 100%;
|
|
30
|
-
width: 100%;
|
|
31
|
-
display: flex;
|
|
32
|
-
justify-content: center;
|
|
33
|
-
align-items: center;
|
|
34
|
-
background: white;
|
|
35
|
-
color: var(--cometchat-text-color-secondary, #727272);
|
|
36
|
-
font: var(--cometchat-font-body-regular, 400 14px Roboto);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.cometchat .cometchat-message-composer {
|
|
40
|
-
border-radius: 0;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.side-component-wrapper { display: flex; width: 30%; max-width: 420px; flex-direction: column; flex-shrink: 0; background: var(--cometchat-background-color-01, #FFF); border-left: 1px solid var(--cometchat-border-color-light, #F5F5F5); height: 100%; overflow: hidden; }
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
CometChatMessageComposer,
|
|
4
|
-
CometChatMessageHeader,
|
|
5
|
-
CometChatMessageList,
|
|
6
|
-
CometChatUIKit,
|
|
7
|
-
UIKitSettingsBuilder,
|
|
8
|
-
} from "@cometchat/chat-uikit-react";
|
|
9
|
-
import { CometChat } from "@cometchat/chat-sdk-javascript";
|
|
10
|
-
import { CometChatSelector } from "./CometChatSelector";
|
|
11
|
-
// css-variables.css is imported in app/app.css — do NOT import it here
|
|
12
|
-
import "./CometChatNoSSR.css";
|
|
13
|
-
|
|
14
|
-
const COMETCHAT_CONSTANTS = {
|
|
15
|
-
APP_ID: import.meta.env.{{ENV_PREFIX}}COMETCHAT_APP_ID as string,
|
|
16
|
-
REGION: import.meta.env.{{ENV_PREFIX}}COMETCHAT_REGION as string,
|
|
17
|
-
AUTH_KEY: import.meta.env.{{ENV_PREFIX}}COMETCHAT_AUTH_KEY as string,
|
|
18
|
-
};
|
|
19
|
-
const UID = "{{LOGIN_UID}}";
|
|
20
|
-
|
|
21
|
-
const CometChatNoSSR: React.FC = () => {
|
|
22
|
-
const [user, setUser] = useState<CometChat.User | undefined>();
|
|
23
|
-
const [error, setError] = useState<string | null>(null);
|
|
24
|
-
const [selectedUser, setSelectedUser] = useState<CometChat.User | undefined>();
|
|
25
|
-
const [selectedGroup, setSelectedGroup] = useState<CometChat.Group | undefined>();
|
|
26
|
-
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
if (typeof window === "undefined") return;
|
|
29
|
-
|
|
30
|
-
const settings = new UIKitSettingsBuilder()
|
|
31
|
-
.setAppId(COMETCHAT_CONSTANTS.APP_ID)
|
|
32
|
-
.setRegion(COMETCHAT_CONSTANTS.REGION)
|
|
33
|
-
.setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY)
|
|
34
|
-
.subscribePresenceForAllUsers()
|
|
35
|
-
.build();
|
|
36
|
-
|
|
37
|
-
CometChatUIKit.init(settings)?.then(() => {
|
|
38
|
-
CometChatUIKit.getLoggedinUser().then((u) => {
|
|
39
|
-
if (!u) {
|
|
40
|
-
CometChatUIKit.login(UID)
|
|
41
|
-
.then(setUser)
|
|
42
|
-
.catch((e: unknown) => setError(String(e)));
|
|
43
|
-
} else {
|
|
44
|
-
setUser(u);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
}).catch((e: unknown) => setError(String(e)));
|
|
48
|
-
}, []);
|
|
49
|
-
|
|
50
|
-
if (error) return <div style={{ color: "red", padding: 16, fontFamily: "monospace" }}>{error}</div>;
|
|
51
|
-
if (!user) return null;
|
|
52
|
-
|
|
53
|
-
return (
|
|
54
|
-
<div className="conversations-with-messages">
|
|
55
|
-
<div className="conversations-wrapper">
|
|
56
|
-
<CometChatSelector
|
|
57
|
-
onSelectorItemClicked={(activeItem) => {
|
|
58
|
-
const item =
|
|
59
|
-
activeItem instanceof CometChat.Conversation
|
|
60
|
-
? activeItem.getConversationWith()
|
|
61
|
-
: activeItem;
|
|
62
|
-
if (item instanceof CometChat.User) {
|
|
63
|
-
setSelectedUser(item);
|
|
64
|
-
setSelectedGroup(undefined);
|
|
65
|
-
} else if (item instanceof CometChat.Group) {
|
|
66
|
-
setSelectedUser(undefined);
|
|
67
|
-
setSelectedGroup(item);
|
|
68
|
-
}
|
|
69
|
-
}}
|
|
70
|
-
/>
|
|
71
|
-
</div>
|
|
72
|
-
{selectedUser || selectedGroup ? (
|
|
73
|
-
<div className="messages-wrapper">
|
|
74
|
-
{selectedUser && <CometChatMessageHeader user={selectedUser} />}
|
|
75
|
-
{selectedGroup && <CometChatMessageHeader group={selectedGroup} />}
|
|
76
|
-
{selectedUser && <CometChatMessageList user={selectedUser} />}
|
|
77
|
-
{selectedGroup && <CometChatMessageList group={selectedGroup} />}
|
|
78
|
-
{selectedUser && <CometChatMessageComposer user={selectedUser} />}
|
|
79
|
-
{selectedGroup && <CometChatMessageComposer group={selectedGroup} />}
|
|
80
|
-
</div>
|
|
81
|
-
) : (
|
|
82
|
-
<div className="empty-conversation">Select a conversation to start chatting</div>
|
|
83
|
-
)}
|
|
84
|
-
</div>
|
|
85
|
-
);
|
|
86
|
-
};
|
|
87
|
-
export default CometChatNoSSR;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
2
|
-
import type { CometChat } from "@cometchat/chat-sdk-javascript";
|
|
3
|
-
import {
|
|
4
|
-
CometChatConversations,
|
|
5
|
-
CometChatUIKitLoginListener,
|
|
6
|
-
} from "@cometchat/chat-uikit-react";
|
|
7
|
-
|
|
8
|
-
interface SelectorProps {
|
|
9
|
-
onSelectorItemClicked?: (
|
|
10
|
-
input: CometChat.Conversation | CometChat.User | CometChat.Group,
|
|
11
|
-
type: string
|
|
12
|
-
) => void;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const CometChatSelector = ({
|
|
16
|
-
onSelectorItemClicked = () => {},
|
|
17
|
-
}: SelectorProps) => {
|
|
18
|
-
const [loggedInUser, setLoggedInUser] = useState<CometChat.User | null>(null);
|
|
19
|
-
const [activeConversation, setActiveConversation] = useState<
|
|
20
|
-
CometChat.Conversation | undefined
|
|
21
|
-
>();
|
|
22
|
-
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
setLoggedInUser(CometChatUIKitLoginListener.getLoggedInUser());
|
|
25
|
-
}, []);
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<>
|
|
29
|
-
{loggedInUser && (
|
|
30
|
-
<CometChatConversations
|
|
31
|
-
activeConversation={activeConversation}
|
|
32
|
-
onItemClick={(e) => {
|
|
33
|
-
setActiveConversation(e);
|
|
34
|
-
onSelectorItemClicked(e, "updateSelectedItem");
|
|
35
|
-
}}
|
|
36
|
-
/>
|
|
37
|
-
)}
|
|
38
|
-
</>
|
|
39
|
-
);
|
|
40
|
-
};
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/* CometChat layout — IMPORTANT: read this before customizing.
|
|
2
|
-
*
|
|
3
|
-
* The CometChat React UI Kit v6 wraps every component in a `<div class="cometchat">`
|
|
4
|
-
* which does NOT set `height: 100%`. CSS flex with `flex: 1` alone WILL NOT propagate
|
|
5
|
-
* height through this wrapper, so the message list (which uses `overflow: hidden auto`
|
|
6
|
-
* + `height: 100%` internally) collapses to content size — disabling scroll and
|
|
7
|
-
* showing messages from the top instead of bottom-anchored.
|
|
8
|
-
*
|
|
9
|
-
* The required workaround is to give EVERY ancestor of `.cometchat-message-list` an
|
|
10
|
-
* explicit fixed height. That's why this stylesheet sets:
|
|
11
|
-
* - #root → 100vh / 100vw (anchor the whole layout in the viewport)
|
|
12
|
-
* - .conversations-with-messages → height: 100% from #root
|
|
13
|
-
* - .conversations-wrapper → height: 100vh (fixed left panel)
|
|
14
|
-
* - .messages-wrapper → flex: 1 (right panel fills remaining space,
|
|
15
|
-
* shrinks when side panels like details/search/
|
|
16
|
-
* threads open alongside it)
|
|
17
|
-
*
|
|
18
|
-
* The layout is side-panel-ready: adding a details panel, search panel, or
|
|
19
|
-
* thread panel alongside the messages wrapper will work without any CSS changes.
|
|
20
|
-
* The messages-wrapper uses flex: 1 + min-width: 0 so it shrinks automatically
|
|
21
|
-
* when a sibling side panel is added to the flex container.
|
|
22
|
-
*
|
|
23
|
-
* If you customize this layout, every container in the chain from <html> down to
|
|
24
|
-
* the message list MUST have a resolved height. If you switch to inline styles or
|
|
25
|
-
* a different parent component, give the chat container a fixed pixel/viewport
|
|
26
|
-
* height OR measure it with a ResizeObserver and set it imperatively.
|
|
27
|
-
*
|
|
28
|
-
* If you see "blank panel where messages should be" or "messages stuck at top
|
|
29
|
-
* instead of scrolling to bottom", this is the bug. See:
|
|
30
|
-
* https://www.cometchat.com/docs/ui-kit/react/components-overview
|
|
31
|
-
*/
|
|
32
|
-
#root { width: 100vw; height: 100vh; }
|
|
33
|
-
.conversations-with-messages { display: flex; height: 100%; width: 100%; }
|
|
34
|
-
.conversations-wrapper { height: 100vh; width: 480px; overflow: hidden; display: flex; flex-direction: column; flex-shrink: 0; }
|
|
35
|
-
.conversations-wrapper > .cometchat { overflow: hidden; }
|
|
36
|
-
.messages-wrapper { flex: 1; min-width: 0; height: 100%; display: flex; flex-direction: column; }
|
|
37
|
-
.empty-conversation { height: 100vh; width: 100%; display: flex; justify-content: center; align-items: center; background: var(--cometchat-background-color-03, #F5F5F5); color: var(--cometchat-text-color-secondary, #727272); font: var(--cometchat-font-body-regular, 400 14px Roboto); }
|
|
38
|
-
.cometchat .cometchat-message-composer { border-radius: 0; }
|
|
39
|
-
/* Side panel — used by details, search, threaded messages. Ready to use in Phase B. */
|
|
40
|
-
.side-component-wrapper { display: flex; width: 30%; max-width: 420px; flex-direction: column; flex-shrink: 0; background: var(--cometchat-background-color-01, #FFF); border-left: 1px solid var(--cometchat-border-color-light, #F5F5F5); height: 100%; overflow: hidden; }
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
CometChatMessageComposer,
|
|
4
|
-
CometChatMessageHeader,
|
|
5
|
-
CometChatMessageList,
|
|
6
|
-
} from "@cometchat/chat-uikit-react";
|
|
7
|
-
import { CometChat } from "@cometchat/chat-sdk-javascript";
|
|
8
|
-
import { CometChatSelector } from "./cometchat/CometChatSelector";
|
|
9
|
-
import "./App.css";
|
|
10
|
-
|
|
11
|
-
function App() {
|
|
12
|
-
const [selectedUser, setSelectedUser] = useState<
|
|
13
|
-
CometChat.User | undefined
|
|
14
|
-
>();
|
|
15
|
-
const [selectedGroup, setSelectedGroup] = useState<
|
|
16
|
-
CometChat.Group | undefined
|
|
17
|
-
>();
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<div className="conversations-with-messages">
|
|
21
|
-
<div className="conversations-wrapper">
|
|
22
|
-
<CometChatSelector
|
|
23
|
-
onSelectorItemClicked={(activeItem) => {
|
|
24
|
-
const item =
|
|
25
|
-
activeItem instanceof CometChat.Conversation
|
|
26
|
-
? activeItem.getConversationWith()
|
|
27
|
-
: activeItem;
|
|
28
|
-
if (item instanceof CometChat.User) {
|
|
29
|
-
setSelectedUser(item);
|
|
30
|
-
setSelectedGroup(undefined);
|
|
31
|
-
} else if (item instanceof CometChat.Group) {
|
|
32
|
-
setSelectedUser(undefined);
|
|
33
|
-
setSelectedGroup(item);
|
|
34
|
-
}
|
|
35
|
-
}}
|
|
36
|
-
/>
|
|
37
|
-
</div>
|
|
38
|
-
{selectedUser || selectedGroup ? (
|
|
39
|
-
<div className="messages-wrapper">
|
|
40
|
-
{selectedUser && <CometChatMessageHeader user={selectedUser} />}
|
|
41
|
-
{selectedGroup && <CometChatMessageHeader group={selectedGroup} />}
|
|
42
|
-
{selectedUser && <CometChatMessageList user={selectedUser} />}
|
|
43
|
-
{selectedGroup && <CometChatMessageList group={selectedGroup} />}
|
|
44
|
-
{selectedUser && <CometChatMessageComposer user={selectedUser} />}
|
|
45
|
-
{selectedGroup && <CometChatMessageComposer group={selectedGroup} />}
|
|
46
|
-
</div>
|
|
47
|
-
) : (
|
|
48
|
-
<div className="empty-conversation">
|
|
49
|
-
Select a conversation to start chatting
|
|
50
|
-
</div>
|
|
51
|
-
)}
|
|
52
|
-
</div>
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
export default App;
|
package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs/CometChatSelector.tsx.tpl
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
2
|
-
import type { CometChat } from "@cometchat/chat-sdk-javascript";
|
|
3
|
-
import {
|
|
4
|
-
CometChatConversations,
|
|
5
|
-
CometChatUIKitLoginListener,
|
|
6
|
-
} from "@cometchat/chat-uikit-react";
|
|
7
|
-
|
|
8
|
-
interface SelectorProps {
|
|
9
|
-
onSelectorItemClicked?: (
|
|
10
|
-
input: CometChat.Conversation | CometChat.User | CometChat.Group,
|
|
11
|
-
type: string
|
|
12
|
-
) => void;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const CometChatSelector = ({
|
|
16
|
-
onSelectorItemClicked = () => {},
|
|
17
|
-
}: SelectorProps) => {
|
|
18
|
-
const [loggedInUser, setLoggedInUser] = useState<CometChat.User | null>(null);
|
|
19
|
-
const [activeConversation, setActiveConversation] = useState<
|
|
20
|
-
CometChat.Conversation | undefined
|
|
21
|
-
>();
|
|
22
|
-
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
setLoggedInUser(CometChatUIKitLoginListener.getLoggedInUser());
|
|
25
|
-
}, []);
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<>
|
|
29
|
-
{loggedInUser && (
|
|
30
|
-
<CometChatConversations
|
|
31
|
-
activeConversation={activeConversation}
|
|
32
|
-
onItemClick={(e) => {
|
|
33
|
-
setActiveConversation(e);
|
|
34
|
-
onSelectorItemClicked(e, "updateSelectedItem");
|
|
35
|
-
}}
|
|
36
|
-
/>
|
|
37
|
-
)}
|
|
38
|
-
</>
|
|
39
|
-
);
|
|
40
|
-
};
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { StrictMode } from 'react'
|
|
2
|
-
import { createRoot } from 'react-dom/client'
|
|
3
|
-
import { CometChatUIKit, UIKitSettingsBuilder } from '@cometchat/chat-uikit-react'
|
|
4
|
-
import './index.css'
|
|
5
|
-
import App from './App.tsx'
|
|
6
|
-
|
|
7
|
-
const COMETCHAT_CONSTANTS = {
|
|
8
|
-
APP_ID: import.meta.env.{{ENV_PREFIX}}COMETCHAT_APP_ID as string,
|
|
9
|
-
REGION: import.meta.env.{{ENV_PREFIX}}COMETCHAT_REGION as string,
|
|
10
|
-
AUTH_KEY: import.meta.env.{{ENV_PREFIX}}COMETCHAT_AUTH_KEY as string,
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const settings = new UIKitSettingsBuilder()
|
|
14
|
-
.setAppId(COMETCHAT_CONSTANTS.APP_ID)
|
|
15
|
-
.setRegion(COMETCHAT_CONSTANTS.REGION)
|
|
16
|
-
.setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY)
|
|
17
|
-
.subscribePresenceForAllUsers()
|
|
18
|
-
.build()
|
|
19
|
-
|
|
20
|
-
CometChatUIKit.init(settings)
|
|
21
|
-
?.then(() => {
|
|
22
|
-
CometChatUIKit.getLoggedinUser().then((user) => {
|
|
23
|
-
if (!user) {
|
|
24
|
-
CometChatUIKit.login('{{LOGIN_UID}}')
|
|
25
|
-
.then(() => mount())
|
|
26
|
-
.catch((e: unknown) => mountError(String(e)))
|
|
27
|
-
} else {
|
|
28
|
-
mount()
|
|
29
|
-
}
|
|
30
|
-
})
|
|
31
|
-
})
|
|
32
|
-
.catch((e: unknown) => mountError(String(e)))
|
|
33
|
-
|
|
34
|
-
function mount() {
|
|
35
|
-
createRoot(document.getElementById('root')!).render(
|
|
36
|
-
<StrictMode>
|
|
37
|
-
<App />
|
|
38
|
-
</StrictMode>,
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function mountError(message: string) {
|
|
43
|
-
createRoot(document.getElementById('root')!).render(
|
|
44
|
-
<div style={{ color: 'red', padding: 16, fontFamily: 'monospace' }}>{message}</div>,
|
|
45
|
-
)
|
|
46
|
-
}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { lazy, Suspense, useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
CometChatUIKit,
|
|
4
|
-
UIKitSettingsBuilder,
|
|
5
|
-
} from "@cometchat/chat-uikit-react";
|
|
6
|
-
|
|
7
|
-
const CometChatMessenger = lazy(
|
|
8
|
-
() => import("../cometchat/CometChatMessenger")
|
|
9
|
-
);
|
|
10
|
-
|
|
11
|
-
const COMETCHAT_CONSTANTS = {
|
|
12
|
-
APP_ID: import.meta.env.{{ENV_PREFIX}}COMETCHAT_APP_ID as string,
|
|
13
|
-
REGION: import.meta.env.{{ENV_PREFIX}}COMETCHAT_REGION as string,
|
|
14
|
-
AUTH_KEY: import.meta.env.{{ENV_PREFIX}}COMETCHAT_AUTH_KEY as string,
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const settings = new UIKitSettingsBuilder()
|
|
18
|
-
.setAppId(COMETCHAT_CONSTANTS.APP_ID)
|
|
19
|
-
.setRegion(COMETCHAT_CONSTANTS.REGION)
|
|
20
|
-
.setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY)
|
|
21
|
-
.subscribePresenceForAllUsers()
|
|
22
|
-
.build();
|
|
23
|
-
|
|
24
|
-
// Module-level promise so init + login only runs once, even if the page
|
|
25
|
-
// remounts (route changes, StrictMode double-render). Subsequent mounts
|
|
26
|
-
// await the same resolved promise.
|
|
27
|
-
let initPromise: Promise<void> | null = null;
|
|
28
|
-
function ensureInitialized(): Promise<void> {
|
|
29
|
-
if (initPromise) return initPromise;
|
|
30
|
-
initPromise = CometChatUIKit.init(settings)
|
|
31
|
-
.then(() => CometChatUIKit.getLoggedinUser())
|
|
32
|
-
.then((user) => {
|
|
33
|
-
if (user) return undefined;
|
|
34
|
-
return CometChatUIKit.login("{{LOGIN_UID}}").then(() => undefined);
|
|
35
|
-
})
|
|
36
|
-
.then(() => undefined);
|
|
37
|
-
return initPromise;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export default function ChatPage() {
|
|
41
|
-
const [ready, setReady] = useState(false);
|
|
42
|
-
const [error, setError] = useState<string | null>(null);
|
|
43
|
-
|
|
44
|
-
useEffect(() => {
|
|
45
|
-
let cancelled = false;
|
|
46
|
-
ensureInitialized()
|
|
47
|
-
.then(() => {
|
|
48
|
-
if (!cancelled) setReady(true);
|
|
49
|
-
})
|
|
50
|
-
.catch((e: unknown) => {
|
|
51
|
-
if (!cancelled) setError(String(e));
|
|
52
|
-
});
|
|
53
|
-
return () => {
|
|
54
|
-
cancelled = true;
|
|
55
|
-
};
|
|
56
|
-
}, []);
|
|
57
|
-
|
|
58
|
-
if (error) {
|
|
59
|
-
return (
|
|
60
|
-
<div
|
|
61
|
-
className="cometchat-page"
|
|
62
|
-
style={{
|
|
63
|
-
color: "red",
|
|
64
|
-
padding: 16,
|
|
65
|
-
fontFamily: "monospace",
|
|
66
|
-
}}
|
|
67
|
-
>
|
|
68
|
-
CometChat failed to load: {error}
|
|
69
|
-
</div>
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
if (!ready) {
|
|
73
|
-
return (
|
|
74
|
-
<div className="cometchat-page" style={{ padding: 16 }}>
|
|
75
|
-
Loading chat…
|
|
76
|
-
</div>
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return (
|
|
81
|
-
<div className="cometchat-page">
|
|
82
|
-
<Suspense fallback={<div style={{ padding: 16 }}>Loading chat…</div>}>
|
|
83
|
-
<CometChatMessenger />
|
|
84
|
-
</Suspense>
|
|
85
|
-
</div>
|
|
86
|
-
);
|
|
87
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/* CometChat layout — IMPORTANT: read this before customizing.
|
|
2
|
-
*
|
|
3
|
-
* The CometChat React UI Kit v6 wraps every component in a `<div class="cometchat">`
|
|
4
|
-
* which does NOT set `height: 100%`. CSS flex with `flex: 1` alone WILL NOT propagate
|
|
5
|
-
* height through this wrapper, so the message list (which uses `overflow: hidden auto`
|
|
6
|
-
* + `height: 100%` internally) collapses to content size — disabling scroll and
|
|
7
|
-
* showing messages from the top instead of bottom-anchored.
|
|
8
|
-
*
|
|
9
|
-
* This stylesheet scopes the layout to `.cometchat-page` (the root div in
|
|
10
|
-
* ChatPage.tsx) so it doesn't leak into the rest of your app's pages.
|
|
11
|
-
*/
|
|
12
|
-
.cometchat-page { width: 100vw; height: 100vh; }
|
|
13
|
-
.conversations-with-messages { display: flex; height: 100%; width: 100%; }
|
|
14
|
-
.conversations-wrapper { height: 100vh; width: 480px; overflow: hidden; display: flex; flex-direction: column; flex-shrink: 0; }
|
|
15
|
-
.conversations-wrapper > .cometchat { overflow: hidden; }
|
|
16
|
-
.messages-wrapper { flex: 1; min-width: 0; height: 100%; display: flex; flex-direction: column; }
|
|
17
|
-
.empty-conversation { height: 100vh; width: 100%; display: flex; justify-content: center; align-items: center; background: var(--cometchat-background-color-03, #F5F5F5); color: var(--cometchat-text-color-secondary, #727272); font: var(--cometchat-font-body-regular, 400 14px Roboto); }
|
|
18
|
-
.cometchat .cometchat-message-composer { border-radius: 0; }
|
|
19
|
-
/* Side panel — used by details, search, threaded messages. Ready to use in Phase B. */
|
|
20
|
-
.side-component-wrapper { display: flex; width: 30%; max-width: 420px; flex-direction: column; flex-shrink: 0; background: var(--cometchat-background-color-01, #FFF); border-left: 1px solid var(--cometchat-border-color-light, #F5F5F5); height: 100%; overflow: hidden; }
|