Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
0d299d7
Make shared component build work in isolation
dbkr Oct 22, 2025
14dbda5
Change all the shared-component import to be the built artifact
dbkr Oct 23, 2025
c65924a
Don't randomly inhale eslint configs in parent dirs please
dbkr Oct 23, 2025
8de247d
Merge remote-tracking branch 'origin/develop' into dbkr/shared_compon…
dbkr Oct 23, 2025
d52e24e
maybe we don't need this anymore?
dbkr Oct 23, 2025
0bfe94a
maybe fix build
dbkr Oct 23, 2025
e2a1429
Maybe fix docker build
dbkr Oct 23, 2025
aff2669
More build faff
dbkr Oct 23, 2025
4c6426f
💅
dbkr Oct 23, 2025
bf3c538
💅x2
dbkr Oct 23, 2025
c9a7aa9
Merge remote-tracking branch 'origin/develop' into dbkr/shared_compon…
dbkr Oct 23, 2025
63ceeaf
Try converting the translation keys to a .d.ts file manually
dbkr Oct 23, 2025
3b530d1
add the script
dbkr Oct 23, 2025
6a6ad96
Add this back for 2nd time now I think
dbkr Oct 24, 2025
00c1884
Merge branch 'develop' into dbkr/shared_component_deps
dbkr Oct 24, 2025
f18d16f
Shouldn't need this anymore
dbkr Oct 24, 2025
9af354e
patch-package on prepare
dbkr Oct 24, 2025
3500b5a
Unused import
dbkr Oct 24, 2025
ea4a76a
Prettier compliance
dbkr Oct 24, 2025
01ba279
Only use counterpart from shared components
dbkr Oct 24, 2025
3589fd5
Import shared components CSS
dbkr Oct 27, 2025
cb568c8
Prettier
dbkr Oct 27, 2025
b1a5a30
Call the one from shared components
dbkr Oct 27, 2025
9d06120
Hopefully make tests work
dbkr Oct 29, 2025
55180e4
Merge remote-tracking branch 'origin/develop' into dbkr/shared_compon…
dbkr Oct 29, 2025
00a2eb9
wake up, comment goes before import
dbkr Oct 29, 2025
5db36a1
Merge remote-tracking branch 'origin/develop' into dbkr/shared_compon…
dbkr Oct 29, 2025
cfe6e16
Fix lint errors
dbkr Oct 29, 2025
6344ded
Fix dupe TranslationKey export
dbkr Oct 29, 2025
a7a02f0
Update compound-web to fix type error
dbkr Oct 29, 2025
137f06e
Maybe, hopefully, get the types working?
dbkr Oct 29, 2025
d47704b
Add copyright header to i18nkeys
dbkr Oct 29, 2025
cf1dcd8
prettier
dbkr Oct 29, 2025
3290048
stop running shared-component tests in EW
dbkr Oct 29, 2025
ff931e3
update snapshots
dbkr Oct 29, 2025
8b63278
More snapshots
dbkr Oct 29, 2025
7b3a6b4
Manual class update
dbkr Oct 29, 2025
6bf10ae
Avoid bundling compound bits
dbkr Oct 30, 2025
f60d4e6
ignore test util files for coverage
dbkr Oct 30, 2025
392f31d
Add !important
dbkr Oct 30, 2025
9e8deae
Another !important because css order has changed
dbkr Oct 30, 2025
dc8e934
Try adding it here to make the test files ignored
dbkr Oct 30, 2025
35daba0
More !important
dbkr Oct 30, 2025
e270151
commit yarn lock change
dbkr Oct 30, 2025
8b8faac
Add shared components coverage file
dbkr Oct 30, 2025
b035a61
Update snapshots
dbkr Oct 31, 2025
608d800
Update snapshots, attempt 2
dbkr Oct 31, 2025
7440032
Another !important
dbkr Oct 31, 2025
2453299
More snapshot updates
dbkr Oct 31, 2025
bff1e86
Merge remote-tracking branch 'origin/develop' into dbkr/shared_compon…
dbkr Oct 31, 2025
09708d3
Add test for i18n wrappers
dbkr Oct 31, 2025
84e4aa9
lint
dbkr Oct 31, 2025
bf512f8
Prettier
dbkr Oct 31, 2025
6b92de8
Hopefully run shared component tests
dbkr Oct 31, 2025
929507d
don't need this bit for non-matrix
dbkr Oct 31, 2025
4015083
install ew deps
dbkr Oct 31, 2025
aec23e1
rigfht coverage location
dbkr Oct 31, 2025
a78746a
Rename job here too
dbkr Oct 31, 2025
f87dfa2
Try different coverage filename
dbkr Nov 3, 2025
a0b89e7
Merge remote-tracking branch 'origin/develop' into dbkr/shared_compon…
dbkr Nov 3, 2025
661ba79
Fix copyrights & comment
dbkr Nov 3, 2025
4065ba4
Typo
dbkr Nov 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/workflows/shared-component-visual-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ jobs:
- name: Install element web dependencies
run: yarn install --frozen-lockfile

- name: Build Element Web resources
# Needed to prepare language files
run: "yarn build:res"

- name: Install dependencies
working-directory: packages/shared-components
run: yarn install --frozen-lockfile
Expand Down
8 changes: 0 additions & 8 deletions .github/workflows/static_analysis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ jobs:
- name: Typecheck
run: "yarn run lint:types"

- name: Build Element Web resources
# Needed to prepare language files for shared components
run: "yarn build:res"

- name: Install Shared Component Dependencies
run: "yarn --cwd packages/shared-components install"

Expand Down Expand Up @@ -91,10 +87,6 @@ jobs:
- name: Run Linter
run: "yarn run lint:js"

- name: Build Element Web resources
# Needed to prepare language files for shared components
run: "yarn build:res"

- name: Install Shared Component Deps
run: "yarn --cwd packages/shared-components install --frozen-lockfile"

Expand Down
61 changes: 57 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ env:
permissions: {}

jobs:
jest:
name: Jest
jest_ew:
name: Jest (Element Web)
runs-on: ubuntu-24.04
strategy:
fail-fast: false
Expand Down Expand Up @@ -93,13 +93,13 @@ jobs:

complete:
name: jest-tests
needs: jest
needs: jest_ew
if: always()
runs-on: ubuntu-24.04
permissions:
statuses: write
steps:
- if: needs.jest.result != 'skipped' && needs.jest.result != 'success'
- if: needs.jest_ew.result != 'skipped' && needs.jest_ew.result != 'success'
run: exit 1

- name: Skip SonarCloud in merge queue
Expand All @@ -112,3 +112,56 @@ jobs:
context: SonarCloud Code Analysis
sha: ${{ github.sha }}
target_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}

jest_sc:
name: Jest (Shared Components)
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
repository: ${{ inputs.matrix-js-sdk-sha && 'element-hq/element-web' || github.repository }}

- name: Yarn cache
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
node-version: "lts/*"
cache: "yarn"

- name: Install EW Deps
run: "yarn install"

- name: Install Shared Component Deps
working-directory: "packages/shared-components"
run: "yarn install"

- name: Jest Cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: /tmp/jest_cache
key: ${{ hashFiles('**/yarn.lock') }}

- name: Get number of CPU cores
id: cpu-cores
uses: SimenB/github-actions-cpu-cores@97ba232459a8e02ff6121db9362b09661c875ab8 # v2

- name: Run tests
working-directory: "packages/shared-components"
run: |
yarn test \
--coverage=${{ env.ENABLE_COVERAGE }} \
--ci \
--max-workers ${{ steps.cpu-cores.outputs.count }} \
--cacheDirectory /tmp/jest_cache
env:
# tell jest to use coloured output
FORCE_COLOR: true

- name: Upload Artifact
if: env.ENABLE_COVERAGE == 'true'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: coverage-sharedcomponents
path: |
packages/shared-components/coverage
!packages/shared-components/coverage/lcov-report
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ storybook-static

/packages/shared-components/node_modules
/packages/shared-components/dist
/packages/shared-components/src/i18nKeys.d.ts
2 changes: 1 addition & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const config: Config = {
// This is needed to be able to load dual CJS/ESM WASM packages e.g. rust crypto & matrix-wywiwyg
customExportConditions: ["browser", "node"],
},
testMatch: ["<rootDir>/test/**/*-test.[tj]s?(x)", "<rootDir>/packages/*/src/**/*.test.[t]s?(x)"],
testMatch: ["<rootDir>/test/**/*-test.[tj]s?(x)"],
globalSetup: "<rootDir>/test/globalSetup.ts",
setupFiles: ["jest-canvas-mock", "web-streams-polyfill/polyfill"],
setupFilesAfterEnv: ["<rootDir>/test/setupTests.ts"],
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"dependencies": {
"@babel/runtime": "^7.12.5",
"@element-hq/element-web-module-api": "1.4.1",
"@element-hq/web-shared-components": "file:packages/shared-components",
"@fontsource/inconsolata": "^5",
"@fontsource/inter": "^5",
"@formatjs/intl-segmenter": "^11.5.7",
Expand All @@ -104,7 +105,6 @@
"browserslist": "^4.23.2",
"classnames": "^2.2.6",
"commonmark": "^0.31.0",
"counterpart": "^0.18.6",
"css-tree": "^3.0.0",
"diff-dom": "^5.0.0",
"diff-match-patch": "^1.0.5",
Expand Down
1 change: 1 addition & 0 deletions packages/shared-components/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
root: true,
plugins: ["matrix-org", "eslint-plugin-react-compiler"],
extends: [
"plugin:matrix-org/babel",
Expand Down
1 change: 1 addition & 0 deletions packages/shared-components/.prettierignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
dist/
i18n/i18nKeys.d.ts
21 changes: 21 additions & 0 deletions packages/shared-components/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module.exports = {
sourceMaps: true,
presets: [
[
"@babel/preset-env",
{
include: ["@babel/plugin-transform-class-properties"],
},
],
["@babel/preset-typescript", { allowDeclareFields: true }],
"@babel/preset-react",
],
plugins: [
"@babel/plugin-proposal-export-default-from",
"@babel/plugin-transform-numeric-separator",
"@babel/plugin-transform-object-rest-spread",
"@babel/plugin-transform-optional-chaining",
"@babel/plugin-transform-nullish-coalescing-operator",
"@babel/plugin-transform-runtime",
],
};
58 changes: 58 additions & 0 deletions packages/shared-components/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
Copyright 2025 Element Creations 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 { env } from "process";

import type { Config } from "jest";

const config: Config = {
testEnvironment: "jsdom",
testEnvironmentOptions: {
url: "http://localhost/",
},
testMatch: ["<rootDir>/src/**/*.test.[tj]s?(x)"],
setupFilesAfterEnv: ["<rootDir>/src/test/setupTests.ts"],
moduleNameMapper: {
// Support CSS module
"\\.(module.css)$": "identity-obj-proxy",
"\\.(css|scss|pcss)$": "<rootDir>/__mocks__/cssMock.js",
"\\.(gif|png|ttf|woff2)$": "<rootDir>/__mocks__/imageMock.js",
"\\.svg$": "<rootDir>/__mocks__/svg.js",
"\\$webapp/i18n/languages.json": "<rootDir>/../../__mocks__/languages.json",
"^react$": "<rootDir>/node_modules/react",
"^react-dom$": "<rootDir>/node_modules/react-dom",
"waveWorker\\.min\\.js": "<rootDir>/__mocks__/empty.js",
"context-filter-polyfill": "<rootDir>/__mocks__/empty.js",
"workers/(.+)Factory": "<rootDir>/__mocks__/workerFactoryMock.js",
},
transformIgnorePatterns: [
"/node_modules/(?!(mime|matrix-js-sdk|uuid|p-retry|is-network-error|react-merge-refs)).+$",
],
collectCoverageFrom: [
"<rootDir>/src/**/*.{js,ts,tsx}",
"<rootDir>/packages/**/*.{js,ts,tsx}",
// Coverage chokes on type definition files
"!<rootDir>/src/**/*.d.ts",
],
coverageReporters: ["text-summary", "lcov"],
testResultsProcessor: "@casualbot/jest-sonar-reporter",
prettierPath: null,
moduleDirectories: ["node_modules", "./src/test/utils"],
};

// if we're running under GHA, enable the GHA reporter
if (env["GITHUB_ACTIONS"] !== undefined) {
const reporters: Config["reporters"] = [["github-actions", { silent: false }], "summary"];

// if we're running against the develop branch, also enable the slow test reporter
if (env["GITHUB_REF"] == "refs/heads/develop") {
reporters.push("<rootDir>/test/slowReporter.cjs");
}
config.reporters = reporters;
}

export default config;
28 changes: 24 additions & 4 deletions packages/shared-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
"types": "./dist/element-web-shared-components.d.ts",
"default": "./dist/element-web-shared-components.mjs"
}
},
"./dist/element-web-shared-components.css": {
"require": "./dist/element-web-shared-components.css",
"import": "./dist/element-web-shared-components.css"
}
},
"types": "dist/element-web-shared-components.d.ts",
Expand All @@ -30,8 +34,8 @@
"package.json"
],
"scripts": {
"postinstall": "patch-package",
"prepare": "vite build",
"test": "jest",
"prepare": "patch-package && yarn --cwd ../.. build:res && ts-node scripts/gatherTranslationKeys.ts && vite build",
"storybook": "storybook dev -p 6007",
"build-storybook": "storybook build",
"lint": "yarn lint:types && yarn lint:js",
Expand All @@ -42,9 +46,13 @@
"test:storybook:update": "playwright-screenshots --entrypoint yarn --with-node-modules && playwright-screenshots --entrypoint /work/node_modules/.bin/test-storybook --with-node-modules --url http://host.docker.internal:6007/ --updateSnapshot"
},
"dependencies": {
"classnames": "^2.5.1",
"counterpart": "^0.18.6",
"lodash": "^4.17.21",
"matrix-web-i18n": "^3.4.0",
"patch-package": "^8.0.1",
"counterpart": "^0.18.6"
"react-merge-refs": "^3.0.2",
"temporal-polyfill": "^0.3.0"
},
"devDependencies": {
"@storybook/addon-a11y": "^9.1.10",
Expand All @@ -53,13 +61,21 @@
"@storybook/icons": "^1.6.0",
"@storybook/react-vite": "^9.1.10",
"@storybook/test-runner": "^0.23.0",
"@testing-library/dom": "^10.4.1",
"@testing-library/react": "^16.3.0",
"@types/counterpart": "^0.18.4",
"@types/lodash": "^4.17.20",
"@types/react": "^19.2.2",
"concurrently": "^9.2.1",
"eslint": "8",
"eslint-plugin-matrix-org": "^3.0.0",
"eslint-plugin-storybook": "^10.0.0",
"jest": "^30.2.0",
"jest-image-snapshot": "^6.5.1",
"patch-package": "^8.0.1",
"prettier": "^3.6.2",
"storybook": "^9.1.10",
"ts-node": "^10.9.2",
"typescript": "^5.9.3",
"vite": "^7.1.9",
"vite-plugin-dts": "^4.5.4",
Expand All @@ -68,5 +84,9 @@
"engines": {
"node": ">=20.0.0"
},
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
"peerDependencies": {
"@vector-im/compound-design-tokens": "^6.0.0",
"@vector-im/compound-web": "^8.2.5"
}
}
61 changes: 61 additions & 0 deletions packages/shared-components/scripts/gatherTranslationKeys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
Copyright 2025 Element Creations 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.
*/

// Gathers all the translation keys from element-web's en_EN.json into a TypeScript type definition file
// that exports a type `TranslationKey` which is a union of all supported translation keys.
// This prevents having to import the json file and make typescript do the work as this results in vite-dts
// generating an import to the json file in the .d.ts which doesn't work at runtime: this way, the type
// gets put into the bundle.
// XXX: It should *not* be in the 'src' directory, being a generated file, but if it isn't then the type
// bundler won't bundle the types and will leave the file as a relative import, which will break.

import * as fs from "fs";
import * as path from "path";

const i18nStringsPath = path.resolve(__dirname, "../../../src/i18n/strings/en_EN.json");
const outPath = path.resolve(__dirname, "../src/i18nKeys.d.ts");

function gatherKeys(obj: any, prefix: string[] = []): string[] {
if (typeof obj !== "object" || obj === null) return [];
let keys: string[] = [];
for (const key of Object.keys(obj)) {
const value = obj[key];

// add the path (for both leaves and intermediates as then we include plurals)
keys.push([...prefix, key].join("|"));
if (typeof value === "object" && value !== null) {
// If the value is an object, recurse
keys = keys.concat(gatherKeys(value, [...prefix, key]));
}
}
return keys;
}

function main() {
const json = JSON.parse(fs.readFileSync(i18nStringsPath, "utf8"));
const keys = gatherKeys(json);
const typeDef =
"/*\n" +
" * Copyright 2025 Element Creations Ltd.\n" +
" *\n" +
" * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\n" +
" * Please see LICENSE files in the repository root for full details.\n" +
" */\n" +
"\n" +
"// This file is auto-generated by gatherTranslationKeys.ts\n" +
"// Do not edit manually.\n\n" +
"export type TranslationKey =\n" +
keys.map((k) => ` | \"${k}\"`).join("\n") +
";\n";
fs.mkdirSync(path.dirname(outPath), { recursive: true });
fs.writeFileSync(outPath, typeDef, "utf8");
console.log(`Wrote ${keys.length} keys to ${outPath}`);
}

if (require.main === module) {
main();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

.audioPlayer {
padding: var(--cpd-space-4x) var(--cpd-space-3x) var(--cpd-space-3x) var(--cpd-space-3x);
padding: var(--cpd-space-4x) var(--cpd-space-3x) var(--cpd-space-3x) var(--cpd-space-3x) !important;
}

.mediaInfo {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing

exports[`AudioPlayerView renders the audio player in default state 1`] = `
<div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing

exports[`Clock renders the clock 1`] = `
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
*/

.button {
border-radius: 32px;
background-color: var(--cpd-color-bg-subtle-primary);
border-radius: 32px !important;
background-color: var(--cpd-color-bg-subtle-primary) !important;
}
Loading
Loading