Files
ThreadNet-Web/packages/shared-components/vite.config.ts
T
a4f63cdd22 Emoji picker to shared components (#34337)
* Exploration of a virtuoso-powered emoji picker

moved to shared components

Fable generated

* fix pnpm lock

* format & fix some lint issues

* wrong import

* fix lint warning

* Fix off-by-one

and remove manual overflow adjustment: let's leave the default unless
it turns out to be necessary. Emoji should not take that long to load.

* Convert to functional component

* WIP: change to one big virtuoso scroller

* Change to use virtuoso's own onRangeChanged

and santitise category data and how it's passed around

* Convert Tabs to functional component

and put the focusing behaviour back with it just keeping track of
refs by itself.

* Absorb two line config file into main component

* Actually add the config to the main file

* Convert emoji to functional

Also make selected always defined and use useCallback.

* QuickReactions to functional component

* Non-default exports & doc

* Search to functional component

* Well it seems to work just fine now

* Use ref prop

* fix lockfile AGAIN

* lint

* Remove default export

* Remove some mx_ classnames and fix the inputRef

to make the arrow keys in the search box work (well, work as much as
they ever did).

* Remove last of the mx_ id / classnames

(except the one in the test)

* Use useMemo to memoize

* No need to export props interface (I think?)

and fix comment now we don't do the mutation stuff anymore

* Fix test

* Fix axe violations & add screenshots

* Avoid comparing dom snapshots in test

* Allow more before or after, just compare order of the ones present in both.

* Switch existing usages to new emoji picker

and kill the old one with fire

* Unused stuff

* Remove i18n strings

* Fix some tests

* Update screenshots

* Fix test

by removing the last of the weird memoized-but-mutated data structure

* Move the string somewhere more sensible than 'a11y'

* i18n lint

* Give the emojis IDs so aria-activedescendant works

* Fix more tests

* Add a small wrapper emoji picker component

This lets us easily memoize the recent emojis when the emoji picker is opened.
Also it saves a bit of boilerplate.

* Remove old emojipicker css

* Typos

Co-authored-by: David Langley <davidl@element.io>

* Use compound constants

* Rethemendex

* Use catalog version for emojibase

* Add comments

* More comments

* Fix comment

* More comments

* more comments (and make them uniform)

* More comments

* Fix pnpm lock again

* Another comment

* Apply button types to new version

* Add comment

* Disable screenshot

as per comment

---------

Co-authored-by: Will Hunt <2072976+Half-Shot@users.noreply.github.com>
Co-authored-by: David Langley <davidl@element.io>
2026-08-05 13:44:35 +00:00

113 lines
4.8 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 { fileURLToPath } from "node:url";
import { defineConfig, esmExternalRequirePlugin, type Plugin } from "vite";
import dts from "unplugin-dts/vite";
import react from "@vitejs/plugin-react";
import path from "node:path";
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 ?? fileURLToPath(import.meta.resolve("./dist"));
const expectedPath = path.resolve(outDir, cssAssetFileName);
const renamedFromPath = path.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": fileURLToPath(import.meta.resolve("./src/index.ts")),
"numbers": fileURLToPath(import.meta.resolve("./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: [
"@matrix-org/emojibase-bindings",
"@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",
"@matrix-org/emojibase-bindings": "matrixEmojibaseBindings",
"@vector-im/compound-design-tokens": "compoundDesignTokens",
"@vector-im/compound-web": "compoundWeb",
"react-virtuoso": "reactVirtuoso",
"react-resizable-panels": "reactResizablePanels",
},
},
},
},
plugins: [
react(),
layerCssAssets(),
dts({
bundleTypes: {
invokeOptions: {
localBuild: !!process.env.CI,
// oxlint-disable-next-line unicorn/prefer-module
typescriptCompilerFolder: path.resolve(require.resolve("@typescript/old"), "../.."),
},
},
include: ["src/**/*.{ts,tsx}"],
exclude: ["src/**/*.test.{ts,tsx}", "src/**/*.stories.{ts,tsx}"],
copyDtsFiles: false,
}),
],
});