create-weave-frontend-app 0.10.2 → 0.11.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.
@@ -76,11 +76,11 @@ function tryGitInit(root) {
76
76
  //#endregion
77
77
  //#region src/versions.js
78
78
  const versions = {
79
- "@inditextech/weave-types": "0.10.2",
80
- "@inditextech/weave-sdk": "0.10.2",
81
- "@inditextech/weave-store-websockets": "0.10.2",
82
- "@inditextech/weave-store-azure-web-pubsub": "0.10.2",
83
- "@inditextech/weave-react": "0.10.2"
79
+ "@inditextech/weave-types": "0.11.0",
80
+ "@inditextech/weave-sdk": "0.11.0",
81
+ "@inditextech/weave-store-websockets": "0.11.0",
82
+ "@inditextech/weave-store-azure-web-pubsub": "0.11.0",
83
+ "@inditextech/weave-react": "0.11.0"
84
84
  };
85
85
 
86
86
  //#endregion
@@ -428,4 +428,4 @@ function pick(obj, keys) {
428
428
 
429
429
  //#endregion
430
430
  export { create, cwd, getPackageManager };
431
- //# sourceMappingURL=create-app-CA6IZiJb.js.map
431
+ //# sourceMappingURL=create-app-D39n_602.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-app-CA6IZiJb.js","names":["cwd: string","root: string","manager: PackageManager","dest: string","options: Options","file: string","dest: string","projectName: string","from: string","to: string","rename: (s: string) => string","obj: T","keys: K[]","result: Partial<T>"],"sources":["../src/git.ts","../src/versions.js","../template/package.json","../src/auto-install.ts","../src/constants.ts","../src/create-app.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { rmSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/*\nInitialize a Git repo on the project.\n\nBased on https://github.com/vercel/next.js/blob/canary/packages/create-next-app/helpers/git.ts\n*/\n\nfunction isInGitRepository(cwd: string): boolean {\n try {\n execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore', cwd });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isInMercurialRepository(cwd: string): boolean {\n try {\n execSync('hg --cwd . root', { stdio: 'ignore', cwd });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isDefaultBranchSet(cwd: string): boolean {\n try {\n execSync('git config init.defaultBranch', { stdio: 'ignore', cwd });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function tryGitInit(root: string): boolean {\n let didInit = false;\n\n try {\n execSync('git --version', { stdio: 'ignore' });\n if (isInGitRepository(root) || isInMercurialRepository(root)) {\n return false;\n }\n\n execSync('git init', { stdio: 'ignore', cwd: root });\n didInit = true;\n\n if (!isDefaultBranchSet(root)) {\n execSync('git checkout -b main', { stdio: 'ignore', cwd: root });\n }\n\n execSync('git add -A', { stdio: 'ignore', cwd: root });\n execSync('git commit -m \"Initial commit from Create Fumadocs App\"', {\n stdio: 'ignore',\n cwd: root,\n });\n return true;\n } catch {\n if (didInit) {\n try {\n rmSync(join(root, '.git'), { recursive: true, force: true });\n } catch {\n // do nothing\n }\n }\n\n return false;\n }\n}\n","export const versions = {\"@inditextech/weave-types\":\"0.10.2\",\"@inditextech/weave-sdk\":\"0.10.2\",\"@inditextech/weave-store-websockets\":\"0.10.2\",\"@inditextech/weave-store-azure-web-pubsub\":\"0.10.2\",\"@inditextech/weave-react\":\"0.10.2\"}","{\n \"name\": \"example-versions\",\n \"version\": \"0.0.0\",\n \"private\": true,\n \"description\": \"Used to track dependency versions in create-*-app\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"@hookform/resolvers\": \"^4.1.3\",\n \"@inditextech/weave-react\": \"0.0.0\",\n \"@inditextech/weave-sdk\": \"0.0.0\",\n \"@inditextech/weave-store-websockets\": \"0.0.0\",\n \"@inditextech/weave-store-azure-web-pubsub\": \"0.0.0\",\n \"@next/env\": \"^15.2.1\",\n \"@radix-ui/react-accordion\": \"^1.2.3\",\n \"@radix-ui/react-avatar\": \"^1.1.3\",\n \"@radix-ui/react-checkbox\": \"^1.1.4\",\n \"@radix-ui/react-dialog\": \"^1.1.6\",\n \"@radix-ui/react-dropdown-menu\": \"^2.1.6\",\n \"@radix-ui/react-label\": \"^2.1.2\",\n \"@radix-ui/react-popover\": \"^1.1.6\",\n \"@radix-ui/react-scroll-area\": \"^1.2.3\",\n \"@radix-ui/react-select\": \"^2.1.6\",\n \"@radix-ui/react-slider\": \"^1.2.3\",\n \"@radix-ui/react-slot\": \"^1.1.2\",\n \"@radix-ui/react-tabs\": \"^1.1.3\",\n \"@radix-ui/react-tooltip\": \"^1.1.8\",\n \"@react-three/fiber\": \"^8.18.0\",\n \"@react-three/postprocessing\": \"^2.19.1\",\n \"@tanstack/react-query\": \"^5.67.1\",\n \"boring-avatars\": \"^1.11.2\",\n \"class-variance-authority\": \"^0.7.1\",\n \"clsx\": \"^2.1.1\",\n \"cmdk\": \"^1.0.0\",\n \"color\": \"^5.0.0\",\n \"framer-motion\": \"^11.18.2\",\n \"konva\": \"^9.3.18\",\n \"motion\": \"^12.4.7\",\n \"next\": \"14.2.28\",\n \"next-themes\": \"^0.4.6\",\n \"ogl\": \"^1.0.11\",\n \"onnxruntime-web\": \"^1.21.0-dev.20250206-d981b153d3\",\n \"pdf-lib\": \"^1.17.1\",\n \"platform-detect\": \"^3.0.1\",\n \"postprocessing\": \"^6.37.1\",\n \"react\": \"18.2.0\",\n \"react-dom\": \"18.2.0\",\n \"react-hook-form\": \"^7.54.2\",\n \"react-number-format\": \"^5.4.3\",\n \"sharp\": \"^0.33.5\",\n \"sonner\": \"^2.0.3\",\n \"tailwind-merge\": \"^3.0.2\",\n \"tailwindcss-animate\": \"^1.0.7\",\n \"three\": \"^0.167.1\",\n \"uuid\": \"^11.1.0\",\n \"vaul\": \"^1.1.2\",\n \"zod\": \"^3.24.2\",\n \"zustand\": \"^5.0.3\"\n },\n \"devDependencies\": {\n \"@eslint/eslintrc\": \"^3\",\n \"@tailwindcss/postcss\": \"^4\",\n \"@testing-library/dom\": \"^10.4.0\",\n \"@testing-library/react\": \"^16.2.0\",\n \"@types/node\": \"^20\",\n \"@types/react\": \"^18\",\n \"@types/react-dom\": \"^18\",\n \"@vitejs/plugin-react\": \"^4.3.4\",\n \"@vitest/coverage-v8\": \"^3.0.7\",\n \"eslint\": \"^8\",\n \"eslint-config-next\": \"14.2.24\",\n \"eslint-config-prettier\": \"^10.0.2\",\n \"jsdom\": \"^26.0.0\",\n \"lucide-react\": \"^0.477.0\",\n \"tailwindcss\": \"^4\",\n \"typescript\": \"^5\",\n \"vite-tsconfig-paths\": \"^5.1.4\",\n \"vitest\": \"^3.0.7\"\n }\n}\n","import { spawn } from 'cross-spawn';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\n\nexport function getPackageManager(): PackageManager {\n const userAgent = process.env.npm_config_user_agent ?? '';\n\n if (userAgent.startsWith('yarn')) {\n return 'yarn';\n }\n\n if (userAgent.startsWith('pnpm')) {\n return 'pnpm';\n }\n\n if (userAgent.startsWith('bun')) {\n return 'bun';\n }\n\n return 'npm';\n}\n\nexport function autoInstall(\n manager: PackageManager,\n dest: string,\n): Promise<void> {\n return new Promise((res, reject) => {\n const installProcess = spawn(manager, ['install'], {\n stdio: 'ignore',\n env: {\n ...process.env,\n NODE_ENV: 'development',\n DISABLE_OPENCOLLECTIVE: '1',\n },\n cwd: dest,\n });\n\n installProcess.on('close', (code) => {\n if (code !== 0) {\n reject(new Error('Install failed'));\n } else {\n res();\n }\n });\n });\n}\n","import { fileURLToPath } from 'node:url';\n\nexport const sourceDir = fileURLToPath(new URL(`../`, import.meta.url).href);\nexport const cwd = process.cwd();\n","import path from 'node:path';\nimport fs from 'node:fs/promises';\nimport { tryGitInit } from '@/git';\nimport { versions as localVersions } from '@/versions';\nimport versionPkg from './../template/package.json';\nimport type { PackageManager } from './auto-install';\nimport { autoInstall } from './auto-install';\nimport { cwd, sourceDir } from './constants';\n\nexport type Template = '+nextjs+websockets' | '+nextjs+azure-web-pubsub';\n\nexport interface Options {\n outputDir: string;\n template: Template;\n packageManager: PackageManager;\n installDeps?: boolean;\n initializeGit?: boolean;\n log?: (message: string) => void;\n}\n\nexport async function create(options: Options): Promise<void> {\n const {\n installDeps = true,\n initializeGit = true,\n log = console.log,\n } = options;\n const projectName = path.basename(options.outputDir);\n const dest = path.resolve(cwd, options.outputDir);\n\n function defaultRename(file: string): string {\n file = file.replace('example.gitignore', '.gitignore');\n file = file.replace('example.env', '.env');\n\n return file;\n }\n\n await copy(\n path.join(sourceDir, `template/${options.template}`),\n dest,\n defaultRename\n );\n\n const packageJson = createPackageJson(projectName, options);\n await fs.writeFile(\n path.join(dest, 'package.json'),\n JSON.stringify(packageJson, null, 2)\n );\n\n const readMe = await getReadme(dest, projectName);\n await fs.writeFile(path.join(dest, 'README.md'), readMe);\n\n if (installDeps) {\n await autoInstall(options.packageManager, dest);\n log('Installed dependencies');\n }\n\n if (initializeGit && tryGitInit(dest)) {\n log('Initialized Git repository');\n }\n}\n\nasync function getReadme(dest: string, projectName: string): Promise<string> {\n const template = await fs\n .readFile(path.join(dest, 'README.md'))\n .then((res) => res.toString());\n\n return `# ${projectName}\\n\\n${template}`;\n}\n\nasync function copy(\n from: string,\n to: string,\n rename: (s: string) => string = (s) => s\n): Promise<void> {\n const stats = await fs.stat(from);\n\n if (stats.isDirectory()) {\n const files = await fs.readdir(from);\n\n await Promise.all(\n files.map((file) =>\n copy(path.join(from, file), rename(path.join(to, file)))\n )\n );\n } else {\n await fs.mkdir(path.dirname(to), { recursive: true });\n await fs.copyFile(from, to);\n }\n}\n\nfunction createPackageJson(projectName: string, options: Options): object {\n if (options.template === '+nextjs+azure-web-pubsub') {\n const dependencies = {\n ...pick(versionPkg.dependencies, [\n '@hookform/resolvers',\n '@next/env',\n '@radix-ui/react-accordion',\n '@radix-ui/react-avatar',\n '@radix-ui/react-checkbox',\n '@radix-ui/react-dialog',\n '@radix-ui/react-dropdown-menu',\n '@radix-ui/react-label',\n '@radix-ui/react-popover',\n '@radix-ui/react-scroll-area',\n '@radix-ui/react-select',\n '@radix-ui/react-slider',\n '@radix-ui/react-slot',\n '@radix-ui/react-tabs',\n '@radix-ui/react-tooltip',\n '@react-three/fiber',\n '@react-three/postprocessing',\n '@tanstack/react-query',\n 'boring-avatars',\n 'class-variance-authority',\n 'clsx',\n 'cmdk',\n 'color',\n 'framer-motion',\n 'konva',\n 'motion',\n 'next',\n 'next-themes',\n 'ogl',\n 'onnxruntime-web',\n 'pdf-lib',\n 'platform-detect',\n 'postprocessing',\n 'react',\n 'react-dom',\n 'react-hook-form',\n 'react-number-format',\n 'sharp',\n 'sonner',\n 'tailwind-merge',\n 'tailwindcss-animate',\n 'three',\n 'uuid',\n 'vaul',\n 'zod',\n 'zustand',\n ]),\n ...pick(localVersions, [\n '@inditextech/weave-react',\n '@inditextech/weave-sdk',\n '@inditextech/weave-store-azure-web-pubsub',\n ]),\n };\n\n const devDependencies = {\n ...pick(versionPkg.devDependencies, [\n '@eslint/eslintrc',\n '@tailwindcss/postcss',\n '@testing-library/dom',\n '@testing-library/react',\n '@types/node',\n '@types/react',\n '@types/react-dom',\n '@vitejs/plugin-react',\n 'eslint',\n 'eslint-config-next',\n 'eslint-config-prettier',\n 'jsdom',\n 'lucide-react',\n 'tailwindcss',\n 'typescript',\n 'vite-tsconfig-paths',\n ]),\n };\n\n return {\n name: projectName,\n version: '0.0.0',\n private: true,\n scripts: {\n build: 'next build',\n dev: 'next dev --experimental-https',\n lint: 'next lint',\n start: 'next start',\n },\n dependencies: sortObjectKeys(dependencies),\n devDependencies: sortObjectKeys(devDependencies),\n };\n }\n\n const dependencies = {\n ...pick(versionPkg.dependencies, [\n '@hookform/resolvers',\n '@next/env',\n '@radix-ui/react-accordion',\n '@radix-ui/react-avatar',\n '@radix-ui/react-checkbox',\n '@radix-ui/react-dialog',\n '@radix-ui/react-dropdown-menu',\n '@radix-ui/react-label',\n '@radix-ui/react-popover',\n '@radix-ui/react-scroll-area',\n '@radix-ui/react-select',\n '@radix-ui/react-slider',\n '@radix-ui/react-slot',\n '@radix-ui/react-tabs',\n '@radix-ui/react-tooltip',\n '@react-three/fiber',\n '@react-three/postprocessing',\n '@tanstack/react-query',\n 'boring-avatars',\n 'class-variance-authority',\n 'clsx',\n 'cmdk',\n 'color',\n 'framer-motion',\n 'konva',\n 'motion',\n 'next',\n 'next-themes',\n 'ogl',\n 'onnxruntime-web',\n 'pdf-lib',\n 'platform-detect',\n 'postprocessing',\n 'react',\n 'react-dom',\n 'react-hook-form',\n 'react-number-format',\n 'sharp',\n 'sonner',\n 'tailwind-merge',\n 'tailwindcss-animate',\n 'three',\n 'uuid',\n 'vaul',\n 'zod',\n 'zustand',\n ]),\n ...pick(localVersions, [\n '@inditextech/weave-react',\n '@inditextech/weave-sdk',\n '@inditextech/weave-store-websockets',\n ]),\n };\n\n const devDependencies = {\n ...pick(versionPkg.devDependencies, [\n '@eslint/eslintrc',\n '@tailwindcss/postcss',\n '@testing-library/dom',\n '@testing-library/react',\n '@types/node',\n '@types/react',\n '@types/react-dom',\n '@vitejs/plugin-react',\n 'eslint',\n 'eslint-config-next',\n 'eslint-config-prettier',\n 'jsdom',\n 'lucide-react',\n 'tailwindcss',\n 'typescript',\n 'vite-tsconfig-paths',\n ]),\n };\n\n return {\n name: projectName,\n version: '0.0.0',\n private: true,\n scripts: {\n build: 'next build',\n dev: 'next dev --experimental-https',\n lint: 'next lint',\n start: 'next start',\n },\n dependencies: sortObjectKeys(dependencies),\n devDependencies: sortObjectKeys(devDependencies),\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction sortObjectKeys<T extends Record<string, any>>(obj: T): T {\n const sortedEntries = Object.keys(obj)\n .sort()\n .map((key) => [key, obj[key]] as [keyof T, T[keyof T]]);\n\n return Object.fromEntries(sortedEntries) as T;\n}\n\nfunction pick<T extends object, K extends keyof T>(\n obj: T,\n keys: K[]\n): Pick<T, K> {\n const result: Partial<T> = {};\n\n for (const key of keys) {\n if (key in obj) {\n result[key] = obj[key];\n }\n }\n\n return result as Pick<T, K>;\n}\n"],"mappings":"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ACxE,KAAI,QAAQ,aAAa,4BAA4B;EACnD,MAAM,iBAAe;GACnB,GAAG,KAAK,gBAAW,cAAc;IAC/B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACD,EAAC;GACF,GAAG,KAAK,UAAe;IACrB;IACA;IACA;GACD,EAAC;EACH;EAED,MAAM,oBAAkB,EACtB,GAAG,KAAK,gBAAW,iBAAiB;GAClC;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACD,EAAC,CACH;AAED,SAAO;GACL,MAAM;GACN,SAAS;GACT,SAAS;GACT,SAAS;IACP,OAAO;IACP,KAAK;IACL,MAAM;IACN,OAAO;GACR;GACD,cAAc,eAAe,eAAa;GAC1C,iBAAiB,eAAe,kBAAgB;EACjD;CACF;CAED,MAAM,iBAAe;EACnB,GAAG,KAAK,gBAAW,cAAc;GAC/B;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACD,EAAC;EACF,GAAG,KAAK,UAAe;GACrB;GACA;GACA;EACD,EAAC;CACH;CAED,MAAM,oBAAkB,EACtB,GAAG,KAAK,gBAAW,iBAAiB;EAClC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACD,EAAC,CACH;AAED,QAAO;EACL,MAAM;EACN,SAAS;EACT,SAAS;EACT,SAAS;GACP,OAAO;GACP,KAAK;GACL,MAAM;GACN,OAAO;EACR;EACD,cAAc,eAAe,eAAa;EAC1C,iBAAiB,eAAe,kBAAgB;CACjD;AACF;AAGD,SAAS,eAA8CO,KAAW;CAChE,MAAM,gBAAgB,OAAO,KAAK,IAAI,CACnC,MAAM,CACN,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAK,EAA0B;AAEzD,QAAO,OAAO,YAAY,cAAc;AACzC;AAED,SAAS,KACPA,KACAC,MACY;CACZ,MAAMC,SAAqB,CAAE;AAE7B,MAAK,MAAM,OAAO,KAChB,KAAI,OAAO,IACT,QAAO,OAAO,IAAI;AAItB,QAAO;AACR"}
1
+ {"version":3,"file":"create-app-D39n_602.js","names":["cwd: string","root: string","manager: PackageManager","dest: string","options: Options","file: string","dest: string","projectName: string","from: string","to: string","rename: (s: string) => string","obj: T","keys: K[]","result: Partial<T>"],"sources":["../src/git.ts","../src/versions.js","../template/package.json","../src/auto-install.ts","../src/constants.ts","../src/create-app.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { rmSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/*\nInitialize a Git repo on the project.\n\nBased on https://github.com/vercel/next.js/blob/canary/packages/create-next-app/helpers/git.ts\n*/\n\nfunction isInGitRepository(cwd: string): boolean {\n try {\n execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore', cwd });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isInMercurialRepository(cwd: string): boolean {\n try {\n execSync('hg --cwd . root', { stdio: 'ignore', cwd });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isDefaultBranchSet(cwd: string): boolean {\n try {\n execSync('git config init.defaultBranch', { stdio: 'ignore', cwd });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function tryGitInit(root: string): boolean {\n let didInit = false;\n\n try {\n execSync('git --version', { stdio: 'ignore' });\n if (isInGitRepository(root) || isInMercurialRepository(root)) {\n return false;\n }\n\n execSync('git init', { stdio: 'ignore', cwd: root });\n didInit = true;\n\n if (!isDefaultBranchSet(root)) {\n execSync('git checkout -b main', { stdio: 'ignore', cwd: root });\n }\n\n execSync('git add -A', { stdio: 'ignore', cwd: root });\n execSync('git commit -m \"Initial commit from Create Fumadocs App\"', {\n stdio: 'ignore',\n cwd: root,\n });\n return true;\n } catch {\n if (didInit) {\n try {\n rmSync(join(root, '.git'), { recursive: true, force: true });\n } catch {\n // do nothing\n }\n }\n\n return false;\n }\n}\n","export const versions = {\"@inditextech/weave-types\":\"0.11.0\",\"@inditextech/weave-sdk\":\"0.11.0\",\"@inditextech/weave-store-websockets\":\"0.11.0\",\"@inditextech/weave-store-azure-web-pubsub\":\"0.11.0\",\"@inditextech/weave-react\":\"0.11.0\"}","{\n \"name\": \"example-versions\",\n \"version\": \"0.0.0\",\n \"private\": true,\n \"description\": \"Used to track dependency versions in create-*-app\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"@hookform/resolvers\": \"^4.1.3\",\n \"@inditextech/weave-react\": \"0.0.0\",\n \"@inditextech/weave-sdk\": \"0.0.0\",\n \"@inditextech/weave-store-websockets\": \"0.0.0\",\n \"@inditextech/weave-store-azure-web-pubsub\": \"0.0.0\",\n \"@next/env\": \"^15.2.1\",\n \"@radix-ui/react-accordion\": \"^1.2.3\",\n \"@radix-ui/react-avatar\": \"^1.1.3\",\n \"@radix-ui/react-checkbox\": \"^1.1.4\",\n \"@radix-ui/react-dialog\": \"^1.1.6\",\n \"@radix-ui/react-dropdown-menu\": \"^2.1.6\",\n \"@radix-ui/react-label\": \"^2.1.2\",\n \"@radix-ui/react-popover\": \"^1.1.6\",\n \"@radix-ui/react-scroll-area\": \"^1.2.3\",\n \"@radix-ui/react-select\": \"^2.1.6\",\n \"@radix-ui/react-slider\": \"^1.2.3\",\n \"@radix-ui/react-slot\": \"^1.1.2\",\n \"@radix-ui/react-tabs\": \"^1.1.3\",\n \"@radix-ui/react-tooltip\": \"^1.1.8\",\n \"@react-three/fiber\": \"^8.18.0\",\n \"@react-three/postprocessing\": \"^2.19.1\",\n \"@tanstack/react-query\": \"^5.67.1\",\n \"boring-avatars\": \"^1.11.2\",\n \"class-variance-authority\": \"^0.7.1\",\n \"clsx\": \"^2.1.1\",\n \"cmdk\": \"^1.0.0\",\n \"color\": \"^5.0.0\",\n \"framer-motion\": \"^11.18.2\",\n \"konva\": \"^9.3.18\",\n \"motion\": \"^12.4.7\",\n \"next\": \"14.2.28\",\n \"next-themes\": \"^0.4.6\",\n \"ogl\": \"^1.0.11\",\n \"onnxruntime-web\": \"^1.21.0-dev.20250206-d981b153d3\",\n \"pdf-lib\": \"^1.17.1\",\n \"platform-detect\": \"^3.0.1\",\n \"postprocessing\": \"^6.37.1\",\n \"react\": \"18.2.0\",\n \"react-dom\": \"18.2.0\",\n \"react-hook-form\": \"^7.54.2\",\n \"react-number-format\": \"^5.4.3\",\n \"sharp\": \"^0.33.5\",\n \"sonner\": \"^2.0.3\",\n \"tailwind-merge\": \"^3.0.2\",\n \"tailwindcss-animate\": \"^1.0.7\",\n \"three\": \"^0.167.1\",\n \"uuid\": \"^11.1.0\",\n \"vaul\": \"^1.1.2\",\n \"zod\": \"^3.24.2\",\n \"zustand\": \"^5.0.3\"\n },\n \"devDependencies\": {\n \"@eslint/eslintrc\": \"^3\",\n \"@tailwindcss/postcss\": \"^4\",\n \"@testing-library/dom\": \"^10.4.0\",\n \"@testing-library/react\": \"^16.2.0\",\n \"@types/node\": \"^20\",\n \"@types/react\": \"^18\",\n \"@types/react-dom\": \"^18\",\n \"@vitejs/plugin-react\": \"^4.3.4\",\n \"@vitest/coverage-v8\": \"^3.0.7\",\n \"eslint\": \"^8\",\n \"eslint-config-next\": \"14.2.24\",\n \"eslint-config-prettier\": \"^10.0.2\",\n \"jsdom\": \"^26.0.0\",\n \"lucide-react\": \"^0.477.0\",\n \"tailwindcss\": \"^4\",\n \"typescript\": \"^5\",\n \"vite-tsconfig-paths\": \"^5.1.4\",\n \"vitest\": \"^3.0.7\"\n }\n}\n","import { spawn } from 'cross-spawn';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\n\nexport function getPackageManager(): PackageManager {\n const userAgent = process.env.npm_config_user_agent ?? '';\n\n if (userAgent.startsWith('yarn')) {\n return 'yarn';\n }\n\n if (userAgent.startsWith('pnpm')) {\n return 'pnpm';\n }\n\n if (userAgent.startsWith('bun')) {\n return 'bun';\n }\n\n return 'npm';\n}\n\nexport function autoInstall(\n manager: PackageManager,\n dest: string,\n): Promise<void> {\n return new Promise((res, reject) => {\n const installProcess = spawn(manager, ['install'], {\n stdio: 'ignore',\n env: {\n ...process.env,\n NODE_ENV: 'development',\n DISABLE_OPENCOLLECTIVE: '1',\n },\n cwd: dest,\n });\n\n installProcess.on('close', (code) => {\n if (code !== 0) {\n reject(new Error('Install failed'));\n } else {\n res();\n }\n });\n });\n}\n","import { fileURLToPath } from 'node:url';\n\nexport const sourceDir = fileURLToPath(new URL(`../`, import.meta.url).href);\nexport const cwd = process.cwd();\n","import path from 'node:path';\nimport fs from 'node:fs/promises';\nimport { tryGitInit } from '@/git';\nimport { versions as localVersions } from '@/versions';\nimport versionPkg from './../template/package.json';\nimport type { PackageManager } from './auto-install';\nimport { autoInstall } from './auto-install';\nimport { cwd, sourceDir } from './constants';\n\nexport type Template = '+nextjs+websockets' | '+nextjs+azure-web-pubsub';\n\nexport interface Options {\n outputDir: string;\n template: Template;\n packageManager: PackageManager;\n installDeps?: boolean;\n initializeGit?: boolean;\n log?: (message: string) => void;\n}\n\nexport async function create(options: Options): Promise<void> {\n const {\n installDeps = true,\n initializeGit = true,\n log = console.log,\n } = options;\n const projectName = path.basename(options.outputDir);\n const dest = path.resolve(cwd, options.outputDir);\n\n function defaultRename(file: string): string {\n file = file.replace('example.gitignore', '.gitignore');\n file = file.replace('example.env', '.env');\n\n return file;\n }\n\n await copy(\n path.join(sourceDir, `template/${options.template}`),\n dest,\n defaultRename\n );\n\n const packageJson = createPackageJson(projectName, options);\n await fs.writeFile(\n path.join(dest, 'package.json'),\n JSON.stringify(packageJson, null, 2)\n );\n\n const readMe = await getReadme(dest, projectName);\n await fs.writeFile(path.join(dest, 'README.md'), readMe);\n\n if (installDeps) {\n await autoInstall(options.packageManager, dest);\n log('Installed dependencies');\n }\n\n if (initializeGit && tryGitInit(dest)) {\n log('Initialized Git repository');\n }\n}\n\nasync function getReadme(dest: string, projectName: string): Promise<string> {\n const template = await fs\n .readFile(path.join(dest, 'README.md'))\n .then((res) => res.toString());\n\n return `# ${projectName}\\n\\n${template}`;\n}\n\nasync function copy(\n from: string,\n to: string,\n rename: (s: string) => string = (s) => s\n): Promise<void> {\n const stats = await fs.stat(from);\n\n if (stats.isDirectory()) {\n const files = await fs.readdir(from);\n\n await Promise.all(\n files.map((file) =>\n copy(path.join(from, file), rename(path.join(to, file)))\n )\n );\n } else {\n await fs.mkdir(path.dirname(to), { recursive: true });\n await fs.copyFile(from, to);\n }\n}\n\nfunction createPackageJson(projectName: string, options: Options): object {\n if (options.template === '+nextjs+azure-web-pubsub') {\n const dependencies = {\n ...pick(versionPkg.dependencies, [\n '@hookform/resolvers',\n '@next/env',\n '@radix-ui/react-accordion',\n '@radix-ui/react-avatar',\n '@radix-ui/react-checkbox',\n '@radix-ui/react-dialog',\n '@radix-ui/react-dropdown-menu',\n '@radix-ui/react-label',\n '@radix-ui/react-popover',\n '@radix-ui/react-scroll-area',\n '@radix-ui/react-select',\n '@radix-ui/react-slider',\n '@radix-ui/react-slot',\n '@radix-ui/react-tabs',\n '@radix-ui/react-tooltip',\n '@react-three/fiber',\n '@react-three/postprocessing',\n '@tanstack/react-query',\n 'boring-avatars',\n 'class-variance-authority',\n 'clsx',\n 'cmdk',\n 'color',\n 'framer-motion',\n 'konva',\n 'motion',\n 'next',\n 'next-themes',\n 'ogl',\n 'onnxruntime-web',\n 'pdf-lib',\n 'platform-detect',\n 'postprocessing',\n 'react',\n 'react-dom',\n 'react-hook-form',\n 'react-number-format',\n 'sharp',\n 'sonner',\n 'tailwind-merge',\n 'tailwindcss-animate',\n 'three',\n 'uuid',\n 'vaul',\n 'zod',\n 'zustand',\n ]),\n ...pick(localVersions, [\n '@inditextech/weave-react',\n '@inditextech/weave-sdk',\n '@inditextech/weave-store-azure-web-pubsub',\n ]),\n };\n\n const devDependencies = {\n ...pick(versionPkg.devDependencies, [\n '@eslint/eslintrc',\n '@tailwindcss/postcss',\n '@testing-library/dom',\n '@testing-library/react',\n '@types/node',\n '@types/react',\n '@types/react-dom',\n '@vitejs/plugin-react',\n 'eslint',\n 'eslint-config-next',\n 'eslint-config-prettier',\n 'jsdom',\n 'lucide-react',\n 'tailwindcss',\n 'typescript',\n 'vite-tsconfig-paths',\n ]),\n };\n\n return {\n name: projectName,\n version: '0.0.0',\n private: true,\n scripts: {\n build: 'next build',\n dev: 'next dev --experimental-https',\n lint: 'next lint',\n start: 'next start',\n },\n dependencies: sortObjectKeys(dependencies),\n devDependencies: sortObjectKeys(devDependencies),\n };\n }\n\n const dependencies = {\n ...pick(versionPkg.dependencies, [\n '@hookform/resolvers',\n '@next/env',\n '@radix-ui/react-accordion',\n '@radix-ui/react-avatar',\n '@radix-ui/react-checkbox',\n '@radix-ui/react-dialog',\n '@radix-ui/react-dropdown-menu',\n '@radix-ui/react-label',\n '@radix-ui/react-popover',\n '@radix-ui/react-scroll-area',\n '@radix-ui/react-select',\n '@radix-ui/react-slider',\n '@radix-ui/react-slot',\n '@radix-ui/react-tabs',\n '@radix-ui/react-tooltip',\n '@react-three/fiber',\n '@react-three/postprocessing',\n '@tanstack/react-query',\n 'boring-avatars',\n 'class-variance-authority',\n 'clsx',\n 'cmdk',\n 'color',\n 'framer-motion',\n 'konva',\n 'motion',\n 'next',\n 'next-themes',\n 'ogl',\n 'onnxruntime-web',\n 'pdf-lib',\n 'platform-detect',\n 'postprocessing',\n 'react',\n 'react-dom',\n 'react-hook-form',\n 'react-number-format',\n 'sharp',\n 'sonner',\n 'tailwind-merge',\n 'tailwindcss-animate',\n 'three',\n 'uuid',\n 'vaul',\n 'zod',\n 'zustand',\n ]),\n ...pick(localVersions, [\n '@inditextech/weave-react',\n '@inditextech/weave-sdk',\n '@inditextech/weave-store-websockets',\n ]),\n };\n\n const devDependencies = {\n ...pick(versionPkg.devDependencies, [\n '@eslint/eslintrc',\n '@tailwindcss/postcss',\n '@testing-library/dom',\n '@testing-library/react',\n '@types/node',\n '@types/react',\n '@types/react-dom',\n '@vitejs/plugin-react',\n 'eslint',\n 'eslint-config-next',\n 'eslint-config-prettier',\n 'jsdom',\n 'lucide-react',\n 'tailwindcss',\n 'typescript',\n 'vite-tsconfig-paths',\n ]),\n };\n\n return {\n name: projectName,\n version: '0.0.0',\n private: true,\n scripts: {\n build: 'next build',\n dev: 'next dev --experimental-https',\n lint: 'next lint',\n start: 'next start',\n },\n dependencies: sortObjectKeys(dependencies),\n devDependencies: sortObjectKeys(devDependencies),\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction sortObjectKeys<T extends Record<string, any>>(obj: T): T {\n const sortedEntries = Object.keys(obj)\n .sort()\n .map((key) => [key, obj[key]] as [keyof T, T[keyof T]]);\n\n return Object.fromEntries(sortedEntries) as T;\n}\n\nfunction pick<T extends object, K extends keyof T>(\n obj: T,\n keys: K[]\n): Pick<T, K> {\n const result: Partial<T> = {};\n\n for (const key of keys) {\n if (key in obj) {\n result[key] = obj[key];\n }\n }\n\n return result as Pick<T, K>;\n}\n"],"mappings":"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ACxE,KAAI,QAAQ,aAAa,4BAA4B;EACnD,MAAM,iBAAe;GACnB,GAAG,KAAK,gBAAW,cAAc;IAC/B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACD,EAAC;GACF,GAAG,KAAK,UAAe;IACrB;IACA;IACA;GACD,EAAC;EACH;EAED,MAAM,oBAAkB,EACtB,GAAG,KAAK,gBAAW,iBAAiB;GAClC;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACD,EAAC,CACH;AAED,SAAO;GACL,MAAM;GACN,SAAS;GACT,SAAS;GACT,SAAS;IACP,OAAO;IACP,KAAK;IACL,MAAM;IACN,OAAO;GACR;GACD,cAAc,eAAe,eAAa;GAC1C,iBAAiB,eAAe,kBAAgB;EACjD;CACF;CAED,MAAM,iBAAe;EACnB,GAAG,KAAK,gBAAW,cAAc;GAC/B;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACD,EAAC;EACF,GAAG,KAAK,UAAe;GACrB;GACA;GACA;EACD,EAAC;CACH;CAED,MAAM,oBAAkB,EACtB,GAAG,KAAK,gBAAW,iBAAiB;EAClC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACD,EAAC,CACH;AAED,QAAO;EACL,MAAM;EACN,SAAS;EACT,SAAS;EACT,SAAS;GACP,OAAO;GACP,KAAK;GACL,MAAM;GACN,OAAO;EACR;EACD,cAAc,eAAe,eAAa;EAC1C,iBAAiB,eAAe,kBAAgB;CACjD;AACF;AAGD,SAAS,eAA8CO,KAAW;CAChE,MAAM,gBAAgB,OAAO,KAAK,IAAI,CACnC,MAAM,CACN,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAK,EAA0B;AAEzD,QAAO,OAAO,YAAY,cAAc;AACzC;AAED,SAAS,KACPA,KACAC,MACY;CACZ,MAAMC,SAAqB,CAAE;AAE7B,MAAK,MAAM,OAAO,KAChB,KAAI,OAAO,IACT,QAAO,OAAO,IAAI;AAItB,QAAO;AACR"}
@@ -1,3 +1,3 @@
1
- import { create } from "./create-app-CA6IZiJb.js";
1
+ import { create } from "./create-app-D39n_602.js";
2
2
 
3
3
  export { create };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { create, cwd, getPackageManager } from "./create-app-CA6IZiJb.js";
2
+ import { create, cwd, getPackageManager } from "./create-app-D39n_602.js";
3
3
  import path from "node:path";
4
4
  import fs from "node:fs/promises";
5
5
  import { cancel, confirm, group, intro, isCancel, outro, select, spinner, text } from "@clack/prompts";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-weave-frontend-app",
3
- "version": "0.10.2",
3
+ "version": "0.11.0",
4
4
  "description": "Create a new frontend artifact for a site with Weave.js",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -1,10 +1,4 @@
1
- /*
2
- * SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.)
3
- *
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- @import "tailwindcss";
1
+ @import 'tailwindcss';
8
2
 
9
3
  @plugin "tailwindcss-animate";
10
4
 
@@ -186,7 +180,7 @@
186
180
  @apply w-full h-full;
187
181
  }
188
182
  body {
189
- @apply bg-background ring-0 text-foreground w-full h-full;
183
+ @apply bg-background ring-0 text-foreground w-full h-full overflow-hidden;
190
184
  }
191
185
  }
192
186
 
@@ -195,6 +189,6 @@
195
189
  @apply border-border outline-ring/50;
196
190
  }
197
191
  body {
198
- @apply bg-background ring-0 text-foreground;
192
+ @apply bg-background ring-0 text-foreground overflow-hidden;
199
193
  }
200
194
  }
@@ -44,6 +44,8 @@ export default function RootLayout({
44
44
  return (
45
45
  <html lang="en">
46
46
  <body
47
+ contentEditable="true"
48
+ suppressContentEditableWarning={true}
47
49
  className={`${questrial.variable} ${notoSans.variable} ${notoSansMono.variable} antialiased`}
48
50
  >
49
51
  <AppProviders>{children}</AppProviders>
@@ -107,15 +107,7 @@ export const RoomLayout = () => {
107
107
  className="w-full h-full flex flex-col"
108
108
  >
109
109
  <section className="w-full h-full flex">
110
- <motion.section
111
- animate={{
112
- width: sidebarLeftActive === null ? 0 : 320,
113
- opacity: sidebarLeftActive === null ? 0 : 1,
114
- }}
115
- transition={{
116
- duration: sidebarLeftActive === null ? 0.1 : 0.25,
117
- ease: 'easeInOut',
118
- }}
110
+ <section
119
111
  id="sidebar-left"
120
112
  className={cn(
121
113
  'bg-white h-full border-l border-zinc-200 shadow-md',
@@ -131,7 +123,7 @@ export const RoomLayout = () => {
131
123
  <ColorTokensLibrary key={SIDEBAR_ELEMENTS.colorTokens} />
132
124
  <ElementsTree key={SIDEBAR_ELEMENTS.nodesTree} />
133
125
  </AnimatePresence>
134
- </motion.section>
126
+ </section>
135
127
  <section
136
128
  className={cn('w-full h-full flex flex-col', {
137
129
  ['w-[calc(100%-320px)]']:
@@ -194,15 +186,7 @@ export const RoomLayout = () => {
194
186
  )}
195
187
  </section>
196
188
  </section>
197
- <motion.section
198
- animate={{
199
- width: sidebarRightActive === null ? 0 : 320,
200
- opacity: sidebarRightActive === null ? 0 : 1,
201
- }}
202
- transition={{
203
- duration: sidebarRightActive === null ? 0.1 : 0.25,
204
- ease: 'easeInOut',
205
- }}
189
+ <section
206
190
  id="sidebar-right"
207
191
  className={cn(
208
192
  'bg-white h-full border-l border-zinc-200 shadow-md',
@@ -213,7 +197,7 @@ export const RoomLayout = () => {
213
197
  )}
214
198
  >
215
199
  <NodeProperties />
216
- </motion.section>
200
+ </section>
217
201
  </section>
218
202
  </motion.div>
219
203
  </AnimatePresence>
@@ -13,7 +13,7 @@ function useCopyPaste() {
13
13
  (error: WeaveCopyPasteNodesPluginOnCopyEvent): void => {
14
14
  if (error) {
15
15
  console.error('onCopy', error);
16
- toast.error('Aan error occurred when copying to the clipboard');
16
+ toast.error('An error occurred when copying to the clipboard');
17
17
  } else {
18
18
  toast.success('Copy successful');
19
19
  }
@@ -25,7 +25,7 @@ function useCopyPaste() {
25
25
  (error: WeaveCopyPasteNodesPluginOnPasteEvent): void => {
26
26
  if (error) {
27
27
  console.error('onPaste', error);
28
- toast.error('Aan error occurred when reading from the clipboard');
28
+ toast.error('An error occurred when reading from the clipboard');
29
29
  } else {
30
30
  toast.success('Paste successful');
31
31
  }
@@ -36,8 +36,6 @@ export const NodeProperties = () => {
36
36
  );
37
37
 
38
38
  React.useEffect(() => {
39
- if (!instance) return;
40
-
41
39
  if (
42
40
  actualAction &&
43
41
  [
@@ -53,7 +51,7 @@ export const NodeProperties = () => {
53
51
  setSidebarActive(SIDEBAR_ELEMENTS.nodeProperties, 'right');
54
52
  }
55
53
 
56
- if (!actualAction) {
54
+ if (!actualAction && !node) {
57
55
  setNodePropertiesAction(undefined);
58
56
  setSidebarActive(null, 'right');
59
57
  }
@@ -61,7 +59,7 @@ export const NodeProperties = () => {
61
59
  if (node) {
62
60
  setNodePropertiesAction('update');
63
61
  }
64
- }, [actualAction, node]);
62
+ }, [actualAction, node, setSidebarActive, setNodePropertiesAction]);
65
63
 
66
64
  const nodeType = React.useMemo(() => {
67
65
  switch (node?.type) {
@@ -104,6 +102,15 @@ export const NodeProperties = () => {
104
102
  }, [actualAction]);
105
103
 
106
104
  React.useEffect(() => {
105
+ if (
106
+ nodePropertiesAction === 'create' &&
107
+ actualAction === 'selectionTool' &&
108
+ actionType === 'Unknown' &&
109
+ nodeType === 'Unknown'
110
+ ) {
111
+ setSidebarActive(null, 'right');
112
+ return;
113
+ }
107
114
  if (nodePropertiesAction === 'create' && actionType) {
108
115
  setSidebarActive(SIDEBAR_ELEMENTS.nodeProperties, 'right');
109
116
  return;
@@ -113,7 +120,14 @@ export const NodeProperties = () => {
113
120
  return;
114
121
  }
115
122
  setSidebarActive(null, 'right');
116
- }, [node, sidebarRightActive, setSidebarActive]);
123
+ }, [
124
+ actionType,
125
+ nodeType,
126
+ nodePropertiesAction,
127
+ node,
128
+ sidebarRightActive,
129
+ setSidebarActive,
130
+ ]);
117
131
 
118
132
  const title = React.useMemo(() => {
119
133
  if (nodePropertiesAction === 'create') {
@@ -136,9 +150,22 @@ export const NodeProperties = () => {
136
150
  <button
137
151
  className="cursor-pointer bg-transparent hover:bg-accent p-2"
138
152
  onClick={() => {
139
- if (instance) {
140
- instance.selectNodesByKey([]);
153
+ if (!instance) return;
154
+ if (
155
+ actualAction &&
156
+ [
157
+ 'rectangleTool',
158
+ 'brushTool',
159
+ 'penTool',
160
+ 'imageTool',
161
+ 'colorTokenTool',
162
+ 'frameTool',
163
+ ].includes(actualAction)
164
+ ) {
165
+ instance.cancelAction(actualAction);
141
166
  }
167
+ instance.selectNodesByKey([]);
168
+ setNodePropertiesAction(undefined);
142
169
  setSidebarActive(null, 'right');
143
170
  }}
144
171
  >
@@ -21,18 +21,20 @@ import {
21
21
  LogOut,
22
22
  ChevronDown,
23
23
  ChevronUp,
24
- Grid2X2PlusIcon,
25
- Grid2x2XIcon,
26
24
  Grid3X3Icon,
27
25
  GripIcon,
28
- CheckIcon,
29
26
  Braces,
27
+ MousePointer2,
28
+ Check,
29
+ Grid2X2Check,
30
+ Grid2X2X,
30
31
  } from 'lucide-react';
31
32
  import {
32
33
  WEAVE_GRID_TYPES,
33
34
  WeaveExportStageActionParams,
34
35
  WeaveStageGridPlugin,
35
36
  WeaveStageGridType,
37
+ WeaveUsersPointersPlugin,
36
38
  } from '@inditextech/weave-sdk';
37
39
  import { ConnectionStatus } from '../connection-status';
38
40
  import { topElementVariants } from './variants';
@@ -52,11 +54,30 @@ export function RoomHeader() {
52
54
  const room = useCollaborationRoom((state) => state.room);
53
55
 
54
56
  const [menuOpen, setMenuOpen] = React.useState(false);
57
+ const [pointersEnabled, setPointersEnabled] = React.useState(true);
55
58
  const [gridEnabled, setGridEnabled] = React.useState(true);
56
59
  const [gridType, setGridType] = React.useState<WeaveStageGridType>(
57
60
  WEAVE_GRID_TYPES.LINES
58
61
  );
59
62
 
63
+ const handleToggleUsersPointers = React.useCallback(() => {
64
+ if (!instance) return;
65
+
66
+ const userPointersPlugin =
67
+ instance.getPlugin<WeaveUsersPointersPlugin>('usersPointers');
68
+
69
+ if (userPointersPlugin && userPointersPlugin.isEnabled()) {
70
+ userPointersPlugin.disable();
71
+ setPointersEnabled(false);
72
+ return;
73
+ }
74
+ if (userPointersPlugin && !userPointersPlugin.isEnabled()) {
75
+ userPointersPlugin.enable();
76
+ setPointersEnabled(true);
77
+ return;
78
+ }
79
+ }, [instance]);
80
+
60
81
  const handleToggleGrid = React.useCallback(() => {
61
82
  if (instance && instance.isPluginEnabled('stageGrid')) {
62
83
  instance.disablePlugin('stageGrid');
@@ -180,60 +201,75 @@ export function RoomHeader() {
180
201
  </DropdownMenuLabel>
181
202
  <DropdownMenuGroup>
182
203
  <HelpDrawerTrigger />
183
- </DropdownMenuGroup>
184
- <DropdownMenuSeparator />
185
- <DropdownMenuLabel className="px-2 py-1 pt-2 text-zinc-600 text-xs">
186
- Grid
187
- </DropdownMenuLabel>
188
- <DropdownMenuItem
189
- className="text-foreground cursor-pointer hover:rounded-none"
190
- onClick={handleToggleGrid}
191
- >
192
- {!gridEnabled && (
193
- <>
194
- <Grid2X2PlusIcon /> Enable
195
- </>
196
- )}
197
- {gridEnabled && (
198
- <>
199
- <Grid2x2XIcon /> Disable
200
- </>
201
- )}
202
- </DropdownMenuItem>
203
- <DropdownMenuItem
204
- disabled={
205
- !gridEnabled ||
206
- (gridEnabled && gridType === WEAVE_GRID_TYPES.DOTS)
207
- }
208
- className="text-foreground cursor-pointer hover:rounded-none"
209
- onClick={() => {
210
- handleSetGridType(WEAVE_GRID_TYPES.DOTS);
211
- }}
212
- >
213
- <div className="w-full flex justify-between items-center">
214
- <div className="w-full flex justify-start items-center gap-2">
215
- <GripIcon size={16} /> Dots
204
+ <DropdownMenuItem
205
+ className="text-foreground cursor-pointer hover:rounded-none"
206
+ onClick={handleToggleUsersPointers}
207
+ >
208
+ <div className="w-full flex justify-between items-center gap-2">
209
+ <div className="w-full flex justify-start items-center gap-2">
210
+ <MousePointer2 size={16} />
211
+ Show users pointers
212
+ </div>
213
+ {pointersEnabled && (
214
+ <Check size={16} className="text-foreground" />
215
+ )}
216
216
  </div>
217
- {gridType === WEAVE_GRID_TYPES.DOTS && <CheckIcon />}
218
- </div>
219
- </DropdownMenuItem>
220
- <DropdownMenuItem
221
- disabled={
222
- !gridEnabled ||
223
- (gridEnabled && gridType === WEAVE_GRID_TYPES.LINES)
224
- }
225
- className="text-foreground cursor-pointer hover:rounded-none"
226
- onClick={() => {
227
- handleSetGridType(WEAVE_GRID_TYPES.LINES);
228
- }}
229
- >
230
- <div className="w-full flex justify-between items-center">
231
- <div className="w-full flex justify-start items-center gap-2">
232
- <Grid3X3Icon size={16} /> Lines
217
+ </DropdownMenuItem>
218
+ <DropdownMenuItem
219
+ className="text-foreground cursor-pointer hover:rounded-none"
220
+ onClick={handleToggleGrid}
221
+ >
222
+ <div className="w-full flex justify-between items-center gap-2">
223
+ <div className="w-full flex justify-start items-center gap-2">
224
+ {gridEnabled ? (
225
+ <>
226
+ <Grid2X2X size={16} />
227
+ Hide grid
228
+ </>
229
+ ) : (
230
+ <>
231
+ <Grid2X2Check size={16} />
232
+ Show grid
233
+ </>
234
+ )}
235
+ </div>
233
236
  </div>
234
- {gridType === WEAVE_GRID_TYPES.LINES && <CheckIcon />}
235
- </div>
236
- </DropdownMenuItem>
237
+ </DropdownMenuItem>
238
+ <DropdownMenuItem
239
+ disabled={
240
+ !gridEnabled ||
241
+ (gridEnabled && gridType === WEAVE_GRID_TYPES.DOTS)
242
+ }
243
+ className="text-foreground cursor-pointer hover:rounded-none"
244
+ onClick={() => {
245
+ handleSetGridType(WEAVE_GRID_TYPES.DOTS);
246
+ }}
247
+ >
248
+ <div className="w-full flex justify-between items-center">
249
+ <div className="w-full flex justify-start items-center gap-2">
250
+ <GripIcon size={16} /> Grid as dots
251
+ </div>
252
+ {gridType === WEAVE_GRID_TYPES.DOTS && <Check size={16} />}
253
+ </div>
254
+ </DropdownMenuItem>
255
+ <DropdownMenuItem
256
+ disabled={
257
+ !gridEnabled ||
258
+ (gridEnabled && gridType === WEAVE_GRID_TYPES.LINES)
259
+ }
260
+ className="text-foreground cursor-pointer hover:rounded-none"
261
+ onClick={() => {
262
+ handleSetGridType(WEAVE_GRID_TYPES.LINES);
263
+ }}
264
+ >
265
+ <div className="w-full flex justify-between items-center">
266
+ <div className="w-full flex justify-start items-center gap-2">
267
+ <Grid3X3Icon size={16} /> Grid as lines
268
+ </div>
269
+ {gridType === WEAVE_GRID_TYPES.LINES && <Check size={16} />}
270
+ </div>
271
+ </DropdownMenuItem>
272
+ </DropdownMenuGroup>
237
273
  <DropdownMenuSeparator />
238
274
  <DropdownMenuLabel className="px-2 py-1 pt-2 text-zinc-600 text-xs">
239
275
  Exporting
@@ -48,7 +48,7 @@ export function UploadFile() {
48
48
  ) as any;
49
49
 
50
50
  finishUploadCallback?.(
51
- `${process.env.NEXT_PUBLIC_API_ENDPOINT}/rooms/${room}/images/${imageId}`
51
+ `${process.env.NEXT_PUBLIC_API_ENDPOINT}/weavejs/rooms/${room}/images/${imageId}`
52
52
  );
53
53
  }
54
54
  },
@@ -94,6 +94,9 @@ export function UploadFile() {
94
94
  }
95
95
 
96
96
  if (showSelectFile && inputFileRef.current) {
97
+ inputFileRef.current.addEventListener('cancel', () => {
98
+ instance?.cancelAction('imageTool');
99
+ });
97
100
  inputFileRef.current.click();
98
101
  setShowSelectFileImage(false);
99
102
  }
@@ -118,7 +121,10 @@ export function UploadFile() {
118
121
  accept="image/png,image/gif,image/jpeg"
119
122
  name="image"
120
123
  ref={inputFileRef}
121
- className="hidden"
124
+ className="invisible"
125
+ onClick={() => {
126
+ inputFileRef.current.value = null;
127
+ }}
122
128
  onChange={(e) => {
123
129
  const file = e.target.files?.[0];
124
130
  if (file) {
@@ -1,10 +1,4 @@
1
- /*
2
- * SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.)
3
- *
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- @import "tailwindcss";
1
+ @import 'tailwindcss';
8
2
 
9
3
  @plugin "tailwindcss-animate";
10
4
 
@@ -186,7 +180,7 @@
186
180
  @apply w-full h-full;
187
181
  }
188
182
  body {
189
- @apply bg-background ring-0 text-foreground w-full h-full;
183
+ @apply bg-background ring-0 text-foreground w-full h-full overflow-hidden;
190
184
  }
191
185
  }
192
186
 
@@ -195,6 +189,6 @@
195
189
  @apply border-border outline-ring/50;
196
190
  }
197
191
  body {
198
- @apply bg-background ring-0 text-foreground;
192
+ @apply bg-background ring-0 text-foreground overflow-hidden;
199
193
  }
200
194
  }
@@ -44,6 +44,8 @@ export default function RootLayout({
44
44
  return (
45
45
  <html lang="en">
46
46
  <body
47
+ contentEditable="true"
48
+ suppressContentEditableWarning={true}
47
49
  className={`${questrial.variable} ${notoSans.variable} ${notoSansMono.variable} antialiased`}
48
50
  >
49
51
  <AppProviders>{children}</AppProviders>
@@ -107,15 +107,7 @@ export const RoomLayout = () => {
107
107
  className="w-full h-full flex flex-col"
108
108
  >
109
109
  <section className="w-full h-full flex">
110
- <motion.section
111
- animate={{
112
- width: sidebarLeftActive === null ? 0 : 320,
113
- opacity: sidebarLeftActive === null ? 0 : 1,
114
- }}
115
- transition={{
116
- duration: sidebarLeftActive === null ? 0.1 : 0.25,
117
- ease: 'easeInOut',
118
- }}
110
+ <section
119
111
  id="sidebar-left"
120
112
  className={cn(
121
113
  'bg-white h-full border-l border-zinc-200 shadow-md',
@@ -131,7 +123,7 @@ export const RoomLayout = () => {
131
123
  <ColorTokensLibrary key={SIDEBAR_ELEMENTS.colorTokens} />
132
124
  <ElementsTree key={SIDEBAR_ELEMENTS.nodesTree} />
133
125
  </AnimatePresence>
134
- </motion.section>
126
+ </section>
135
127
  <section
136
128
  className={cn('w-full h-full flex flex-col', {
137
129
  ['w-[calc(100%-320px)]']:
@@ -194,15 +186,7 @@ export const RoomLayout = () => {
194
186
  )}
195
187
  </section>
196
188
  </section>
197
- <motion.section
198
- animate={{
199
- width: sidebarRightActive === null ? 0 : 320,
200
- opacity: sidebarRightActive === null ? 0 : 1,
201
- }}
202
- transition={{
203
- duration: sidebarRightActive === null ? 0.1 : 0.25,
204
- ease: 'easeInOut',
205
- }}
189
+ <section
206
190
  id="sidebar-right"
207
191
  className={cn(
208
192
  'bg-white h-full border-l border-zinc-200 shadow-md',
@@ -213,7 +197,7 @@ export const RoomLayout = () => {
213
197
  )}
214
198
  >
215
199
  <NodeProperties />
216
- </motion.section>
200
+ </section>
217
201
  </section>
218
202
  </motion.div>
219
203
  </AnimatePresence>
@@ -13,7 +13,7 @@ function useCopyPaste() {
13
13
  (error: WeaveCopyPasteNodesPluginOnCopyEvent): void => {
14
14
  if (error) {
15
15
  console.error('onCopy', error);
16
- toast.error('Aan error occurred when copying to the clipboard');
16
+ toast.error('An error occurred when copying to the clipboard');
17
17
  } else {
18
18
  toast.success('Copy successful');
19
19
  }
@@ -25,7 +25,7 @@ function useCopyPaste() {
25
25
  (error: WeaveCopyPasteNodesPluginOnPasteEvent): void => {
26
26
  if (error) {
27
27
  console.error('onPaste', error);
28
- toast.error('Aan error occurred when reading from the clipboard');
28
+ toast.error('An error occurred when reading from the clipboard');
29
29
  } else {
30
30
  toast.success('Paste successful');
31
31
  }
@@ -36,8 +36,6 @@ export const NodeProperties = () => {
36
36
  );
37
37
 
38
38
  React.useEffect(() => {
39
- if (!instance) return;
40
-
41
39
  if (
42
40
  actualAction &&
43
41
  [
@@ -53,7 +51,7 @@ export const NodeProperties = () => {
53
51
  setSidebarActive(SIDEBAR_ELEMENTS.nodeProperties, 'right');
54
52
  }
55
53
 
56
- if (!actualAction) {
54
+ if (!actualAction && !node) {
57
55
  setNodePropertiesAction(undefined);
58
56
  setSidebarActive(null, 'right');
59
57
  }
@@ -61,7 +59,7 @@ export const NodeProperties = () => {
61
59
  if (node) {
62
60
  setNodePropertiesAction('update');
63
61
  }
64
- }, [actualAction, node]);
62
+ }, [actualAction, node, setSidebarActive, setNodePropertiesAction]);
65
63
 
66
64
  const nodeType = React.useMemo(() => {
67
65
  switch (node?.type) {
@@ -104,6 +102,15 @@ export const NodeProperties = () => {
104
102
  }, [actualAction]);
105
103
 
106
104
  React.useEffect(() => {
105
+ if (
106
+ nodePropertiesAction === 'create' &&
107
+ actualAction === 'selectionTool' &&
108
+ actionType === 'Unknown' &&
109
+ nodeType === 'Unknown'
110
+ ) {
111
+ setSidebarActive(null, 'right');
112
+ return;
113
+ }
107
114
  if (nodePropertiesAction === 'create' && actionType) {
108
115
  setSidebarActive(SIDEBAR_ELEMENTS.nodeProperties, 'right');
109
116
  return;
@@ -113,7 +120,14 @@ export const NodeProperties = () => {
113
120
  return;
114
121
  }
115
122
  setSidebarActive(null, 'right');
116
- }, [node, sidebarRightActive, setSidebarActive]);
123
+ }, [
124
+ actionType,
125
+ nodeType,
126
+ nodePropertiesAction,
127
+ node,
128
+ sidebarRightActive,
129
+ setSidebarActive,
130
+ ]);
117
131
 
118
132
  const title = React.useMemo(() => {
119
133
  if (nodePropertiesAction === 'create') {
@@ -136,9 +150,22 @@ export const NodeProperties = () => {
136
150
  <button
137
151
  className="cursor-pointer bg-transparent hover:bg-accent p-2"
138
152
  onClick={() => {
139
- if (instance) {
140
- instance.selectNodesByKey([]);
153
+ if (!instance) return;
154
+ if (
155
+ actualAction &&
156
+ [
157
+ 'rectangleTool',
158
+ 'brushTool',
159
+ 'penTool',
160
+ 'imageTool',
161
+ 'colorTokenTool',
162
+ 'frameTool',
163
+ ].includes(actualAction)
164
+ ) {
165
+ instance.cancelAction(actualAction);
141
166
  }
167
+ instance.selectNodesByKey([]);
168
+ setNodePropertiesAction(undefined);
142
169
  setSidebarActive(null, 'right');
143
170
  }}
144
171
  >
@@ -21,18 +21,20 @@ import {
21
21
  LogOut,
22
22
  ChevronDown,
23
23
  ChevronUp,
24
- Grid2X2PlusIcon,
25
- Grid2x2XIcon,
26
24
  Grid3X3Icon,
27
25
  GripIcon,
28
- CheckIcon,
29
26
  Braces,
27
+ MousePointer2,
28
+ Check,
29
+ Grid2X2Check,
30
+ Grid2X2X,
30
31
  } from 'lucide-react';
31
32
  import {
32
33
  WEAVE_GRID_TYPES,
33
34
  WeaveExportStageActionParams,
34
35
  WeaveStageGridPlugin,
35
36
  WeaveStageGridType,
37
+ WeaveUsersPointersPlugin,
36
38
  } from '@inditextech/weave-sdk';
37
39
  import { ConnectionStatus } from '../connection-status';
38
40
  import { topElementVariants } from './variants';
@@ -52,11 +54,30 @@ export function RoomHeader() {
52
54
  const room = useCollaborationRoom((state) => state.room);
53
55
 
54
56
  const [menuOpen, setMenuOpen] = React.useState(false);
57
+ const [pointersEnabled, setPointersEnabled] = React.useState(true);
55
58
  const [gridEnabled, setGridEnabled] = React.useState(true);
56
59
  const [gridType, setGridType] = React.useState<WeaveStageGridType>(
57
60
  WEAVE_GRID_TYPES.LINES
58
61
  );
59
62
 
63
+ const handleToggleUsersPointers = React.useCallback(() => {
64
+ if (!instance) return;
65
+
66
+ const userPointersPlugin =
67
+ instance.getPlugin<WeaveUsersPointersPlugin>('usersPointers');
68
+
69
+ if (userPointersPlugin && userPointersPlugin.isEnabled()) {
70
+ userPointersPlugin.disable();
71
+ setPointersEnabled(false);
72
+ return;
73
+ }
74
+ if (userPointersPlugin && !userPointersPlugin.isEnabled()) {
75
+ userPointersPlugin.enable();
76
+ setPointersEnabled(true);
77
+ return;
78
+ }
79
+ }, [instance]);
80
+
60
81
  const handleToggleGrid = React.useCallback(() => {
61
82
  if (instance && instance.isPluginEnabled('stageGrid')) {
62
83
  instance.disablePlugin('stageGrid');
@@ -180,60 +201,75 @@ export function RoomHeader() {
180
201
  </DropdownMenuLabel>
181
202
  <DropdownMenuGroup>
182
203
  <HelpDrawerTrigger />
183
- </DropdownMenuGroup>
184
- <DropdownMenuSeparator />
185
- <DropdownMenuLabel className="px-2 py-1 pt-2 text-zinc-600 text-xs">
186
- Grid
187
- </DropdownMenuLabel>
188
- <DropdownMenuItem
189
- className="text-foreground cursor-pointer hover:rounded-none"
190
- onClick={handleToggleGrid}
191
- >
192
- {!gridEnabled && (
193
- <>
194
- <Grid2X2PlusIcon /> Enable
195
- </>
196
- )}
197
- {gridEnabled && (
198
- <>
199
- <Grid2x2XIcon /> Disable
200
- </>
201
- )}
202
- </DropdownMenuItem>
203
- <DropdownMenuItem
204
- disabled={
205
- !gridEnabled ||
206
- (gridEnabled && gridType === WEAVE_GRID_TYPES.DOTS)
207
- }
208
- className="text-foreground cursor-pointer hover:rounded-none"
209
- onClick={() => {
210
- handleSetGridType(WEAVE_GRID_TYPES.DOTS);
211
- }}
212
- >
213
- <div className="w-full flex justify-between items-center">
214
- <div className="w-full flex justify-start items-center gap-2">
215
- <GripIcon size={16} /> Dots
204
+ <DropdownMenuItem
205
+ className="text-foreground cursor-pointer hover:rounded-none"
206
+ onClick={handleToggleUsersPointers}
207
+ >
208
+ <div className="w-full flex justify-between items-center gap-2">
209
+ <div className="w-full flex justify-start items-center gap-2">
210
+ <MousePointer2 size={16} />
211
+ Show users pointers
212
+ </div>
213
+ {pointersEnabled && (
214
+ <Check size={16} className="text-foreground" />
215
+ )}
216
216
  </div>
217
- {gridType === WEAVE_GRID_TYPES.DOTS && <CheckIcon />}
218
- </div>
219
- </DropdownMenuItem>
220
- <DropdownMenuItem
221
- disabled={
222
- !gridEnabled ||
223
- (gridEnabled && gridType === WEAVE_GRID_TYPES.LINES)
224
- }
225
- className="text-foreground cursor-pointer hover:rounded-none"
226
- onClick={() => {
227
- handleSetGridType(WEAVE_GRID_TYPES.LINES);
228
- }}
229
- >
230
- <div className="w-full flex justify-between items-center">
231
- <div className="w-full flex justify-start items-center gap-2">
232
- <Grid3X3Icon size={16} /> Lines
217
+ </DropdownMenuItem>
218
+ <DropdownMenuItem
219
+ className="text-foreground cursor-pointer hover:rounded-none"
220
+ onClick={handleToggleGrid}
221
+ >
222
+ <div className="w-full flex justify-between items-center gap-2">
223
+ <div className="w-full flex justify-start items-center gap-2">
224
+ {gridEnabled ? (
225
+ <>
226
+ <Grid2X2X size={16} />
227
+ Hide grid
228
+ </>
229
+ ) : (
230
+ <>
231
+ <Grid2X2Check size={16} />
232
+ Show grid
233
+ </>
234
+ )}
235
+ </div>
233
236
  </div>
234
- {gridType === WEAVE_GRID_TYPES.LINES && <CheckIcon />}
235
- </div>
236
- </DropdownMenuItem>
237
+ </DropdownMenuItem>
238
+ <DropdownMenuItem
239
+ disabled={
240
+ !gridEnabled ||
241
+ (gridEnabled && gridType === WEAVE_GRID_TYPES.DOTS)
242
+ }
243
+ className="text-foreground cursor-pointer hover:rounded-none"
244
+ onClick={() => {
245
+ handleSetGridType(WEAVE_GRID_TYPES.DOTS);
246
+ }}
247
+ >
248
+ <div className="w-full flex justify-between items-center">
249
+ <div className="w-full flex justify-start items-center gap-2">
250
+ <GripIcon size={16} /> Grid as dots
251
+ </div>
252
+ {gridType === WEAVE_GRID_TYPES.DOTS && <Check size={16} />}
253
+ </div>
254
+ </DropdownMenuItem>
255
+ <DropdownMenuItem
256
+ disabled={
257
+ !gridEnabled ||
258
+ (gridEnabled && gridType === WEAVE_GRID_TYPES.LINES)
259
+ }
260
+ className="text-foreground cursor-pointer hover:rounded-none"
261
+ onClick={() => {
262
+ handleSetGridType(WEAVE_GRID_TYPES.LINES);
263
+ }}
264
+ >
265
+ <div className="w-full flex justify-between items-center">
266
+ <div className="w-full flex justify-start items-center gap-2">
267
+ <Grid3X3Icon size={16} /> Grid as lines
268
+ </div>
269
+ {gridType === WEAVE_GRID_TYPES.LINES && <Check size={16} />}
270
+ </div>
271
+ </DropdownMenuItem>
272
+ </DropdownMenuGroup>
237
273
  <DropdownMenuSeparator />
238
274
  <DropdownMenuLabel className="px-2 py-1 pt-2 text-zinc-600 text-xs">
239
275
  Exporting
@@ -48,7 +48,7 @@ export function UploadFile() {
48
48
  ) as any;
49
49
 
50
50
  finishUploadCallback?.(
51
- `${process.env.NEXT_PUBLIC_API_ENDPOINT}/rooms/${room}/images/${imageId}`
51
+ `${process.env.NEXT_PUBLIC_API_ENDPOINT}/weavejs/rooms/${room}/images/${imageId}`
52
52
  );
53
53
  }
54
54
  },
@@ -94,6 +94,9 @@ export function UploadFile() {
94
94
  }
95
95
 
96
96
  if (showSelectFile && inputFileRef.current) {
97
+ inputFileRef.current.addEventListener('cancel', () => {
98
+ instance?.cancelAction('imageTool');
99
+ });
97
100
  inputFileRef.current.click();
98
101
  setShowSelectFileImage(false);
99
102
  }
@@ -118,7 +121,10 @@ export function UploadFile() {
118
121
  accept="image/png,image/gif,image/jpeg"
119
122
  name="image"
120
123
  ref={inputFileRef}
121
- className="hidden"
124
+ className="invisible"
125
+ onClick={() => {
126
+ inputFileRef.current.value = null;
127
+ }}
122
128
  onChange={(e) => {
123
129
  const file = e.target.files?.[0];
124
130
  if (file) {