@connectycube/react-ui-kit 0.0.7 → 0.0.8

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/bin/cli.js CHANGED
@@ -4,7 +4,7 @@ import path from 'path';
4
4
  import { fileURLToPath } from 'url';
5
5
 
6
6
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
- const commandsDir = path.resolve(__dirname, '../cmd');
7
+ const commandsDir = path.resolve(__dirname, '../commands');
8
8
  const args = process.argv.slice(2);
9
9
  const cmd = args[0] ? args[0] === '--help' ? 'help' : args[0] : 'help';
10
10
 
@@ -7,41 +7,47 @@ import { execa } from "execa";
7
7
  const cwd = process.cwd();
8
8
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
9
 
10
- async function promptIsTypeScript() {
10
+ async function confirmInstallDependencies(component, deps) {
11
11
  const response = await prompts({
12
- type: "select",
13
- name: "isTypeScript",
14
- message: "What language does your project use?",
15
- choices: [
16
- { title: "👉 TypeScript (🟦 *.{ts,tsx})", value: true },
17
- { title: "👉 JavaScript (🟨 *.{js,jsx})", value: false }
18
- ],
19
- initial: 0
12
+ type: "confirm",
13
+ name: "confirm",
14
+ message: `📦 Install dependencies for "${component}"?\n🔗 ${deps.join("\n🔗 ")}\n`,
15
+ initial: true,
20
16
  });
21
17
 
22
- return response.isTypeScript;
18
+ return response.confirm;
23
19
  }
24
20
 
25
21
  export async function installDependencies(component) {
26
22
  const input = path.join(__dirname, "..", "configs", "dependencies.json");
27
23
 
28
- if (await fs.pathExists(input)) return;
24
+ if (!(await fs.pathExists(input))) return;
29
25
 
30
26
  try {
31
27
  const allDeps = await fs.readJSON(input);
32
28
  const cmpDeps = allDeps && allDeps[component];
33
29
 
34
30
  if (cmpDeps && typeof cmpDeps === "object") {
35
- const deps = Object.entries(cmpDeps).map(([pkg, ver]) => (ver ? `${pkg}@${ver}` : pkg));
31
+ const deps = Object.entries(cmpDeps).map(([pkg, ver]) =>
32
+ ver ? `${pkg}@${ver}` : pkg
33
+ );
36
34
 
37
35
  if (deps.length) {
38
- const pm = fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))
39
- ? "pnpm" : fs.existsSync(path.join(cwd, "yarn.lock"))
40
- ? "yarn" : "npm";
36
+ const confirm = await confirmInstallDependencies(component, deps);
41
37
 
42
- if (!pm || !deps || deps.length === 0) return;
38
+ if (!confirm) {
39
+ console.log("⏩ Skipped dependency installation.");
43
40
 
44
- console.log(`ℹ️ Installing dependencies for ${component}: ${deps.join(", ")}`);
41
+ return;
42
+ }
43
+
44
+ const pm = fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))
45
+ ? "pnpm"
46
+ : fs.existsSync(path.join(cwd, "yarn.lock"))
47
+ ? "yarn"
48
+ : "npm";
49
+
50
+ console.log(`ℹ️ Installing dependencies using ${pm}...`);
45
51
 
46
52
  const cmd = pm === "yarn" || pm === "pnpm" ? "add" : "install";
47
53
  const flags = pm === "npm" ? ["--save"] : [];
@@ -56,6 +62,21 @@ export async function installDependencies(component) {
56
62
  }
57
63
  }
58
64
 
65
+ async function promptIsTypeScript() {
66
+ const response = await prompts({
67
+ type: "select",
68
+ name: "isTypeScript",
69
+ message: "What language does your project use?",
70
+ choices: [
71
+ { title: "👉 TypeScript (🟦 *.{ts,tsx})", value: true },
72
+ { title: "👉 JavaScript (🟨 *.{js,jsx})", value: false }
73
+ ],
74
+ initial: 0
75
+ });
76
+
77
+ return response.isTypeScript;
78
+ }
79
+
59
80
  export async function add(component) {
60
81
  if (!component) {
61
82
  console.warn(`⚠️ Usage: npx @connectycube/react-ui-kit add [component-name]`);
@@ -70,6 +91,7 @@ export async function add(component) {
70
91
  }
71
92
 
72
93
  const filename = `${component}${isTypeScript ? ".tsx" : ".jsx"}`;
94
+ const utilsFilename = `utils${isTypeScript ? ".ts" : ".js"}`;
73
95
  const sourceDir = path.join(__dirname, "..", isTypeScript ? "src" : "gen", "components");
74
96
  const input = path.join(sourceDir, filename);
75
97
 
@@ -80,8 +102,8 @@ export async function add(component) {
80
102
 
81
103
  const dest = path.join(cwd, "src", "components", "connectycube-ui");
82
104
  const output = path.join(dest, filename);
83
- const utilsInput = path.join(sourceDir, "utils.ts");
84
- const utilsOutput = path.join(dest, "utils.ts");
105
+ const utilsInput = path.join(sourceDir, utilsFilename);
106
+ const utilsOutput = path.join(dest, utilsFilename);
85
107
 
86
108
  await fs.ensureDir(dest);
87
109
  await fs.copyFile(input, output);
@@ -90,9 +112,9 @@ export async function add(component) {
90
112
 
91
113
  if (!(await fs.pathExists(utilsOutput))) {
92
114
  await fs.copyFile(utilsInput, utilsOutput);
93
- console.log(`- utils.ts (${utilsOutput}`);
115
+ console.log(`- ${utilsFilename} (${utilsOutput})`);
94
116
  } else {
95
- console.log("- utils.ts (already exists)");
117
+ console.log(`- ${utilsFilename} (already exists)`);
96
118
  }
97
119
 
98
120
  await installDependencies(component);
@@ -4,7 +4,7 @@ import { fileURLToPath } from 'url';
4
4
 
5
5
  export function help() {
6
6
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
- const commands = path.resolve(__dirname, '../cmd');
7
+ const commands = path.resolve(__dirname, '../commands');
8
8
  const names = fs.readdirSync(commands).filter(f => f.endsWith('.js'));
9
9
 
10
10
  console.info('ℹ️ Usage: npx @connectycube/react-ui-kit@latest <command> [args]');
@@ -0,0 +1,5 @@
1
+ {
2
+ "stream-view": {
3
+ "webrtc-adapter": ""
4
+ }
5
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@connectycube/react-ui-kit",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Simple React UI Kit generator with TSX/JSX",
5
5
  "homepage": "https://github.com/ConnectyCube/react-ui-kit#readme",
6
6
  "bugs": {
@@ -33,8 +33,9 @@
33
33
  "module": "dist/index.js",
34
34
  "types": "dist/types/index.d.ts",
35
35
  "files": [
36
+ "configs",
37
+ "commands",
36
38
  "bin",
37
- "cmd",
38
39
  "dist",
39
40
  "src",
40
41
  "gen"
@@ -61,7 +62,8 @@
61
62
  "dependencies": {
62
63
  "execa": "^9.6.0",
63
64
  "fs-extra": "^11.3.2",
64
- "prompts": "^2.4.2"
65
+ "prompts": "^2.4.2",
66
+ "webrtc-adapter": "^9.0.3"
65
67
  },
66
68
  "peerDependencies": {
67
69
  "clsx": "*",
@@ -0,0 +1,63 @@
1
+ import { forwardRef, useEffect, useImperativeHandle, useMemo, useRef } from 'react';
2
+ import { cn, getRandomString } from './utils';
3
+
4
+ export const StreamView = forwardRef(({ id, stream, mirror, className, muted, ...props }, ref) => {
5
+ const videoRef = useRef(null);
6
+ const elementId = useMemo(() => id ?? `stream-${getRandomString()}`, [id]);
7
+ const isMuted = typeof muted === 'boolean' ? muted : true;
8
+ const defaultClassName = 'size-full object-contain';
9
+ const mirrorClassName = mirror ? 'scale-x-[-1]' : '';
10
+
11
+ useImperativeHandle(
12
+ ref,
13
+ () => ({
14
+ id: elementId,
15
+ element: videoRef.current,
16
+ }),
17
+ [elementId]
18
+ );
19
+
20
+ useEffect(() => {
21
+ if (videoRef.current && stream) {
22
+ videoRef.current.srcObject = stream;
23
+
24
+ const playVideo = () => {
25
+ try {
26
+ videoRef.current?.play();
27
+ } catch (error) {
28
+ console.error('<StreamView/> play():', error);
29
+ }
30
+ };
31
+
32
+ videoRef.current.onloadedmetadata = () => {
33
+ setTimeout(playVideo, 100);
34
+ };
35
+ }
36
+ }, [stream]);
37
+
38
+ return stream ? (
39
+ <video
40
+ ref={videoRef}
41
+ id={elementId}
42
+ className={cn(defaultClassName, mirrorClassName, className)}
43
+ muted={isMuted}
44
+ autoPlay
45
+ playsInline
46
+ {...props}
47
+ />
48
+ ) : null;
49
+ });
50
+
51
+ export const LocalStreamView = forwardRef(({ muted, mirror, ...props }, ref) => {
52
+ const isMuted = typeof muted === 'boolean' ? muted : true;
53
+ const isMirror = typeof mirror === 'boolean' ? mirror : true;
54
+
55
+ return <StreamView ref={ref} muted={isMuted} mirror={isMirror} {...props} />;
56
+ });
57
+
58
+ export const RemoteStreamView = forwardRef(({ muted, mirror, ...props }, ref) => {
59
+ const isMuted = typeof muted === 'boolean' ? muted : false;
60
+ const isMirror = typeof mirror === 'boolean' ? mirror : false;
61
+
62
+ return <StreamView ref={ref} muted={isMuted} mirror={isMirror} {...props} />;
63
+ });
@@ -0,0 +1,10 @@
1
+ import { clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+
4
+ export function cn(...inputs) {
5
+ return twMerge(clsx(inputs));
6
+ }
7
+
8
+ export function getRandomString(length = 8) {
9
+ return (Date.now() / Math.random()).toString(36).replace('.', '').slice(0, length);
10
+ }
File without changes