@coxwave/tap-kit
v2.2.1
Published
EduTAP SDK with React support
Readme
@coxwave/tap-kit
EduTAP AI 튜터를 웹사이트에 통합하기 위한 공식 SDK
특징
- React 우선 지원 -
useTapKithook으로 간편한 통합 - 타입 안전 - 완전한 TypeScript 지원
- 경량 - 스마트한 CDN 로딩
- 쉬운 마이그레이션 - tap-sdk와 100% API 호환
설치
npm install @coxwave/tap-kitReact에서 사용하기 (권장)
<TapKit /> 컴포넌트와 useTapKit hook을 함께 사용합니다:
'use client'; // Next.js App Router 사용 시
import { TapKit, useTapKit } from '@coxwave/tap-kit/react';
function App() {
const tapkit = useTapKit({
apiKey: 'your-api-key',
userId: 'user-123',
courseId: 'course-456',
clipId: 'clip-789',
mode: 'floating',
onReady: () => console.log('TapKit 준비 완료!'),
onError: (error) => console.error('에러:', error),
});
return (
<div>
<button onClick={tapkit.show} disabled={!tapkit.isReady}>
AI 튜터에게 질문하기
</button>
<TapKit control={tapkit.control} style={{ height: '600px' }} />
</div>
);
}Vanilla JS에서 사용하기
npm 패키지를 import하면 <tap-kit> Web Component를 사용할 수 있습니다:
import '@coxwave/tap-kit';
// Web Component 생성
const kit = document.createElement('tap-kit');
kit.apiKey = 'your-api-key'; // Property로 설정 (보안)
kit.userId = 'user-123';
kit.courseId = 'course-456';
kit.clipId = 'clip-789';
document.body.appendChild(kit);
// 초기화 대기
await kit.ready;
kit.show();CDN에서 사용하기
npm 없이 CDN으로 직접 사용하려면 CDN 사용 가이드를 참고하세요.
API Reference
<TapKit /> Component
<tap-kit> Web Component를 React에서 선언적으로 사용할 수 있는 컴포넌트입니다.
Props:
control: TapKitControl- useTapKit hook에서 반환된 control 객체 (필수)style?: CSSProperties- 인라인 스타일 (선택)className?: string- CSS 클래스 (선택)ref?: Ref<TapKitElement>- Web Component에 대한 ref (선택)
Ref 사용 예시:
const tapkitRef = useRef<TapKitElement>(null);
<TapKit ref={tapkitRef} control={tapkit.control} />
// ref로 Web Component 직접 제어
tapkitRef.current?.show();
tapkitRef.current?.hide();
tapkitRef.current?.setCourse({ courseId: 'new', clipId: 'new-1' });useTapKit(options)
TapKit 인스턴스를 생성하고 관리하는 React Hook입니다.
Parameters:
options.apiKey: string- API 키 (필수)options.userId?: string- 사용자 IDoptions.courseId?: string- 코스 IDoptions.clipId?: string- 클립 IDoptions.clipPlayHead?: number- 재생 위치 (초)options.language?: 'ko' | 'en'- 언어 설정options.mode?: 'inline' | 'floating' | 'sidebar'- 표시 모드options.buttonId?: string- 커스텀 버튼 엘리먼트 IDoptions.debug?: boolean- 디버그 모드options.onReady?: () => void- SDK 준비 완료 이벤트options.onError?: (error: Error) => void- 에러 발생 이벤트options.onTimelineSeek?: (clipPlayHead: number, clipId: string) => void- 타임라인 탐색 이벤트options.onAlarmFadeIn?: (messageInfo: unknown) => void- 알람 표시 이벤트
Returns:
control: TapKitControl- TapKit 컴포넌트에 전달할 control 객체isReady: boolean- 로딩 완료 여부error: Error | null- 에러 객체show: () => void- 채팅 열기hide: () => void- 채팅 닫기setCourse: (course) => void- 강의 정보 변경video: { bind, unbind }- 비디오 동기화 컨트롤
사용 예제
기본 사용
'use client';
import { TapKit, useTapKit } from '@coxwave/tap-kit/react';
function App() {
const tapkit = useTapKit({
apiKey: 'your-api-key',
userId: 'user-123',
courseId: 'course-456',
clipId: 'clip-789',
});
return <TapKit control={tapkit.control} style={{ height: '600px' }} />;
}강의 변경
'use client';
import { TapKit, useTapKit } from '@coxwave/tap-kit/react';
function App() {
const tapkit = useTapKit({
apiKey: 'your-api-key',
userId: 'user-123',
courseId: 'course-456',
clipId: 'clip-789',
});
const handleClipChange = (newClipId: string) => {
tapkit.setCourse({
courseId: 'course-456',
clipId: newClipId,
});
};
return (
<div>
<button onClick={() => handleClipChange('clip-001')}>클립 1</button>
<button onClick={() => handleClipChange('clip-002')}>클립 2</button>
<TapKit control={tapkit.control} />
</div>
);
}비디오 동기화
'use client';
import { useRef, useEffect } from 'react';
import { TapKit, useTapKit } from '@coxwave/tap-kit/react';
function App() {
const videoRef = useRef<HTMLVideoElement>(null);
const tapkit = useTapKit({
apiKey: 'your-api-key',
userId: 'user-123',
courseId: 'course-456',
clipId: 'clip-789',
onTimelineSeek: (clipPlayHead, clipId) => {
if (videoRef.current) {
videoRef.current.currentTime = clipPlayHead;
}
},
});
useEffect(() => {
if (!tapkit.isReady || !videoRef.current) return;
tapkit.video.bind(
{
getCurrentTime: () => videoRef.current!.currentTime,
// clipId는 optional - cross-clip seeking 지원 시 활용
setCurrentTime: (time, clipId) => { videoRef.current!.currentTime = time; },
},
'clip-789' // Optional: 생략하면 SDK 설정에서 자동 추적
);
return () => tapkit.video.unbind();
}, [tapkit.isReady]);
return (
<div>
<video ref={videoRef} controls />
<TapKit control={tapkit.control} />
</div>
);
}문서
tap-sdk에서 마이그레이션
기존 @coxwave/tap-sdk를 사용 중이라면:
- import TapSDK from '@coxwave/tap-sdk';
+ import TapKit from '@coxwave/tap-kit';
- const sdk = new TapSDK({ apiKey: '...' });
+ const kit = new TapKit({ apiKey: '...' });API는 100% 호환됩니다!
License
MIT
