Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
98 changes: 57 additions & 41 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ Thank you for considering contributing to Symfony UX!
Symfony UX is an open source, community-driven project, and we are happy to receive contributions from the community!

> [!TIP]
> It's a good idea to read the [Symfony's Contribution Guide](https://symfony.com/doc/current/contributing/index.html) first, even if not all of it applies to Symfony UX and should be adapted to this project (e.g.: Symfony UX has only one base branch, `2.x`).
> It's a good idea to read the [Symfony's Contribution Guide](https://symfony.com/doc/current/contributing/index.html) first

## Reporting an issue

If you either find a bug, have a feature request, or need help/have a question, please [open an issue](https://github.com/symfony/ux/issues/new/choose).
If you find a bug, have a feature request, or need help/have a question, please [open an issue](https://github.com/symfony/ux/issues/new/choose).

Please provide as much information as possible,
and remember to follow our [Code of Conduct](https://symfony.com/doc/current/contributing/code_of_conduct/index.html)
as well, to ensure a friendly environment for all contributors.
to ensure a friendly environment for all contributors.

## Contributing to the code and documentation

Expand All @@ -22,11 +22,15 @@ Thanks for your interest in contributing to Symfony UX! Here are some guidelines
### Forking the repository

To contribute to Symfony UX, you need to [fork the **symfony/ux** repository](https://github.com/symfony/ux/fork) on GitHub.
This will give you a copy of the code under your GitHub user account, read [the documentation "How to fork a repository"](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo).
This will give you a copy of the code under your GitHub user account. Read [the documentation "How to fork a repository"](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo).

After forking the repository, you can clone it to your local machine:

```shell
# With GitHub CLI https://cli.github.com/
$ gh repo clone <USERNAME>/symfony-ux symfony-ux
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The repository name should be 'ux' not 'symfony-ux'. The correct command should be gh repo clone <USERNAME>/ux symfony-ux to clone the fork of the symfony/ux repository.

Suggested change
$ gh repo clone <USERNAME>/symfony-ux symfony-ux
$ gh repo clone <USERNAME>/ux symfony-ux

Copilot uses AI. Check for mistakes.

# Using SSH
$ git clone git@github.com:<USERNAME>/symfony-ux.git symfony-ux
$ cd symfony-ux
# Add the upstream repository, to keep your fork up-to-date
Expand All @@ -37,16 +41,19 @@ $ git remote add upstream git@github.com:symfony/ux.git

To set up the development environment, you need the following tools:

- [PHP](https://www.php.net/downloads.php) 8.1 or higher
- [Composer](https://getcomposer.org/download/)
- [Node.js](https://nodejs.org/en/download/package-manager) 22.18 or higher
- [Corepack](https://github.com/nodejs/corepack)
- [PNPM](https://pnpm.io/) 10.13 or higher
- **[PHP](https://www.php.net/downloads.php) 8.1 or higher** - Required for running Symfony components
- **[Composer](https://getcomposer.org/download/)** - PHP dependency manager
- **[Node.js](https://nodejs.org/en/download/package-manager) 22.18 or higher** - Required for asset compilation
- **[Corepack](https://github.com/nodejs/corepack)** - Package manager manager (comes with Node.js 16+)
- **[PNPM](https://pnpm.io/) 10.16.1 or higher** - JavaScript package manager (installed via Corepack)
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The minimum version specified here (10.16.1) is more specific than the version mentioned earlier in the original documentation (10.13). This creates an inconsistency. Consider clarifying if 10.16.1 is the actual required minimum version, and if so, this should be consistent throughout the documentation.

Suggested change
- **[PNPM](https://pnpm.io/) 10.16.1 or higher** - JavaScript package manager (installed via Corepack)
- **[PNPM](https://pnpm.io/) 10.13 or higher** - JavaScript package manager (installed via Corepack)

Copilot uses AI. Check for mistakes.

With these tools installed, you can install the project dependencies:

```shell
# Install root PHP dependencies
$ composer install

# Enable PNPM through Corepack, and install JavaScript dependencies
$ corepack enable && pnpm install
```

Expand All @@ -73,33 +80,36 @@ runnable with `php vendor/bin/simple-phpunit`.
### Working with assets

Assets are specific to each Symfony UX package:
- They are located in the `assets/` directory of each package, and can be either TypeScript or CSS files, respectively compiled through Rollup and PostCSS,
- Assets are mentioned in the `package.json` file of each package,
- Assets **must be** compiled before committing changes,
- Assets **must be** compatible with the [Symfony AssetMapper](https://symfony.com/doc/current/frontend/asset_mapper.html) and [Symfony Webpack Encore](https://symfony.com/doc/current/frontend/encore/index.html).
- They are located in the `assets/` directory of each package and can be either TypeScript or CSS files, all compiled through [tsup](https://github.com/egoist/tsup)
- Assets are mentioned in the `package.json` file of each package
- Assets **must be** compiled before committing changes
- Assets **must be** compatible with the [Symfony AssetMapper](https://symfony.com/doc/current/frontend/asset_mapper.html) and [Symfony Webpack Encore](https://symfony.com/doc/current/frontend/encore/index.html)

To help you with assets, you can run the following commands in a specific package directory (e.g., `src/Map/assets/`):
- `pnpm run build`: build (compile) assets from the package,
- `pnpm run watch`: watch for modifications and rebuild assets from the package,
- `pnpm run test`: run the tests from the package,
- `pnpm run test:unit`: run the Unit tests from the package,
- `pnpm run test:browser`: run the Browser tests from the package, in a headless browser
- `pnpm run test:browser:ui`: run the Browser tests from the package in interactive mode, allowing you to see the tests running in a browser window and debug them if needed
- `pnpm run check`: run the formatter, linter, and sort imports, and fails if any modifications
- `pnpm run check --write`: run the formatter, linter, imports sorting, and write modifications
- `pnpm run build`: build (compile) assets from the package
- `pnpm run watch`: watch for modifications and rebuild assets from the package
- `pnpm run test`: run the tests from the package
- `pnpm run test:unit`: run the unit tests from the package
- `pnpm run test:browser`: run the browser tests from the package in a headless browser
- `pnpm run test:browser:ui`: run the browser tests from the package in interactive mode, allowing you to see the tests running in a browser window and debug them if needed
- `pnpm run check`: run the formatter, linter, and sort imports, and fail if any modifications are needed
- `pnpm run check --write`: run the formatter, linter, and import sorting, and write modifications

Thanks to [PNPM Workspaces](https://pnpm.io/workspaces), you can also run these commands from the root directory of the project:
- `pnpm run build`: build (compile) assets from **all** packages,
- `pnpm run test`: run the tests from **all** packages,
- `pnpm run test:unit`: run the Unit tests from **all** packages,
- `pnpm run test:browser`: run the Browser tests from **all** packages, in a headless browser
- `pnpm run check`: run the formatter, linter, and sort imports for **all** packages, and fails if any modifications
- `pnpm run check --write`: run the formatter, linter, imports sorting for **all** packages, and write modifications
- `pnpm run build`: build (compile) assets from **all** packages
- `pnpm run test`: run the tests from **all** packages
- `pnpm run test:unit`: run the unit tests from **all** packages
- `pnpm run test:browser`: run the browser tests from **all** packages in a headless browser
- `pnpm run check`: run the formatter, linter, and sort imports for **all** packages, and fail if any modifications are needed
- `pnpm run check --write`: run the formatter, linter, and import sorting for **all** packages, and write modifications

> [!IMPORTANT]
> Always run `pnpm run build` before committing your changes to ensure assets are properly compiled.

#### Working with Unit tests

We use [Vitest](https://vitest.dev/) for unit testing of the assets,
and tests files are located in the `assets/test/unit/` directory of each UX package,
and test files are located in the `assets/test/unit/` directory of each UX package,
for example: `src/Vue/assets/test/unit/render_controller.test.ts`.

**Running tests:**
Expand All @@ -109,37 +119,43 @@ for example: `src/Vue/assets/test/unit/render_controller.test.ts`.
- `pnpm run test:unit`: runs the unit tests for the package

> [!IMPORTANT]
> The command `pnpm run test:unit` ensure that each possible combination of dependencies is tested
> The command `pnpm run test:unit` ensures that each possible combination of dependencies is tested
> (e.g., `"chart.js": "^3.4.1 || ^4.0"` for UX Chartjs).
> Thus it may take some time to run, and it may be not recommended to use watch mode.
> Thus it may take some time to run, and **we don't recommend using watch mode**.

#### Working with End-to-End (E2E) tests

> [!NOTE]
> E2E tests simulate real user interactions in a browser, to ensure that the
> UX packages work as expected in a real-world scenario.

Symfony UX use [Playwright](https://playwright.dev/) for browser automation and testing,
Symfony UX uses [Playwright](https://playwright.dev/) for browser automation and testing,
and a dedicated Symfony application located in the [`apps/e2e/`](./apps/e2e/) directory,
which contains many examples of Symfony UX packages usage.
which contains many examples of Symfony UX package usages.

Tests files are located in the `assets/test/browser/` directory of each UX package,
Test files are located in the `assets/test/browser/` directory of each UX package,
for example: `src/Vue/assets/test/browser/vue.test.ts`.

**Setup:**
1. Ensure to have followed the steps in the [Setting up the development environment](#setting-up-the-development-environment) section
2. Read and follow the instructions in the [`apps/e2e/README.md`](./apps/e2e/README.md) file,
1. Ensure you have followed the steps in the [Setting up the development environment](#setting-up-the-development-environment) section
2. Read and follow the instructions in the [`apps/e2e/README.md`](./apps/e2e/README.md) file

**Running tests:**
- At the project's root, you can run the following commands:
- `pnpm run test:browser`: runs the browser tests for **all** UX packages, using a headless browser
- `pnpm run test:browser`: runs the browser tests for **all** UX packages using a headless browser
- Inside the `assets/` directory of each UX package, you can run the following commands:
- `pnpm run test:browser`: runs browser tests for the package, using a headless browser
- `pnpm run test:browser`: runs browser tests for the package using a headless browser
- `pnpm run test:browser:ui`: runs the browser tests in interactive mode, allowing you to see the tests running in a browser window and debug them if needed

> [!IMPORTANT]
> Due to their nature, E2E tests may be slower to run than unit tests.
> During the development, we recommend to run `pnpm run test:browser` or `pnpm run test:browser:ui` for a specific UX package.
> During development, we recommend running `pnpm run test:browser` or `pnpm run test:browser:ui` for a specific UX package.

> [!TIP]
> If tests are failing locally, try running them in headed mode to see what's happening:
> ```shell
> $ pnpm run test:browser:ui
> ```

### Working on documentation

Expand All @@ -156,17 +172,17 @@ command from the root directory of the project:
docker run --rm -it -e DOCS_DIR='/docs' -v ${PWD}:/docs oskarstark/doctor-rst -vvv
```

## Useful Git commands
## Useful commands

1. To keep your fork up-to-date with the upstream repository and `2.x` branch, you can run the following commands:
To keep your fork up-to-date with the upstream repository and `2.x` branch:
```shell
$ git checkout 2.x && \
git fetch upstream && \
git reset --hard upstream/2.x && \
git push origin 2.x
```

2. To rebase your branch on top of the `2.x` branch, you can run the following commands:
To rebase your branch on top of the `2.x` branch:
```shell
$ git checkout my-feature-branch && \
git rebase upstream/2.x && \
Expand Down
76 changes: 76 additions & 0 deletions src/Toolkit/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Contributing

Due to its nature, the Symfony UX Toolkit requires a specific setup to develop and test it properly. Please follow the instructions below to set up your development environment.

## Setting up the development environment

First, ensure you have followed the [Symfony UX's Contribution Guide](https://github.com/symfony/ux/blob/2.x/CONTRIBUTING.md) to set up your fork of the main repository, install dependencies, etc.

Then, install the UX Toolkit dependencies:
```shell
# src/Toolkit
composer install
```

## Previewing kits

Currently, kits can only be previewed through the Symfony UX Website. Installation instructions can be found in the [Symfony UX Website's `README.md`](https://github.com/symfony/ux/tree/2.x/ux.symfony.com).

Then, run the following commands from the `ux.symfony.com/` directory:
```shell
# Link local UX packages
php ../link

# Run the local web server
symfony serve -d
```

When the server is running, you can access:
- The UX Toolkit homepage at https://127.0.0.1:9044/toolkit
- The list of available kits at https://127.0.0.1:9044/toolkit#kits
- A dedicated section for each kit, e.g., https://127.0.0.1:9044/toolkit/kits/shadcn for the Shadcn UI Kit

## Kit structure

A kit is composed of several recipes, each providing Twig components, styles, and JavaScript.

1. Each kit is located in the `src/Toolkit/kits/` directory
2. Each kit has its own directory named after the kit, e.g., `shadcn/` for the Shadcn UI Kit
3. Each kit directory contains:
- An `INSTALL.md` file with installation instructions (used by the UX Website)
- A `manifest.json` file containing metadata about the kit: its name, description, license, homepage, etc.
- A folder for each recipe provided by the kit, e.g., `button/` for the Button recipe
4. Each recipe directory contains:
- A `manifest.json` file containing metadata about the recipe: its type, name, description, files to copy, dependencies, etc.
- An `EXAMPLES.md` file with usage examples (used by the UX Website)
- Based on the "files to copy" setting, the kit may contain subdirectories such as:
- `templates/components/` for Twig components
- `assets/controllers/` for Stimulus controllers
- The "files to copy" structure is flexible, but we recommend following the above conventions for consistency across kits and Symfony apps

## Working with kits

After setting up your development environment and the UX Website locally, you can start modifying the kits and testing them.

Adding new recipes or modifying existing ones will be automatically reflected in the UX Website, thanks to the local linking done with the `php link` command.
You can then preview your changes by navigating to the relevant sections in the UX Website.

### Running tests & snapshots

Tests use snapshots to ensure that the kits and their recipes work as expected and to prevent regressions.

Snapshots are created from all Twig code examples provided in each recipe's `EXAMPLES.md` file. The Twig code examples are rendered in an isolated environment.

The rendered output is then compared to stored snapshots to ensure that the kit's recipes work as expected.

To update the snapshots, run the following command from the `src/Toolkit/` directory:
```shell
# Remove existing snapshots (may be useful if some Twig code examples were removed)
rm -fr tests/Functional/__snapshots__

# Run tests and update snapshots
php vendor/bin/simple-phpunit -d --update-snapshots

# Add the updated snapshots to git
git add tests/Functional/__snapshots__
```
Loading