UNPKG

@vchatcloud/react-ui-kit

Version:

VChatCloud UI Kit for react integration

526 lines (419 loc) 16.6 kB
# VChatCloud React UI Kit [![NPM Version](https://img.shields.io/npm/v/%40vchatcloud%2Freact-ui-kit)](https://www.npmjs.com/package/@vchatcloud/react-ui-kit) VChatCloud React UI Kit은 UI 컴포넌트를 제공하여 VChatCloud 채팅 서비스를 React에 통합하기 쉽게 만들어줍니다. ## 목차 - [VChatCloud React UI Kit](#vchatcloud-react-ui-kit) - [목차](#목차) - [설치](#설치) - [사용법](#사용법) - [코드 예시](#코드-예시) - [컴포넌트 설명](#컴포넌트-설명) - [VChatCloudApp](#vchatcloudapp) - [주의사항](#주의사항) - [커스터마이징](#커스터마이징) - [컴포넌트 변경](#컴포넌트-변경) - [색상 변경](#색상-변경) - [추가 정보](#추가-정보) ## 설치 해당 라이브러리는 react 18버전을 지원합니다. ```bash npm install react@~18 react-dom@~18 @vchatcloud/react-ui-kit # or # yarn add react@~18 react-dom@~18 @vchatcloud/react-ui-kit # or # pnpm add react@~18 react-dom@~18 @vchatcloud/react-ui-kit ``` ## 사용법 우선 사용하려는 프로젝트의 `index.html`에 해당 내용을 작성합니다. ```html <head> <!-- ... --> <!-- 아래 내용을 추가합니다. --> <script src="https://www.vchatcloud.com/lib/e7lib-latest.min.js"></script> <script src="https://www.vchatcloud.com/lib/vchatcloud-last.min.js"></script> </head> ``` 그 후 프로젝트에서 UI Kit을 사용하려면, 필요한 컴포넌트를 import하여 사용합니다. `VChatCloudApp` 컴포넌트를 사용하여 VChatCloud를 설정하고 실행할 수 있습니다. ### 코드 예시 ```tsx import { VChatCloudApp, ChannelUserGrade } from "@vchatcloud/react-ui-kit"; import { FC, useEffect, useRef } from "react"; const App: FC = () => { const [roomId, clientKey, nickName, grade, userInfo] = [ "YOUR_ROOM_ID", // clientKey는 원하는 값을 사용하면 되지만, 사용자끼리 중복되지 않도록 주의해주세요. // 같은 clientKey로 로그인 시 기존에 로그인 된 사용자는 접속이 종료됩니다. // 또는 `setRandomClientKey`함수를 불러와 사용할 수 있습니다. "YOUR_CLIENT_KEY", "YOUR_NICKNAME", "user", { profile: 1 }, ]; const privateContainer = useRef<HTMLDivElement>(null); // private container 사용 시 useEffect(() => { if (!privateContainer.current) return; privateContainer.current.style.display = "none"; const observer = new MutationObserver(() => { if (!privateContainer.current) return; privateContainer.current.style.display = privateContainer.current.children.length === 0 ? "none" : "block"; }); observer.observe(privateContainer.current, { childList: true }); return () => observer.disconnect(); }, []); return ( <> <div className="app" style={{ width: "100%", height: "100vh" }}> <VChatCloudApp clientKey={clientKey} email="YOUR_EMAIL" // VChatCloud CMS계정 ID grade={grade} nickName={nickName} privateContainer=".private-container" // querySelector 파라미터 또는 HTMLElement roomId={roomId} sessionType="parameter" userInfo={userInfo} // logoUrl="LOGO_IMG_URL" // company="YOUR_COMPANY_NAME" /> </div> {/* 비밀채팅용 wrapper */} <div className="app private-container" ref={privateContainer} style={{ width: "100%", height: "100vh" }} /> </> ); }; export default App; ``` ## 컴포넌트 설명 ### VChatCloudApp `VChatCloudApp` 컴포넌트는 VChatCloud 서비스를 설정하고 실행하는 메인 컴포넌트입니다. 주요 props는 다음과 같습니다: - `clientKey` : 사용자 고유의 클라이언트 키. - `email` : VChatCloud CMS 계정 ID. - `grade` : 사용자 등급 (`user`, `userManager` 등). - `nickName` : 사용자 닉네임. - `roomId` : 채팅방 ID. - `privateContainer` : 비밀 채팅을 위한 HTML 컨테이너 (`querySelector 파라미터` 또는 `HTMLElement`). - `sessionType` : 세션 타입 - `login` : 로그인 화면을 사용해 접속자가 원하는 닉네임과 프로필을 설정할 수 있습니다. - `parameter` : 파라미터로 사용자의 정보를 불러와 사용합니다. 개발자가 지정한 정보를 사용하게 됩니다. - `private` : 파라미터와 동일하게 사용자의 정보를 불러와 사용하지만, 비밀채팅을 이용할 때 설정합니다. - `userInfo` : 추가 사용자 정보 (객체 형태). `userInfo.profile`에 숫자를 지정하면 기본 제공하는 프로필 이미지를 사용할 수 있습니다. _(1 ~ 48까지 제공)_ - `logoUrl` : 로그인 화면에서 표시할 로고 이미지를 변경할 수 있습니다. - `company` : 로그인 화면에서 표시할 푸터의 회사 정보를 변경할 수 있습니다. ## 주의사항 - **`StrictMode` 비활성화 필요** : 개발서버로 실행 시 `StrictMode`를 비활성화 하여야 오류가 발생하지 않습니다. - **중복된 `clientKey` 주의** : 같은 clientKey로 로그인 시 기존에 로그인 된 사용자가 접속이 종료됩니다. `setRandomClientKey` 함수를 사용하여 랜덤 clientKey를 생성할 수 있습니다. ## 커스터마이징 ### 컴포넌트 변경 `VChatCloudApp`을 사용하는 대신 `VChatCloudProvider`를 사용하실 수 있습니다. `VChatCloudProvider`내부에 원하는 컴포넌트를 사용하실 수 있으며, `useVChatCloud`훅을 불러와 필요한 데이터에 접근할 수 있습니다. 단 `useVChatCloud`훅을 사용할 경우 반드시 `VChatCloudProvider` 컴포넌트 내부에서 사용하여야 합니다. ```tsx import { VChatCloudApp, useVChatCloud } from "@vchatcloud/react-ui-kit"; import { useCallback } from "react"; const SendButton = () => { const { channel } = useVChatCloud(); const send = useCallback(() => { channel?.sendMessage({ message: "Hello VChatCloud!" }); }, [channel]); return <button onClick={send}>전송</button>; }; const App = () => { return ( <VChatCloudProvider clientKey={clientKey} company={company} email={email} grade={grade} logoUrl={logoUrl} nickName={nickName} privateContainer={privateContainer} roomId={roomId} sessionType={sessionType} url={url} userInfo={userInfo} onDisconnect={onDisconnect} > {/* 원하는 컴포넌트로 재정의하세요. */} <SendButton /> </VChatCloudProvider> ); }; export default App; ``` ### 색상 변경 css 변수를 사용하여 원하는 부분을 덮어 써 색상을 재 지정할 수 있습니다. 목록은 아래에 있습니다. <details> ```css /* 일반, 라이트 모드 */ :root, :root .light { --button-primary: #0a0a6b; --button-secondary: #fff; --image-invert: none; --scrollbar-bg: #cfcfcf; --login-bg: #c9c9f2; --login-desc: #0033ab; --login-footer: #0a0a6b4c; --profile-shadow: 1px 1.7px 7px 0 rgba(201, 201, 201, 0.3); --profile-border: #f2f2f2; --profile-bg: #fff; --profile-button-bg: #aaa; --profile-img-border: #eaeaea; --profile-input-border: #dddddd; --profile-input-color: #000; --profile-input-focus-border: #0033ab; --notify-toast-box-shadow: 1.5px 2.6px 5px 0 rgba(168, 168, 168, 0.3); --notify-toast-bg-color: #363940; --notify-toast-text-color: #fff; --drawer-color-bg: #fff; --drawer-color-text: #333; --drawer-color-border: #ddd; --drawer-color-shadow: rgba(168, 168, 168, 0.3); --drawer-color-drawer-border: #f2f2f2; --file-drawer-border-color: #ddd; --file-drawer-header-title-color: #333; --file-drawer-tab-color: #666; --file-drawer-tab-focus-color: #000; --file-drawer-tab-focus-border-color: #000; --file-drawer-select-count-color: #666; --file-drawer-save-color: #000; --preview-item-checked-border-color: #4160b9; --file-item-preview-bg: #fff; --file-item-preview-border: #f2f2f2; --file-item-preview-text: #000; --file-item-preview-sub-text: #999; --translate-modal-shadow: rgba(168, 168, 168, 0.3); --translate-modal-popup-bg: #fff; --translate-modal-border-color: #f2f2f2; --translate-modal-title-color: #333; --translate-modal-translate-bg-color: #ddd; --translate-modal-translate-text-color: #000; --modal-dim: rgba(0, 0, 0, 0.7); --modal-shadow: rgba(168, 168, 168, 0.3); --modal-bg: #fff; --modal-border: #f2f2f2; --modal-title: #333; --modal-content: #444; --invite-popup-input-bg: #fff; --invite-popup-input-border: #ddd; --invite-popup-input-color: #666; --secret-bg-color: #ddd; --secret-text-color: #000; --checkbox-border-color: #ddd; --checkbox-bg-color: #fff; --user-item-border-color: #f2f2f2; --user-item-nickname-color: #333; --user-item-translate-color: #999; --toggle-bar-color: #ddd; --toggle-bar-on-color: #c9ddff; --toggle-dot-color: #999; --toggle-dot-on-color: #2a61be; --toggle-label-color: #666; --whisper-modal-input-text-color: #000; --whisper-modal-input-bg-color: #fff; --whisper-modal-input-border-color: #ddd; --user-popup-shadow: rgba(168, 168, 168, 0.3); --user-popup-border: #f2f2f2; --user-popup-bg: #fff; --user-popup-text: #000; --user-popup-focus-bg: #0a0a6b; --user-popup-focus-text: #fff; --user-popup-opacity: 1; --user-popup-focus-opacity: 1; --chatting-field-bg: #fff; --chatting-field-nickname: #0033ab; --chatting-field-input-text: #000; --chatting-field-input-placeholder: #888; --chatting-field-border-color: #ddd; --chatting-field-input-size-color: #999; --emoticon-field-border-color: #ddd; --emoticon-field-hover-bg-color: rgba(0, 0, 0, 0.1); --emoticon-field-list-bg-color: #f2f2f2; --emoticon-field-list-opacity: 1; --emoticon-field-focus-border-color: #ddd; --emoticon-field-focus-box-shadow: 1px 1.7px 1px 0 rgba(207, 207, 207, 0.3); --emoticon-field-focus-bg-color: #fff; --scroll-down-bg: #fff; --scroll-down-text: #333; --scroll-down-border: #ddd; --scroll-down-shadow: rgba(105, 105, 105, 0.25); --chatting-header-bg: #f2f2f2; --chatting-header-border: #f2f2f2; --chatting-header-text: #000; --chatting-header-user-count: #999; --chatting-body-bg: #fff; --notice-item-bg: #333; --notice-item-content: #fff; --notice-item-shadow: rgba(157, 173, 184, 0.3); --chat-base-border: #f2f2f2; --chat-base-nickname: #666; --chat-base-time: #999; --text-chat-item-message: #333; --whisper-item-from: #e1dffc; --whisper-item-nickname-from: #0a0a6b; --whisper-item-to: #f2f2f2; --whisper-item-nickname-to: #0a0a6b; --whisper-item-nickname-where: #666; --whisper-item-message: #010000; --whisper-item-time: #999; --whisper-item-shadow: rgba(157, 173, 184, 0.3); --join-item-message: #0033ab; --exit-item-message: #ff5a5a; --alert-item-message: #ff7800; --open-graph-item-border: #ddd; --open-graph-item-shadow: rgba(157, 173, 184, 0.3); --open-graph-item-background: #fff; --open-graph-item-title: #333; --open-graph-item-desc: #666; --radio-group-border: #ddd; --radio-group-checked: #000; --radio-group-radio-bg: #fff; --radio-group-text: #000; } /* 다크 모드 */ :root .dark { --button-primary: #fff; --button-secondary: #000; --image-invert: invert(100%); --scrollbar-bg: #444; --login-bg: #292929; --login-desc: #ddd; --login-footer: #aaa; --profile-shadow: 1.5px 2.6px 5px 0 rgba(0, 0, 0, 0.3); --profile-border: #444; --profile-bg: #313131; --profile-button-bg: #aaa; --profile-img-border: #444; --profile-input-border: #444; --profile-input-color: #fff; --profile-input-focus-border: #fff; --notify-toast-box-shadow: 1.5px 2.6px 5px 0 rgba(0, 0, 0, 0.3); --notify-toast-bg-color: #333; --notify-toast-text-color: #fff; --drawer-color-bg: #333; --drawer-color-text: #fff; --drawer-color-border: #444; --drawer-color-shadow: rgba(0, 0, 0, 0.3); --drawer-color-drawer-border: #444; --file-drawer-border-color: #444; --file-drawer-header-title-color: #fff; --file-drawer-tab-color: #ddd; --file-drawer-tab-focus-color: #fff; --file-drawer-tab-focus-border-color: #fff; --file-drawer-select-count-color: #fff; --file-drawer-save-color: #fff; --preview-item-checked-border-color: #0ed893; --file-item-preview-bg: #fff; --file-item-preview-border: #f2f2f2; --file-item-preview-text: #000; --file-item-preview-sub-text: #999; --translate-modal-shadow: rgba(0, 0, 0, 0.3); --translate-modal-popup-bg: #313131; --translate-modal-border-color: #444; --translate-modal-title-color: #fff; --translate-modal-translate-bg-color: #222; --translate-modal-translate-text-color: #fff; --modal-dim: rgba(0, 0, 0, 0.7); --modal-shadow: rgba(0, 0, 0, 0.3); --modal-bg: #313131; --modal-border: #444; --modal-title: #fff; --modal-content: #fff; --modal-button-primary: #fff; --invite-popup-input-bg: #000; --invite-popup-input-border: #444; --invite-popup-input-color: #aaa; --secret-bg-color: #222; --secret-text-color: #fff; --checkbox-border-color: #ddd; --checkbox-bg-color: #fff; --user-item-border-color: #444; --user-item-nickname-color: #fff; --user-item-translate-color: #aaa; --toggle-bar-color: #666; --toggle-bar-on-color: #fff; --toggle-dot-color: #999; --toggle-dot-on-color: #0ed893; --toggle-label-color: #ddd; --whisper-modal-input-text-color: #fff; --whisper-modal-input-bg-color: #191919; --whisper-modal-input-border-color: #444; --user-popup-shadow: rgba(0, 0, 0, 0.3); --user-popup-border: #444; --user-popup-bg: #313131; --user-popup-text: #fff; --user-popup-focus-bg: #313131; --user-popup-focus-text: #fff; --user-popup-opacity: 0.7; --user-popup-focus-opacity: 1; --chatting-field-bg: #292929; --chatting-field-nickname: #aaa; --chatting-field-input-text: #fff; --chatting-field-input-placeholder: #aaa; --chatting-field-border-color: #444; --chatting-field-input-size-color: #ddd; --emoticon-field-border-color: #444; --emoticon-field-hover-bg-color: rgba(255, 255, 255, 0.1); --emoticon-field-list-bg-color: #353535; --emoticon-field-list-opacity: 0.5; --emoticon-field-focus-border-color: #353535; --emoticon-field-focus-box-shadow: 1px 1.7px 1px 0 rgba(0, 0, 0, 0.3); --emoticon-field-focus-bg-color: #292929; --scroll-down-bg: #353535; --scroll-down-text: #aaa; --scroll-down-border: #353535; --scroll-down-shadow: rgba(0, 0, 0, 0.25); --chatting-header-bg: #191919; --chatting-header-border: #444; --chatting-header-text: #fff; --chatting-header-user-count: #ddd; --chatting-body-bg: #292929; --notice-item-bg: #111; --notice-item-content: #fff; --notice-item-shadow: rgba(0, 0, 0, 0.3); --chat-base-border: #444; --chat-base-nickname: #aaa; --chat-base-time: #aaa; --text-chat-item-message: #fff; --whisper-item-from: #384150; --whisper-item-nickname-from: #dfb84e; --whisper-item-to: #353535; --whisper-item-nickname-to: #00ffc0; --whisper-item-nickname-where: #aaa; --whisper-item-message: #fff; --whisper-item-time: #aaa; --whisper-item-shadow: rgba(0, 0, 0, 0.3); --join-item-message: #00ffc0; --exit-item-message: #ff3a54; --alert-item-message: #fff000; --open-graph-item-border: #444; --open-graph-item-shadow: rgba(0, 0, 0, 0.3); --open-graph-item-background: #fff; --open-graph-item-title: #333; --open-graph-item-desc: #666; --radio-group-border: #ddd; --radio-group-checked: #000; --radio-group-radio-bg: #fff; --radio-group-text: #fff; } ``` </details> 아래와 같이 원하는 변수를 재 지정하여 덮어쓸 수 있습니다. ```css :root, :root .light { --button-primary: skyblue; } /* 다크모드 색상 */ :root .dark { --button-primary: beige; } ``` ## 추가 정보 더 많은 정보와 자세한 사용법은 [공식 문서 링크](https://www.vchatcloud.com/doc/react)를 참조하세요.