Files
Florian Duros 85aca65a81 Room list: drag and drop rooms into sections (#33366)
* chore: add dnd kit deps

* chore: patch dnd kit to fix ts error

* feat(sc): add drag-and-drop to room list item and wrapper

* feat(sc): make the room list header a droppable element

* feat(sc): add dnd to room list view

* feat(tags): can tag room as CHAT

* feat(vm): implement `changeRoomSection`

* feat(sc): disable dragging in flat list

* fix: disable keyboard navigation when dragging element

* test(sc): update snapshots

* test(sc): add dnd test

* test(e2e): add e2e tests for room drag and drop

* test(vm): add tests for changeRoomSection

* fix: remove focus visible when dropping with the mouse

* test(playwright): update existing screenshots

* chore(sc): move numbers out of main build

The Ew RecorderWorklet imports shared component bundle. However if the
bundle uses some deps using document/window which, the worklet will not
work.

The solution is to put the used functions into a separate bundle.

* doc(sc): add subpath import into README

* doc: typo barrel/bundle

* test: improve test expect

* refactor: add utils to section tag

* fix: incorrect check in tagRoom

* fix: add doc about dndkit tunning
2026-05-13 09:06:22 +00:00

104 lines
4.3 KiB
TypeScript

/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*
*/
import { existsSync, readFileSync, renameSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { defineConfig, esmExternalRequirePlugin, type Plugin } from "vite";
import dts from "unplugin-dts/vite";
const __dirname = dirname(fileURLToPath(import.meta.url));
const cssLayerOrder = "@layer compound-tokens, compound-web, shared-components, app-web;";
const sharedComponentsLayer = "shared-components";
const cssAssetFileName = "element-web-shared-components.css";
function layerCssAssets(): Plugin {
return {
name: "element-web-shared-components-css-layer",
// Rename + layer-wrap the emitted CSS file. With multi-entry lib mode,
// vite/rolldown derives CSS filenames from the unscoped package name (dropping
// the `element-` prefix), so we rename on disk to keep the path stable for
// consumers importing `@element-hq/web-shared-components/.../*.css`.
writeBundle(options): void {
const outDir = options.dir ?? resolve(__dirname, "dist");
const expectedPath = resolve(outDir, cssAssetFileName);
const renamedFromPath = resolve(outDir, "web-shared-components.css");
if (existsSync(renamedFromPath)) {
renameSync(renamedFromPath, expectedPath);
}
// No CSS emitted in this build (e.g. storybook's vite build doesn't produce
// the library CSS bundle), or already renamed and layered on a prior pass.
if (!existsSync(expectedPath)) return;
const source = readFileSync(expectedPath, "utf-8");
if (source.startsWith(cssLayerOrder)) return;
writeFileSync(expectedPath, `${cssLayerOrder}\n@layer ${sharedComponentsLayer} {\n${source}\n}\n`);
},
};
}
export default defineConfig({
build: {
lib: {
// Two entries: the main bundle and a standalone `numbers` utility that callers
// running outside the browser DOM (e.g. AudioWorkletGlobalScope) can import without
// pulling in the rest of the package — which transitively loads dnd-kit and
// other window/document-dependent code.
entry: {
"element-web-shared-components": resolve(__dirname, "src/index.ts"),
"numbers": resolve(__dirname, "src/core/utils/numbers.ts"),
},
name: "Element Web Shared Components",
// Multi-entry mode needs both formats explicit; UMD doesn't support multi-entry
// (single global), so we ship ES + CJS and use the `.umd.cjs` extension for CJS
// to keep the existing package.json `require` paths working.
formats: ["es", "cjs"],
fileName: (format, entryName) => `${entryName}.${format === "es" ? "js" : "umd.cjs"}`,
},
outDir: "dist",
rolldownOptions: {
// make sure to externalize deps that shouldn't be bundled
// into your library
external: [
"@vector-im/compound-design-tokens",
"@vector-im/compound-web",
"react-virtuoso",
"react-resizable-panels",
],
plugins: [
esmExternalRequirePlugin({
external: ["react", "react-dom"],
}),
],
output: {
// Provide global variables to use in the UMD build
// for externalized deps
globals: {
"react": "react",
"@vector-im/compound-design-tokens": "compoundDesignTokens",
"@vector-im/compound-web": "compoundWeb",
"react-virtuoso": "reactVirtuoso",
"react-resizable-panels": "reactResizablePanels",
},
},
},
},
plugins: [
layerCssAssets(),
dts({
bundleTypes: true,
include: ["src/**/*.{ts,tsx}"],
exclude: ["src/**/*.test.{ts,tsx}", "src/**/*.stories.{ts,tsx}"],
copyDtsFiles: false,
}),
],
});