Drop Biome.js for oxfmt and oxlint

This commit is contained in:
Hugo Alliaume
2026-02-03 22:43:43 +01:00
parent d694075182
commit dded1264a4
211 changed files with 2651 additions and 2347 deletions

View File

@@ -2,17 +2,17 @@ rules:
american_english: ~
argument_variable_must_match_type: ~
avoid_repetetive_words: ~
# be_kind_to_newcomers: ~
# be_kind_to_newcomers: ~
blank_line_after_anchor: ~
# blank_line_after_colon: ~
# blank_line_after_colon: ~
blank_line_after_directive: ~
# blank_line_after_filepath_in_code_block: ~
# blank_line_after_filepath_in_php_code_block: ~
# blank_line_after_filepath_in_twig_code_block: ~
# blank_line_after_filepath_in_xml_code_block: ~
# blank_line_after_filepath_in_yaml_code_block: ~
# blank_line_after_filepath_in_code_block: ~
# blank_line_after_filepath_in_php_code_block: ~
# blank_line_after_filepath_in_twig_code_block: ~
# blank_line_after_filepath_in_xml_code_block: ~
# blank_line_after_filepath_in_yaml_code_block: ~
blank_line_before_directive: ~
# composer_dev_option_at_the_end: ~
# composer_dev_option_at_the_end: ~
composer_dev_option_not_at_the_end: ~
correct_code_block_directive_based_on_the_content: ~
deprecated_directive_major_version:
@@ -27,10 +27,10 @@ rules:
ensure_order_of_code_blocks_in_configuration_block: ~
extend_abstract_admin: ~
extend_abstract_controller: ~
# extend_controller: ~
# extend_controller: ~
extension_xlf_instead_of_xliff: ~
# filename_uses_dashes_only: ~
# filename_uses_underscores_only: ~
# filename_uses_dashes_only: ~
# filename_uses_underscores_only: ~
final_admin_classes: ~
final_admin_extension_classes: ~
forbidden_directives:
@@ -38,7 +38,7 @@ rules:
- '.. index::'
indention: ~
kernel_instead_of_app_kernel: ~
# line_length: ~
# line_length: ~
lowercase_as_in_use_statements: ~
max_blank_lines:
max: 2
@@ -46,7 +46,7 @@ rules:
no_admin_yaml: ~
no_app_bundle: ~
no_app_console: ~
# no_bash_prompt: ~
# no_bash_prompt: ~
no_blank_line_after_filepath_in_code_block: ~
no_blank_line_after_filepath_in_php_code_block: ~
no_blank_line_after_filepath_in_twig_code_block: ~
@@ -56,25 +56,25 @@ rules:
no_composer_phar: ~
no_composer_req: ~
no_config_yaml: ~
# no_contraction: ~
# no_contraction: ~
no_directive_after_shorthand: ~
no_explicit_use_of_code_block_php: ~
no_inheritdoc_in_code_examples: ~
no_merge_conflict: ~
no_namespace_after_use_statements: ~
no_php_open_tag_in_code_block_php_directive: ~
# no_php_prefix_before_bin_console: ~
# no_php_prefix_before_composer: ~
# no_space_before_self_xml_closing_tag: ~
# no_php_prefix_before_bin_console: ~
# no_php_prefix_before_composer: ~
# no_space_before_self_xml_closing_tag: ~
only_backslashes_in_namespace_in_php_code_block: ~
only_backslashes_in_use_statements_in_php_code_block: ~
ordered_use_statements: ~
# php_open_tag_in_code_block_php_directive: ~
# php_open_tag_in_code_block_php_directive: ~
php_prefix_before_bin_console: ~
replace_code_block_types: ~
replacement: ~
short_array_syntax: ~
# space_before_self_xml_closing_tag: ~
# space_before_self_xml_closing_tag: ~
space_between_label_and_link_in_doc: ~
space_between_label_and_link_in_ref: ~
string_replacement: ~
@@ -83,7 +83,7 @@ rules:
unused_links: ~
use_deprecated_directive_instead_of_versionadded: ~
use_https_xsd_urls: ~
# use_named_constructor_without_new_keyword_rule: ~
# use_named_constructor_without_new_keyword_rule: ~
valid_inline_highlighted_namespaces: ~
valid_use_statements: ~
versionadded_directive_major_version:

View File

@@ -4,7 +4,6 @@ about: Report a bug in existing features
title: ''
labels: ['Bug']
assignees: ''
---
<!-- ======================== Guidelines ============================
@@ -17,7 +16,7 @@ Describe Your Problem 🎯
- Clearly explain the problem you're facing;
- Describe what you expected to happen versus what actually occurred;
- List the steps to reproduce the bug.
Provide Detailed Information 📋
- Share relevant details: Component version, errors, screenshots;
- If possible, provide a minimal reproducer in a GitHub repository.
@@ -27,6 +26,3 @@ Be Kind and Respectful 🙂
- Remember that this is a volunteer-driven project.
============================= Guidelines ======================== -->

View File

@@ -4,5 +4,4 @@ about: Suggest ideas for new features or enhancements
title: ''
labels: ['RFC']
assignees: ''
---

View File

@@ -4,6 +4,4 @@ about: Help us improve the documentation!
title: ''
labels: 'docs'
assignees: ''
---

View File

@@ -1,5 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: 🛟 Support / help
url: https://ux.symfony.com/support
about: Ask your questions about Symfony UX
- name: 🛟 Support / help
url: https://ux.symfony.com/support
about: Ask your questions about Symfony UX

View File

@@ -1,11 +1,11 @@
| Q | A
| -------------- | ---
| Bug fix? | yes/no
| New feature? | yes/no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | yes/no <!-- if yes, also update UPGRADE-*.md and src/**/CHANGELOG.md -->
| Documentation? | yes/no <!-- required for new features, or documentation updates -->
| Issues | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License | MIT
| Q | A |
| -------------- | ------------------------------------------------------------------------------------------------------------------------ |
| Bug fix? | yes/no |
| New feature? | yes/no <!-- please update src/**/CHANGELOG.md files --> |
| Deprecations? | yes/no <!-- if yes, also update UPGRADE-*.md and src/**/CHANGELOG.md --> |
| Documentation? | yes/no <!-- required for new features, or documentation updates --> |
| Issues | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead --> |
| License | MIT |
<!--
Replace this notice by a description of your feature/bugfix.

View File

@@ -55,7 +55,7 @@ function computeDiffPercent(from, to) {
return 0;
}
return Math.round((from - to) / from * -100);
return Math.round(((from - to) / from) * -100);
}
/**
@@ -90,56 +90,63 @@ export function main() {
* }>
* }>}
*/
const packagesFiles = [...new Set([...Object.keys(pr), ...Object.keys(base)])]
.sort()
.reduce((acc, file) => {
const beforeSize = base[file]?.size || 0;
const afterSize = pr[file]?.size || 0;
const beforeSizeGz = base[file]?.size_gz || 0;
const afterSizeGz = pr[file]?.size_gz || 0;
const packagesFiles = [...new Set([...Object.keys(pr), ...Object.keys(base)])].sort().reduce((acc, file) => {
const beforeSize = base[file]?.size || 0;
const afterSize = pr[file]?.size || 0;
const beforeSizeGz = base[file]?.size_gz || 0;
const afterSizeGz = pr[file]?.size_gz || 0;
if (beforeSize !== afterSize) {
const isBridge = file.includes('src/Bridge'); // we assume that's enough for now
const packageName = file.split('/')[1];
const bridgeName = isBridge ? file.split('/')[4] : '';
const key = isBridge ? `${packageName} (Bridge ${bridgeName})` : packageName;
if (!acc.has(key)) {
acc.set(key, {
meta: {
packageName,
bridgeName,
url: isBridge ? `${repoUrl}/tree/${process.env.HEAD_REF}/src/${packageName}/src/Bridge/${bridgeName}/assets/dist` : `${repoUrl}/tree/${process.env.HEAD_REF}/src/${packageName}/assets/dist`,
}, files: new Set(),
});
}
const added = !base[file] && pr[file];
const removed = base[file] && !pr[file];
acc.get(key).files.add({
state: added ? 'added' : (removed ? 'removed' : 'changed'),
before: { size: beforeSize, sizeGz: beforeSizeGz },
after: { size: afterSize, sizeGz: afterSizeGz },
diffPercent: {
size: removed ? -100 : (added ? 100 : computeDiffPercent(beforeSize, afterSize)),
sizeGz: removed ? -100 : (added ? 100 : computeDiffPercent(beforeSizeGz, afterSizeGz)),
},
if (beforeSize !== afterSize) {
const isBridge = file.includes('src/Bridge'); // we assume that's enough for now
const packageName = file.split('/')[1];
const bridgeName = isBridge ? file.split('/')[4] : '';
const key = isBridge ? `${packageName} (Bridge ${bridgeName})` : packageName;
if (!acc.has(key)) {
acc.set(key, {
meta: {
fileNameShort: file.replace(isBridge ? `src/${file.split('/')[1]}/src/Bridge/${file.split('/')[4]}/assets/dist/` : `src/${file.split('/')[1]}/assets/dist/`, ''),
fileNameUrl: `${repoUrl}/blob/${process.env.HEAD_REF}/${file}`,
packageName,
bridgeName,
url: isBridge
? `${repoUrl}/tree/${process.env.HEAD_REF}/src/${packageName}/src/Bridge/${bridgeName}/assets/dist`
: `${repoUrl}/tree/${process.env.HEAD_REF}/src/${packageName}/assets/dist`,
},
files: new Set(),
});
}
return acc;
}, new Map);
const added = !base[file] && pr[file];
const removed = base[file] && !pr[file];
acc.get(key).files.add({
state: added ? 'added' : removed ? 'removed' : 'changed',
before: { size: beforeSize, sizeGz: beforeSizeGz },
after: { size: afterSize, sizeGz: afterSizeGz },
diffPercent: {
size: removed ? -100 : added ? 100 : computeDiffPercent(beforeSize, afterSize),
sizeGz: removed ? -100 : added ? 100 : computeDiffPercent(beforeSizeGz, afterSizeGz),
},
meta: {
fileNameShort: file.replace(
isBridge
? `src/${file.split('/')[1]}/src/Bridge/${file.split('/')[4]}/assets/dist/`
: `src/${file.split('/')[1]}/assets/dist/`,
''
),
fileNameUrl: `${repoUrl}/blob/${process.env.HEAD_REF}/${file}`,
},
});
}
return acc;
}, new Map());
if (packagesFiles.size === 0) {
output += ' No difference in dist packagesFiles.\n';
return output;
}
output += 'Thanks for the PR! Here is the difference in size of the packages dist files between the base branch and the PR.\n';
output +=
'Thanks for the PR! Here is the difference in size of the packages dist files between the base branch and the PR.\n';
output += 'Please review the changes and make sure they are expected.\n\n';
output += `<table>
<thead><tr><th>File</th><th>Before (Size / Gzip)</th><th>After (Size / Gzip)</th></tr></thead>
@@ -150,15 +157,17 @@ export function main() {
output += `<tr>
<td><a href="${file.meta.fileNameUrl}"><code>${file.meta.fileNameShort}</code></a></td>
`;
output += file.state === 'added'
? `<td><em>Added</em></td>`
: `<td>
output +=
file.state === 'added'
? `<td><em>Added</em></td>`
: `<td>
<code>${formatBytes(file.before.size)}</code>
/ <code>${formatBytes(file.before.sizeGz)}</code>
</td>`;
output += file.state === 'removed'
? `<td><em>Removed</em></td>`
: `<td>
</td>`;
output +=
file.state === 'removed'
? `<td><em>Removed</em></td>`
: `<td>
<code>${formatBytes(file.after.size)}</code>${file.state === 'changed' ? `<sup>${formatDiffPercent(file.diffPercent.size)}</sup>` : ''}
/ <code>${formatBytes(file.after.sizeGz)}</code>${file.state === 'changed' ? `<sup>${formatDiffPercent(file.diffPercent.sizeGz)}</sup>` : ''}
</td>`;

View File

@@ -16,81 +16,81 @@ concurrency:
jobs:
encore-app:
name: "Encore (${{ matrix.name}})"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: Internal, from "vendor/"
ux-packages-source: php-vendor
- name: External, from "npm add"
ux-packages-source: js-packages
steps:
- uses: actions/checkout@v4
name: 'Encore (${{ matrix.name}})'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: Internal, from "vendor/"
ux-packages-source: php-vendor
- name: External, from "npm add"
ux-packages-source: js-packages
steps:
- uses: actions/checkout@v4
- run: npm i -g corepack && corepack enable
- run: npm i -g corepack && corepack enable
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
- uses: shivammathur/setup-php@v2
- uses: shivammathur/setup-php@v2
- name: Install root dependencies
uses: ramsey/composer-install@v3
with:
working-directory: ${{ github.workspace }}
- name: Install root dependencies
uses: ramsey/composer-install@v3
with:
working-directory: ${{ github.workspace }}
- name: Build root packages
run: php .github/build-packages.php
- name: Build root packages
run: php .github/build-packages.php
# We always install PHP deps because of the UX Translator, which requires `var/translations` to exists
- name: Install PHP dependencies
uses: ramsey/composer-install@v3
with:
working-directory: apps/encore
dependency-versions: highest
# We always install PHP deps because of the UX Translator, which requires `var/translations` to exists
- name: Install PHP dependencies
uses: ramsey/composer-install@v3
with:
working-directory: apps/encore
dependency-versions: highest
- working-directory: apps/encore
run: npm install --install-links
- working-directory: apps/encore
run: npm install --install-links
- if: matrix.ux-packages-source == 'js-packages'
name: Install UX JS packages with a JS package manager
working-directory: apps/encore
run: |
PACKAGES_TO_INSTALL=''
for PACKAGE_DATA in $(pnpm ls -r --json --depth -1 | jq 'map(select(.private != true))' | jq -c '.[]'); do
PACKAGE_PATH=$(echo $PACKAGE_DATA | jq -r '.path')
PACKAGES_TO_INSTALL="$PACKAGES_TO_INSTALL file:$(realpath --relative-to=. "$PACKAGE_PATH")"
done
- if: matrix.ux-packages-source == 'js-packages'
name: Install UX JS packages with a JS package manager
working-directory: apps/encore
run: |
PACKAGES_TO_INSTALL=''
for PACKAGE_DATA in $(pnpm ls -r --json --depth -1 | jq 'map(select(.private != true))' | jq -c '.[]'); do
PACKAGE_PATH=$(echo $PACKAGE_DATA | jq -r '.path')
PACKAGES_TO_INSTALL="$PACKAGES_TO_INSTALL file:$(realpath --relative-to=. "$PACKAGE_PATH")"
done
echo "Installing packages: $PACKAGES_TO_INSTALL"
npm add --save-dev --install-links $PACKAGES_TO_INSTALL
echo "Installing packages: $PACKAGES_TO_INSTALL"
npm add --save-dev --install-links $PACKAGES_TO_INSTALL
- name: Ensure UX packages are installed from "${{ env.EXPECTED_PATTERN }}"
working-directory: apps/encore
run: |
for PACKAGE_DATA in $(cat package.json | jq -c '(.dependencies // {}) + (.devDependencies // {}) | to_entries[] | select(.key | startswith("@symfony/ux-")) | {name: .key, version: .value}'); do
PACKAGE=$(echo $PACKAGE_DATA | jq -r '.name')
PACKAGE_VERSION=$(echo $PACKAGE_DATA | jq -r '.version')
- name: Ensure UX packages are installed from "${{ env.EXPECTED_PATTERN }}"
working-directory: apps/encore
run: |
for PACKAGE_DATA in $(cat package.json | jq -c '(.dependencies // {}) + (.devDependencies // {}) | to_entries[] | select(.key | startswith("@symfony/ux-")) | {name: .key, version: .value}'); do
PACKAGE=$(echo $PACKAGE_DATA | jq -r '.name')
PACKAGE_VERSION=$(echo $PACKAGE_DATA | jq -r '.version')
echo -n "Checking $PACKAGE@$PACKAGE_VERSION..."
if [[ $PACKAGE_VERSION == $EXPECTED_PATTERN* ]]; then
echo "✅ OK"
else
echo "❌ KO"
echo " The package version of $PACKAGE must starts with the pattern (e.g.: $EXPECTED_PATTERN), got $PACKAGE_VERSION instead."
exit 1
fi
done;
env:
EXPECTED_PATTERN: ${{ matrix.ux-packages-source == 'php-vendor' && 'file:vendor/symfony/*' || 'file:../../src/*' }}
echo -n "Checking $PACKAGE@$PACKAGE_VERSION..."
if [[ $PACKAGE_VERSION == $EXPECTED_PATTERN* ]]; then
echo "✅ OK"
else
echo "❌ KO"
echo " The package version of $PACKAGE must starts with the pattern (e.g.: $EXPECTED_PATTERN), got $PACKAGE_VERSION instead."
exit 1
fi
done;
env:
EXPECTED_PATTERN: ${{ matrix.ux-packages-source == 'php-vendor' && 'file:vendor/symfony/*' || 'file:../../src/*' }}
- name: Ensure project can be built in dev mode
working-directory: apps/encore
run: npm run dev
- name: Ensure project can be built in dev mode
working-directory: apps/encore
run: npm run dev
- name: Ensure project can be built in prod mode
working-directory: apps/encore
run: npm run build
- name: Ensure project can be built in prod mode
working-directory: apps/encore
run: npm run build

View File

@@ -32,16 +32,16 @@ jobs:
env:
SYMFONY_REQUIRE: '${{ matrix.symfony }}.*'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4
- run: npm i -g corepack && corepack enable
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
cache-dependency-path: |
pnpm-lock.yaml
package.json
- run: npm i -g corepack && corepack enable
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
cache-dependency-path: |
pnpm-lock.yaml
package.json
- name: Install root JS dependencies
run: pnpm install --frozen-lockfile

View File

@@ -21,111 +21,110 @@ jobs:
name: Validate packages definition
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4
- name: Check all composer.json have label "symfony-ux"
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name composer.json); do
if ! jq -e '.keywords | index("symfony-ux")' "$file" > /dev/null; then
echo "File $file does not have the keyword 'symfony-ux' in its composer.json";
exit 1;
fi
done
- name: Check all composer.json have label "symfony-ux"
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name composer.json); do
if ! jq -e '.keywords | index("symfony-ux")' "$file" > /dev/null; then
echo "File $file does not have the keyword 'symfony-ux' in its composer.json";
exit 1;
fi
done
- name: Check all composer.json have license "MIT"
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name composer.json); do
if ! jq -e '.license == "MIT"' "$file" > /dev/null; then
echo "File $file does not have the license 'MIT' in its composer.json";
exit 1;
fi
done
- name: Check all composer.json have license "MIT"
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name composer.json); do
if ! jq -e '.license == "MIT"' "$file" > /dev/null; then
echo "File $file does not have the license 'MIT' in its composer.json";
exit 1;
fi
done
- name: Check all composer.json have minimum-stability "dev"
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name composer.json); do
if ! jq -e '."minimum-stability" == "dev"' "$file" > /dev/null; then
echo "File $file does not have the minimum-stability 'dev' in its composer.json";
exit 1;
fi
done
- name: Check all composer.json have minimum-stability "dev"
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name composer.json); do
if ! jq -e '."minimum-stability" == "dev"' "$file" > /dev/null; then
echo "File $file does not have the minimum-stability 'dev' in its composer.json";
exit 1;
fi
done
- name: Check all composer.json have dependency to "php" >=8.1
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name composer.json); do
if ! jq -e '.require.php | test(">=8.1")' "$file" > /dev/null; then
echo "File $file does not have the dependency 'php' >=8.1 in its composer.json";
exit 1;
fi
done
- name: Check all composer.json have dependency to "php" >=8.1
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name composer.json); do
if ! jq -e '.require.php | test(">=8.1")' "$file" > /dev/null; then
echo "File $file does not have the dependency 'php' >=8.1 in its composer.json";
exit 1;
fi
done
- name: Check all package.json have license "MIT"
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name package.json -not -path "*/tests/*"); do
if ! jq -e '.license == "MIT"' "$file" > /dev/null; then
echo "File $file does not have the license 'MIT' in its package.json";
exit 1;
fi
done
- name: Check all package.json have license "MIT"
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name package.json -not -path "*/tests/*"); do
if ! jq -e '.license == "MIT"' "$file" > /dev/null; then
echo "File $file does not have the license 'MIT' in its package.json";
exit 1;
fi
done
- name: Check all package.json have keywords including "symfony-ux"
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name package.json -not -path "*/tests/*"); do
if ! jq -e '.keywords | index("symfony-ux")' "$file" > /dev/null; then
echo "File $file does not have the keyword 'symfony-ux' in its package.json";
exit 1;
fi
done
- name: Check all package.json have keywords including "symfony-ux"
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name package.json -not -path "*/tests/*"); do
if ! jq -e '.keywords | index("symfony-ux")' "$file" > /dev/null; then
echo "File $file does not have the keyword 'symfony-ux' in its package.json";
exit 1;
fi
done
- name: Check all package.json have type "module"
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name package.json -not -path "*/tests/*"); do
if ! jq -e '.type == "module"' "$file" > /dev/null; then
echo "File $file does not have the type 'module' in its package.json";
exit 1;
fi
done
- name: Check all package.json have type "module"
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name package.json -not -path "*/tests/*"); do
if ! jq -e '.type == "module"' "$file" > /dev/null; then
echo "File $file does not have the type 'module' in its package.json";
exit 1;
fi
done
- name: Check all package.json have files '["dist"]'
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name package.json -not -path "*/tests/*"); do
if ! jq -e '.files | index("dist")' "$file" > /dev/null; then
echo "File $file does not have the files 'dist' in its package.json";
exit 1;
fi
done
- name: Check all package.json have files '["dist"]'
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name package.json -not -path "*/tests/*"); do
if ! jq -e '.files | index("dist")' "$file" > /dev/null; then
echo "File $file does not have the files 'dist' in its package.json";
exit 1;
fi
done
- name: Check all package.json peerDependencies are present in devDependencies and importmap to the exact same version
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name package.json -not -path "*/tests/*"); do
peerDependencies=$(jq -r '.peerDependencies | keys[]' "$file")
for peerDependency in $peerDependencies; do
peerDependencyVersion=$(jq -r --arg dep "$peerDependency" '.peerDependencies[$dep]' "$file")
importmapVersion=$(jq -r ".symfony.importmap.\"$peerDependency\" | if type == \"string\" then . else .version end" "$file")
- name: Check all package.json peerDependencies are present in devDependencies and importmap to the exact same version
if: always()
run: |
for file in $(find src/ -mindepth 2 -type f -name package.json -not -path "*/tests/*"); do
peerDependencies=$(jq -r '.peerDependencies | keys[]' "$file")
for peerDependency in $peerDependencies; do
peerDependencyVersion=$(jq -r --arg dep "$peerDependency" '.peerDependencies[$dep]' "$file")
importmapVersion=$(jq -r ".symfony.importmap.\"$peerDependency\" | if type == \"string\" then . else .version end" "$file")
if [ "$importmapVersion" == null ]; then
echo "File $file does not have the peerDependency '$peerDependency' in its symfony.importmap, skipping version check";
continue
fi
if [ "$importmapVersion" == null ]; then
echo "File $file does not have the peerDependency '$peerDependency' in its symfony.importmap, skipping version check";
continue
fi
if [ "$peerDependencyVersion" != "$importmapVersion" ]; then
echo "File $file has a mismatch for $peerDependency: peerDependency version is '$peerDependencyVersion' but symfony.importmap version is '$importmapVersion'";
exit 1;
fi
done
done
if [ "$peerDependencyVersion" != "$importmapVersion" ]; then
echo "File $file has a mismatch for $peerDependency: peerDependency version is '$peerDependencyVersion' but symfony.importmap version is '$importmapVersion'";
exit 1;
fi
done
done
coding-style-js:
code-format-js:
name: JavaScript Coding Style
runs-on: ubuntu-latest
steps:
@@ -134,13 +133,30 @@ jobs:
- run: npm i -g corepack && corepack enable
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
node-version-file: '.nvmrc'
cache: 'pnpm'
- name: Install root JS dependencies
run: pnpm install --frozen-lockfile
- run: pnpm run ci
- run: pnpm run fmt:check
code-linting-js:
name: JavaScript Coding Style
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm i -g corepack && corepack enable
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
- name: Install root JS dependencies
run: pnpm install --frozen-lockfile
- run: pnpm run lint
phpstan:
name: PHPStan
@@ -161,8 +177,8 @@ jobs:
# LTS version of Symfony
- symfony-version: '6.4.*'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v4
- name: Configure environment
run: |
@@ -178,16 +194,16 @@ jobs:
echo "Packages: $PACKAGES"
echo "PACKAGES=$PACKAGES" >> $GITHUB_ENV
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
tools: flex
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
tools: flex
- name: Get composer cache directory
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Get composer cache directory
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache packages dependencies
uses: actions/cache@v4

View File

@@ -1,29 +1,29 @@
name: Dist Files Size Diff (Comment)
on:
workflow_run:
workflows: ["Dist Files Size Diff"]
types:
- completed
workflow_run:
workflows: ['Dist Files Size Diff']
types:
- completed
jobs:
dist-files-size-diff:
runs-on: ubuntu-latest
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: dist-size-diff
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Read pr-number artifact to env var
id: read-pr-number
run: |
echo "pr-number=$(cat ./pr-number)" >> $GITHUB_OUTPUT
- name: Comment on the pull request (if success)
uses: marocchino/sticky-pull-request-comment@v2
with:
number: ${{ steps.read-pr-number.outputs.pr-number }}
path: ./diff.md
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: dist-size-diff
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Read pr-number artifact to env var
id: read-pr-number
run: |
echo "pr-number=$(cat ./pr-number)" >> $GITHUB_OUTPUT
- name: Comment on the pull request (if success)
uses: marocchino/sticky-pull-request-comment@v2
with:
number: ${{ steps.read-pr-number.outputs.pr-number }}
path: ./diff.md

View File

@@ -1,76 +1,76 @@
name: Dist Files Size Diff
on:
pull_request:
types: [opened, synchronize]
paths:
- 'src/*/assets/dist/**'
- 'src/*/src/Bridge/*/assets/dist/**'
pull_request:
types: [opened, synchronize]
paths:
- 'src/*/assets/dist/**'
- 'src/*/src/Bridge/*/assets/dist/**'
jobs:
dist-files-size-diff:
runs-on: ubuntu-latest
steps:
- name: Configure git
run: |
git config --global user.email ""
git config --global user.name "github-action[bot]"
- uses: actions/checkout@v4
with:
ref: ${{ github.base_ref }}
- name: Configure git
run: |
git config --global user.email ""
git config --global user.name "github-action[bot]"
- name: Get dist files size (from base branch)
id: base-dist-files
run: |
set -e
FILES=$(find src -mindepth 2 -type f -path '*/assets/dist/*' -not \( -path '*/tests/*' -o -path '*/public/*' -o -path '*/vendor/*' \) | sort | while read -r file; do
echo "{\"$file\": {\"size\": $(wc -c < "$file"), \"size_gz\": $(gzip -c "$file" | wc -c)}}"
done | jq -s 'add' -c)
echo "files=$FILES" >> $GITHUB_OUTPUT
- uses: actions/checkout@v4
with:
ref: ${{ github.base_ref }}
- uses: actions/checkout@v4
- name: Get dist files size (from pull request)
id: pr-dist-files
run: |
set -e
FILES=$(find src -mindepth 2 -type f -path '*/assets/dist/*' -not \( -path '*/tests/*' -o -path '*/public/*' -o -path '*/vendor/*' \) | sort | while read -r file; do
echo "{\"$file\": {\"size\": $(wc -c < "$file"), \"size_gz\": $(gzip -c "$file" | wc -c)}}"
done | jq -s 'add' -c)
echo "files=$FILES" >> $GITHUB_OUTPUT
- name: Get dist files size (from base branch)
id: base-dist-files
run: |
set -e
- name: Generate the diff
id: diff
uses: actions/github-script@v7
env:
BASE_DIST_FILES: ${{ steps.base-dist-files.outputs.files }}
HEAD_DIST_FILES: ${{ steps.pr-dist-files.outputs.files }}
HEAD_REPO_NAME: ${{ github.event.pull_request.head.repo.full_name }}
HEAD_REF: ${{ github.event.pull_request.head.ref }}
with:
result-encoding: string
script: |
const fs = require('fs')
const { main } = await import('${{ github.workspace }}/.github/generate-dist-files-size-diff.mjs')
const diff = await main()
console.log(diff);
fs.writeFileSync(process.env.GITHUB_WORKSPACE + '/diff.md', diff)
FILES=$(find src -mindepth 2 -type f -path '*/assets/dist/*' -not \( -path '*/tests/*' -o -path '*/public/*' -o -path '*/vendor/*' \) | sort | while read -r file; do
echo "{\"$file\": {\"size\": $(wc -c < "$file"), \"size_gz\": $(gzip -c "$file" | wc -c)}}"
done | jq -s 'add' -c)
- name: Save PR number
run: |
echo "${{ github.event.number }}" > pr-number
echo "files=$FILES" >> $GITHUB_OUTPUT
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dist-size-diff
path: |
./diff.md
./pr-number
- uses: actions/checkout@v4
- name: Get dist files size (from pull request)
id: pr-dist-files
run: |
set -e
FILES=$(find src -mindepth 2 -type f -path '*/assets/dist/*' -not \( -path '*/tests/*' -o -path '*/public/*' -o -path '*/vendor/*' \) | sort | while read -r file; do
echo "{\"$file\": {\"size\": $(wc -c < "$file"), \"size_gz\": $(gzip -c "$file" | wc -c)}}"
done | jq -s 'add' -c)
echo "files=$FILES" >> $GITHUB_OUTPUT
- name: Generate the diff
id: diff
uses: actions/github-script@v7
env:
BASE_DIST_FILES: ${{ steps.base-dist-files.outputs.files }}
HEAD_DIST_FILES: ${{ steps.pr-dist-files.outputs.files }}
HEAD_REPO_NAME: ${{ github.event.pull_request.head.repo.full_name }}
HEAD_REF: ${{ github.event.pull_request.head.ref }}
with:
result-encoding: string
script: |
const fs = require('fs')
const { main } = await import('${{ github.workspace }}/.github/generate-dist-files-size-diff.mjs')
const diff = await main()
console.log(diff);
fs.writeFileSync(process.env.GITHUB_WORKSPACE + '/diff.md', diff)
- name: Save PR number
run: |
echo "${{ github.event.number }}" > pr-number
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dist-size-diff
path: |
./diff.md
./pr-number

View File

@@ -15,33 +15,33 @@ concurrency:
cancel-in-progress: true
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm i -g corepack && corepack enable
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
cache-dependency-path: |
pnpm-lock.yaml
**/package.json
- run: npm i -g corepack && corepack enable
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
cache-dependency-path: |
pnpm-lock.yaml
**/package.json
- name: Install root JS dependencies
run: pnpm install --frozen-lockfile
- name: Install root JS dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm run build
- name: Build
run: pnpm run build
- name: Check if JS dist files are current
run: |
if ! git diff --quiet; then
echo "The Git workspace is unclean! Changes detected:"
git status --porcelain
git diff
exit 1
else
echo "The Git workspace is clean. No changes detected."
fi
- name: Check if JS dist files are current
run: |
if ! git diff --quiet; then
echo "The Git workspace is unclean! Changes detected:"
git status --porcelain
git diff
exit 1
else
echo "The Git workspace is clean. No changes detected."
fi

View File

@@ -2,8 +2,8 @@
name: Functional Tests
defaults:
run:
shell: bash
run:
shell: bash
on:
push:
@@ -19,23 +19,23 @@ jobs:
turbo-tests:
runs-on: ${{ matrix.os || 'ubuntu-latest' }}
strategy:
fail-fast: false
matrix:
php-version: ['8.1', '8.2', '8.3', '8.4', '8.5']
dependency-version: ['']
symfony-version: ['']
minimum-stability: ['stable']
os: ['']
include:
# dev packages (probably not needed to have multiple such jobs)
- minimum-stability: 'dev'
php-version: '8.5'
# lowest deps
- php-version: '8.1'
dependency-version: 'lowest'
# LTS version of Symfony
- php-version: '8.1'
symfony-version: '6.4.*'
fail-fast: false
matrix:
php-version: ['8.1', '8.2', '8.3', '8.4', '8.5']
dependency-version: ['']
symfony-version: ['']
minimum-stability: ['stable']
os: ['']
include:
# dev packages (probably not needed to have multiple such jobs)
- minimum-stability: 'dev'
php-version: '8.5'
# lowest deps
- php-version: '8.1'
dependency-version: 'lowest'
# LTS version of Symfony
- php-version: '8.1'
symfony-version: '6.4.*'
env:
SYMFONY_REQUIRE: ${{ matrix.symfony-version || '>=5.4' }}
services:
@@ -82,8 +82,8 @@ jobs:
- name: Install JavaScript dependencies
working-directory: src/Turbo/tests/app
run: |
php public/index.php importmap:install
php public/index.php asset-map:compile
php public/index.php importmap:install
php public/index.php asset-map:compile
- name: Create DB
working-directory: src/Turbo/tests/app
@@ -92,7 +92,7 @@ jobs:
- name: Run tests
working-directory: src/Turbo
run: |
[ 'lowest' = '${{ matrix.dependency-version }}' ] && export SYMFONY_DEPRECATIONS_HELPER=weak
vendor/bin/simple-phpunit
[ 'lowest' = '${{ matrix.dependency-version }}' ] && export SYMFONY_DEPRECATIONS_HELPER=weak
vendor/bin/simple-phpunit
env:
SYMFONY_DEPRECATIONS_HELPER: 'max[self]=1'

View File

@@ -1,59 +1,59 @@
name: Release on NPM
on:
push:
tags:
- 'v2.*.*'
push:
tags:
- 'v2.*.*'
permissions:
id-token: write # Required for OIDC
id-token: write # Required for OIDC
contents: read
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: 2.x
- uses: actions/checkout@v4
with:
ref: 2.x
- name: Configure Git
run: |
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
- name: Configure Git
run: |
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
- name: Extract version from tag
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
- name: Extract version from tag
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
- run: npm i -g corepack && corepack enable
- uses: actions/setup-node@v4
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
cache: 'pnpm'
cache-dependency-path: |
pnpm-lock.yaml
package.json
src/**/package.json
- run: npm i -g corepack && corepack enable
- uses: actions/setup-node@v4
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
cache: 'pnpm'
cache-dependency-path: |
pnpm-lock.yaml
package.json
src/**/package.json
# npm 11.5.1 or later is required for OIDC
- run: npm install -g npm@latest
# npm 11.5.1 or later is required for OIDC
- run: npm install -g npm@latest
- name: Install root JS dependencies
run: pnpm install --frozen-lockfile
- name: Install root JS dependencies
run: pnpm install --frozen-lockfile
- name: Update version of JS packages
run: pnpm version ${{ env.VERSION }} --no-git-tag-version --workspaces --no-workspaces-update
- name: Update version of JS packages
run: pnpm version ${{ env.VERSION }} --no-git-tag-version --workspaces --no-workspaces-update
- name: Commit changes
run: |
git add .
git commit -m "Update versions to ${{ env.VERSION }}"
- name: Commit changes
run: |
git add .
git commit -m "Update versions to ${{ env.VERSION }}"
- name: Publish on NPM
run: pnpm publish --recursive --access public --no-git-checks
- name: Publish on NPM
run: pnpm publish --recursive --access public --no-git-checks
- name: Push changes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: git push origin 2.x
- name: Push changes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: git push origin 2.x

View File

@@ -1,8 +1,8 @@
name: Unit Tests
defaults:
run:
shell: bash
run:
shell: bash
on:
push:
@@ -32,31 +32,31 @@ jobs:
minimum-stability: ['stable']
os: ['']
include:
- minimum-stability: 'dev'
php-version: '8.5'
- minimum-stability: 'dev'
php-version: '8.5'
# lowest deps
- php-version: '8.1'
dependency-version: 'lowest'
- php-version: '8.1'
dependency-version: 'lowest'
# LTS version of Symfony
- php-version: '8.1'
symfony-version: '6.4.*'
- php-version: '8.1'
symfony-version: '6.4.*'
os: 'windows-latest'
- php-version: '8.1'
symfony-version: '6.4.*'
- php-version: '8.1'
symfony-version: '6.4.*'
os: 'windows-latest'
- php-version: '8.2'
symfony-version: '7.4.*'
- php-version: '8.2'
symfony-version: '7.4.*'
os: 'windows-latest'
- php-version: '8.2'
symfony-version: '7.4.*'
- php-version: '8.2'
symfony-version: '7.4.*'
os: 'windows-latest'
# Explicit Symfony versions
- php-version: '8.4'
symfony-version: '8.0.*'
- php-version: '8.5'
symfony-version: '8.0.*'
- php-version: '8.4'
symfony-version: '8.0.*'
- php-version: '8.5'
symfony-version: '8.0.*'
env:
SYMFONY_REQUIRE: ${{ matrix.symfony-version || '>=5.4' }} # TODO: To change to '>=6.4' in 3.x
@@ -88,14 +88,14 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: ${{ matrix.os == 'windows-latest' && 'pdo_sqlite,sqlite3,fileinfo,gd,zip' || '' }}
tools: flex
php-version: ${{ matrix.php-version }}
extensions: ${{ matrix.os == 'windows-latest' && 'pdo_sqlite,sqlite3,fileinfo,gd,zip' || '' }}
tools: flex
- name: Get composer cache directory
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Get composer cache directory
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache packages dependencies
uses: actions/cache@v4
@@ -116,38 +116,38 @@ jobs:
- name: Run packages tests (Unix)
if: matrix.os != 'windows-latest'
run: |
source .github/workflows/.utils.sh
echo "$PACKAGES" | xargs -n1 | parallel -j +3 "_run_task {} \
'(cd src/{} \
&& $COMPOSER_MIN_STAB \
&& before_composer_install \"{}\" \"${{ matrix.php-version }}\" \"${{ matrix.symfony-version }}\" \
&& $COMPOSER_UP \
&& after_composer_install \"{}\" \"${{ matrix.php-version }}\" \"${{ matrix.symfony-version }}\" \
&& $PHPUNIT)'"
source .github/workflows/.utils.sh
echo "$PACKAGES" | xargs -n1 | parallel -j +3 "_run_task {} \
'(cd src/{} \
&& $COMPOSER_MIN_STAB \
&& before_composer_install \"{}\" \"${{ matrix.php-version }}\" \"${{ matrix.symfony-version }}\" \
&& $COMPOSER_UP \
&& after_composer_install \"{}\" \"${{ matrix.php-version }}\" \"${{ matrix.symfony-version }}\" \
&& $PHPUNIT)'"
- name: Run packages tests (Windows)
if: matrix.os == 'windows-latest'
run: |
source .github/workflows/.utils.sh
source .github/workflows/.utils.sh
# parallel is not available on Windows, so we need to run the tests sequentially
FAILED_PACKAGES=""
for PACKAGE in $PACKAGES; do
if ! PACKAGE="$PACKAGE" _run_task_sequential $PACKAGE \
'(cd src/$PACKAGE \
&& $COMPOSER_MIN_STAB \
&& before_composer_install $PACKAGE ${{ matrix.php-version }} ${{ matrix.symfony-version }} \
&& $COMPOSER_UP \
&& after_composer_install $PACKAGE ${{ matrix.php-version }} ${{ matrix.symfony-version }} \
&& $PHPUNIT)'; then
FAILED_PACKAGES="$FAILED_PACKAGES $PACKAGE"
# parallel is not available on Windows, so we need to run the tests sequentially
FAILED_PACKAGES=""
for PACKAGE in $PACKAGES; do
if ! PACKAGE="$PACKAGE" _run_task_sequential $PACKAGE \
'(cd src/$PACKAGE \
&& $COMPOSER_MIN_STAB \
&& before_composer_install $PACKAGE ${{ matrix.php-version }} ${{ matrix.symfony-version }} \
&& $COMPOSER_UP \
&& after_composer_install $PACKAGE ${{ matrix.php-version }} ${{ matrix.symfony-version }} \
&& $PHPUNIT)'; then
FAILED_PACKAGES="$FAILED_PACKAGES $PACKAGE"
fi
done
if [ -n "$FAILED_PACKAGES" ]; then
echo "The following packages failed:$FAILED_PACKAGES"
exit 1
fi
done
if [ -n "$FAILED_PACKAGES" ]; then
echo "The following packages failed:$FAILED_PACKAGES"
exit 1
fi
js:
runs-on: ubuntu-latest
steps:
@@ -156,12 +156,12 @@ jobs:
- run: npm i -g corepack && corepack enable
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
cache-dependency-path: |
pnpm-lock.yaml
package.json
src/**/package.json
node-version-file: '.nvmrc'
cache: 'pnpm'
cache-dependency-path: |
pnpm-lock.yaml
package.json
src/**/package.json
- name: Install root JS dependencies
run: pnpm install --frozen-lockfile

22
.oxfmtrc.json Normal file
View File

@@ -0,0 +1,22 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"ignorePatterns": [
"**/composer.json",
"**/vendor",
"**/package.json",
"**/node_modules",
"**/browsers",
"apps/**/config/**/*.yaml",
"apps/**/assets/**/build",
"apps/**/var",
"src/**/dist",
"src/**/var",
"src/**/tests/**/fixtures/**",
"src/**/tests/**/__snapshots__/**"
],
"printWidth": 120,
"tabWidth": 4,
"trailingComma": "es5",
"bracketSameLine": true,
"singleQuote": true
}

25
.oxlintrc.json Normal file
View File

@@ -0,0 +1,25 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": null,
"categories": {},
"rules": {},
"env": {
"builtin": true,
"es2021": true
},
"globals": {},
"ignorePatterns": [
"**/composer.json",
"**/vendor",
"**/package.json",
"**/node_modules",
"**/browsers",
"apps/**/config/**/*.yaml",
"apps/**/assets/**/build",
"apps/**/var",
"src/**/dist",
"src/**/var",
"src/**/tests/**/fixtures/**",
"src/**/tests/**/__snapshots__/**"
]
}

View File

@@ -92,28 +92,31 @@ php vendor/bin/simple-phpunit -d --update-snapshots
### 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, 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)
- 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 fail if any modifications are needed
- `pnpm run check --write`: run the formatter, linter, and import 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
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 fail if any modifications are needed
- `pnpm run check --write`: run the formatter, linter, and import 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 fmt:check`: run the code formatter for **all** packages, and **fail** if any modifications are needed
- `pnpm run fmt`: run the code formatter for **all** packages, and **write** modifications
- `pnpm run lint`: run the linter for **all** packages
- `pnpm run lint:fix`: run the linter for **all** packages, and **fix** any fixable issues
> [!IMPORTANT]
> Always run `pnpm run build` before committing your changes to ensure assets are properly compiled.
@@ -125,10 +128,11 @@ and test files are located in the `assets/test/unit/` directory of each UX packa
for example: `src/Vue/assets/test/unit/render_controller.test.ts`.
**Running tests:**
- At the project's root, you can run the following commands:
- `pnpm run test:unit`: runs the unit tests for **all** UX packages
- `pnpm run test:unit`: runs the unit tests for **all** UX packages
- Inside the `assets/` directory of each UX package, you can run the following commands:
- `pnpm run test:unit`: runs the unit tests for the package
- `pnpm run test:unit`: runs the unit tests for the package
> [!IMPORTANT]
> The command `pnpm run test:unit` ensures that each possible combination of dependencies is tested
@@ -149,15 +153,17 @@ Test files are located in the `assets/test/browser/` directory of each UX packag
for example: `src/Vue/assets/test/browser/vue.test.ts`.
**Setup:**
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:ui`: runs the browser tests in interactive mode, allowing you to see the tests running in a browser window and debug them if needed
- `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.
@@ -165,6 +171,7 @@ for example: `src/Vue/assets/test/browser/vue.test.ts`.
> [!TIP]
> If tests are failing locally, try running them in headed mode to see what's happening:
>
> ```shell
> $ pnpm run test:browser:ui
> ```
@@ -187,6 +194,7 @@ docker run --rm -it -e DOCS_DIR='/docs' -v ${PWD}:/docs oskarstark/doctor-rst -
## Useful commands
To keep your fork up-to-date with the upstream repository and `2.x` branch:
```shell
$ git checkout 2.x && \
git fetch upstream && \
@@ -195,6 +203,7 @@ $ git checkout 2.x && \
```
To rebase your branch on top of the `2.x` branch:
```shell
$ git checkout my-feature-branch && \
git rebase upstream/2.x && \

View File

@@ -21,10 +21,10 @@ or with [Webpack Encore](https://github.com/symfony/webpack-encore)
## Resources
- [Install Symfony UX](https://symfony.com/doc/current/frontend/ux.html).
- [List of UX Packages and their documentation](https://symfony.com/bundles/StimulusBundle/current/index.html#the-ux-packages).
- [Symfony UX Official Demo](https://ux.symfony.com).
- Watch the [Stimulus Screencast on SymfonyCasts](https://symfonycasts.com/screencast/stimulus).
- [Install Symfony UX](https://symfony.com/doc/current/frontend/ux.html).
- [List of UX Packages and their documentation](https://symfony.com/bundles/StimulusBundle/current/index.html#the-ux-packages).
- [Symfony UX Official Demo](https://ux.symfony.com).
- Watch the [Stimulus Screencast on SymfonyCasts](https://symfonycasts.com/screencast/stimulus).
## Let's build an amazing ecosystem together

View File

@@ -2,7 +2,7 @@ import { registerVueControllerComponents } from '@symfony/ux-vue';
import { registerSvelteControllerComponents } from '@symfony/ux-svelte';
import { registerReactControllerComponents } from '@symfony/ux-react';
import './bootstrap.js';
import { trans } from "./translator.js";
import { trans } from './translator.js';
/*
* Welcome to your app's main JavaScript file!

View File

@@ -1,5 +1,5 @@
import { startStimulusApp } from '@symfony/stimulus-bundle';
const app = startStimulusApp();
const _app = startStimulusApp();
// register any custom, 3rd party controllers here
// app.register('some_controller_name', SomeImportedController);
// _app.register('some_controller_name', SomeImportedController);

View File

@@ -2,9 +2,13 @@ const nameCheck = /^[-_a-zA-Z0-9]{4,22}$/;
const tokenCheck = /^[-_/+a-zA-Z0-9]{24,}$/;
// Generate and double-submit a CSRF token in a form field and a cookie, as defined by Symfony's SameOriginCsrfTokenManager
document.addEventListener('submit', function (event) {
generateCsrfToken(event.target);
}, true);
document.addEventListener(
'submit',
function (event) {
generateCsrfToken(event.target);
},
true
);
// When @hotwired/turbo handles form submissions, send the CSRF token in a header in addition to a cookie
// The `framework.csrf_protection.check_header` config option needs to be enabled for the header to be checked
@@ -20,7 +24,7 @@ document.addEventListener('turbo:submit-end', function (event) {
removeCsrfToken(event.detail.formSubmission.formElement);
});
export function generateCsrfToken (formElement) {
export function generateCsrfToken(formElement) {
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');
if (!csrfField) {
@@ -31,8 +35,10 @@ export function generateCsrfToken (formElement) {
let csrfToken = csrfField.value;
if (!csrfCookie && nameCheck.test(csrfToken)) {
csrfField.setAttribute('data-csrf-protection-cookie-value', csrfCookie = csrfToken);
csrfField.defaultValue = csrfToken = btoa(String.fromCharCode.apply(null, (window.crypto || window.msCrypto).getRandomValues(new Uint8Array(18))));
csrfField.setAttribute('data-csrf-protection-cookie-value', (csrfCookie = csrfToken));
csrfField.defaultValue = csrfToken = btoa(
String.fromCharCode.apply(null, (window.crypto || window.msCrypto).getRandomValues(new Uint8Array(18)))
);
csrfField.dispatchEvent(new Event('change', { bubbles: true }));
}
@@ -42,7 +48,7 @@ export function generateCsrfToken (formElement) {
}
}
export function generateCsrfHeaders (formElement) {
export function generateCsrfHeaders(formElement) {
const headers = {};
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');
@@ -59,7 +65,7 @@ export function generateCsrfHeaders (formElement) {
return headers;
}
export function removeCsrfToken (formElement) {
export function removeCsrfToken(formElement) {
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');
if (!csrfField) {

View File

@@ -1,17 +1,16 @@
import * as fs from 'node:fs';
import * as path from 'node:path';
import {globSync} from 'tinyglobby'
import {compile} from 'svelte/compiler';
import { globSync } from 'tinyglobby';
import { compile } from 'svelte/compiler';
globSync('src/**/*.svelte')
.forEach((file) => {
const builtFile = file.replace('src/', 'build/').replace('.svelte', '.js')
console.log(`Building ${file} to ${builtFile}...`)
globSync('src/**/*.svelte').forEach((file) => {
const builtFile = file.replace('src/', 'build/').replace('.svelte', '.js');
console.log(`Building ${file} to ${builtFile}...`);
const result = compile(fs.readFileSync(file, 'utf8'), {
format: 'esm',
});
fs.mkdirSync(path.dirname(builtFile), { recursive: true })
fs.writeFileSync(builtFile, result.js.code);
const result = compile(fs.readFileSync(file, 'utf8'), {
format: 'esm',
});
fs.mkdirSync(path.dirname(builtFile), { recursive: true });
fs.writeFileSync(builtFile, result.js.code);
});

View File

@@ -1,5 +1,5 @@
import { createTranslator } from "@symfony/ux-translator";
import { messages, localeFallbacks } from "../var/translations/index.js";
import { createTranslator } from '@symfony/ux-translator';
import { messages, localeFallbacks } from '../var/translations/index.js';
/*
* This file is part of the Symfony UX Translator package.

View File

@@ -1,4 +1,4 @@
export default {
props: ['name'],
template: `<div>Hello {{ name }} from Vue.js</div>`
}
template: `<div>Hello {{ name }} from Vue.js</div>`,
};

View File

@@ -1,7 +1,6 @@
services:
###> symfony/mercure-bundle ###
mercure:
ports:
- 9877
###> symfony/mercure-bundle ###
mercure:
ports:
- 9877
###< symfony/mercure-bundle ###

View File

@@ -1,31 +1,30 @@
services:
###> symfony/mercure-bundle ###
mercure:
image: dunglas/mercure
restart: unless-stopped
environment:
# Uncomment the following line to disable HTTPS,
#SERVER_NAME: ':80'
MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
# Set the URL of your Symfony project (without trailing slash!) as value of the cors_origins directive
MERCURE_EXTRA_DIRECTIVES: |
cors_origins http://127.0.0.1:8000
# Comment the following line to disable the development mode
command: /usr/bin/caddy run --config /etc/caddy/dev.Caddyfile
healthcheck:
test: ["CMD", "curl", "-f", "https://localhost/healthz"]
timeout: 5s
retries: 5
start_period: 60s
volumes:
- mercure_data:/data
- mercure_config:/config
###> symfony/mercure-bundle ###
mercure:
image: dunglas/mercure
restart: unless-stopped
environment:
# Uncomment the following line to disable HTTPS,
#SERVER_NAME: ':80'
MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
# Set the URL of your Symfony project (without trailing slash!) as value of the cors_origins directive
MERCURE_EXTRA_DIRECTIVES: |
cors_origins http://127.0.0.1:8000
# Comment the following line to disable the development mode
command: /usr/bin/caddy run --config /etc/caddy/dev.Caddyfile
healthcheck:
test: ['CMD', 'curl', '-f', 'https://localhost/healthz']
timeout: 5s
retries: 5
start_period: 60s
volumes:
- mercure_data:/data
- mercure_config:/config
###< symfony/mercure-bundle ###
volumes:
###> symfony/mercure-bundle ###
mercure_data:
mercure_config:
###> symfony/mercure-bundle ###
mercure_data:
mercure_config:
###< symfony/mercure-bundle ###

View File

@@ -30,4 +30,4 @@ published_at: 'Publié le {publication_date, date} - {publication_date, time, sh
# Numbers
progress: '{progress, number, percent} du travail est fait'
value_of_object: "Cet artéfact vaut {price, number, ::currency/EUR}"
value_of_object: 'Cet artéfact vaut {price, number, ::currency/EUR}'

View File

@@ -19,4 +19,4 @@ registerVueControllerComponents(require.context('./vue/controllers', true, /\.vu
document.addEventListener('DOMContentLoaded', () => {
console.log(trans('say_hello', { name: 'Fabien' }));
})
});

View File

@@ -1,10 +1,8 @@
import { startStimulusApp } from '@symfony/stimulus-bridge';
// Registers Stimulus controllers from controllers.json and in the controllers/ directory
export const app = startStimulusApp(require.context(
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
true,
/\.[jt]sx?$/
));
export const app = startStimulusApp(
require.context('@symfony/stimulus-bridge/lazy-controller-loader!./controllers', true, /\.[jt]sx?$/)
);
// register any custom, 3rd party controllers here
// app.register('some_controller_name', SomeImportedController);

View File

@@ -1,10 +1,14 @@
const nameCheck = /^[-_a-zA-Z0-9]{4,22}$/;
const tokenCheck = /^[-_\/+a-zA-Z0-9]{24,}$/;
const tokenCheck = /^[-_/+a-zA-Z0-9]{24,}$/;
// Generate and double-submit a CSRF token in a form field and a cookie, as defined by Symfony's SameOriginCsrfTokenManager
document.addEventListener('submit', function (event) {
generateCsrfToken(event.target);
}, true);
document.addEventListener(
'submit',
function (event) {
generateCsrfToken(event.target);
},
true
);
// When @hotwired/turbo handles form submissions, send the CSRF token in a header in addition to a cookie
// The `framework.csrf_protection.check_header` config option needs to be enabled for the header to be checked
@@ -20,7 +24,7 @@ document.addEventListener('turbo:submit-end', function (event) {
removeCsrfToken(event.detail.formSubmission.formElement);
});
export function generateCsrfToken (formElement) {
export function generateCsrfToken(formElement) {
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');
if (!csrfField) {
@@ -31,8 +35,10 @@ export function generateCsrfToken (formElement) {
let csrfToken = csrfField.value;
if (!csrfCookie && nameCheck.test(csrfToken)) {
csrfField.setAttribute('data-csrf-protection-cookie-value', csrfCookie = csrfToken);
csrfField.defaultValue = csrfToken = btoa(String.fromCharCode.apply(null, (window.crypto || window.msCrypto).getRandomValues(new Uint8Array(18))));
csrfField.setAttribute('data-csrf-protection-cookie-value', (csrfCookie = csrfToken));
csrfField.defaultValue = csrfToken = btoa(
String.fromCharCode.apply(null, (window.crypto || window.msCrypto).getRandomValues(new Uint8Array(18)))
);
csrfField.dispatchEvent(new Event('change', { bubbles: true }));
}
@@ -42,7 +48,7 @@ export function generateCsrfToken (formElement) {
}
}
export function generateCsrfHeaders (formElement) {
export function generateCsrfHeaders(formElement) {
const headers = {};
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');
@@ -59,7 +65,7 @@ export function generateCsrfHeaders (formElement) {
return headers;
}
export function removeCsrfToken (formElement) {
export function removeCsrfToken(formElement) {
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');
if (!csrfField) {

View File

@@ -1,5 +1,5 @@
import { createTranslator } from "@symfony/ux-translator";
import { messages, localeFallbacks } from "../var/translations/index.js";
import { createTranslator } from '@symfony/ux-translator';
import { messages, localeFallbacks } from '../var/translations/index.js';
/*
* This file is part of the Symfony UX Translator package.

View File

@@ -3,7 +3,7 @@
</template>
<script setup>
defineProps({
name: String
});
defineProps({
name: String,
});
</script>

View File

@@ -1,7 +1,6 @@
services:
###> symfony/mercure-bundle ###
mercure:
ports:
- "80"
###> symfony/mercure-bundle ###
mercure:
ports:
- '80'
###< symfony/mercure-bundle ###

View File

@@ -1,31 +1,30 @@
services:
###> symfony/mercure-bundle ###
mercure:
image: dunglas/mercure
restart: unless-stopped
environment:
# Uncomment the following line to disable HTTPS,
#SERVER_NAME: ':80'
MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
# Set the URL of your Symfony project (without trailing slash!) as value of the cors_origins directive
MERCURE_EXTRA_DIRECTIVES: |
cors_origins http://127.0.0.1:8000
# Comment the following line to disable the development mode
command: /usr/bin/caddy run --config /etc/caddy/dev.Caddyfile
healthcheck:
test: ["CMD", "curl", "-f", "https://localhost/healthz"]
timeout: 5s
retries: 5
start_period: 60s
volumes:
- mercure_data:/data
- mercure_config:/config
###> symfony/mercure-bundle ###
mercure:
image: dunglas/mercure
restart: unless-stopped
environment:
# Uncomment the following line to disable HTTPS,
#SERVER_NAME: ':80'
MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
# Set the URL of your Symfony project (without trailing slash!) as value of the cors_origins directive
MERCURE_EXTRA_DIRECTIVES: |
cors_origins http://127.0.0.1:8000
# Comment the following line to disable the development mode
command: /usr/bin/caddy run --config /etc/caddy/dev.Caddyfile
healthcheck:
test: ['CMD', 'curl', '-f', 'https://localhost/healthz']
timeout: 5s
retries: 5
start_period: 60s
volumes:
- mercure_data:/data
- mercure_config:/config
###< symfony/mercure-bundle ###
volumes:
###> symfony/mercure-bundle ###
mercure_data:
mercure_config:
###> symfony/mercure-bundle ###
mercure_data:
mercure_config:
###< symfony/mercure-bundle ###

View File

@@ -62,24 +62,23 @@ Encore
.configureBabelPresetEnv((config) => {
config.useBuiltIns = 'usage';
config.corejs = '3.38';
})
});
// enables Sass/SCSS support
//.enableSassLoader()
// enables Sass/SCSS support
//.enableSassLoader()
// uncomment if you use TypeScript
//.enableTypeScriptLoader()
// uncomment if you use TypeScript
//.enableTypeScriptLoader()
// uncomment if you use React
//.enableReactPreset()
// uncomment if you use React
//.enableReactPreset()
// uncomment to get integrity="..." attributes on your script & link tags
// requires WebpackEncoreBundle 1.4 or higher
//.enableIntegrityHashes(Encore.isProduction())
// uncomment to get integrity="..." attributes on your script & link tags
// requires WebpackEncoreBundle 1.4 or higher
//.enableIntegrityHashes(Encore.isProduction())
// uncomment if you're having problems with a jQuery plugin
//.autoProvidejQuery()
;
// uncomment if you're having problems with a jQuery plugin
//.autoProvidejQuery()
const config = Encore.getWebpackConfig();
// config.resolve.conditionNames = (config.resolve.conditionNames || []).concat(['svelte']);

View File

@@ -1,7 +1,7 @@
module.exports = {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/react',
['@babel/preset-typescript', { allowDeclareFields: true }]
['@babel/preset-typescript', { allowDeclareFields: true }],
],
};

View File

@@ -7,7 +7,7 @@ import * as path from 'node:path';
import { parseArgs } from 'node:util';
import { globSync } from 'tinyglobby';
import { build } from 'tsup';
import { readPackageJSON } from "pkg-types";
import { readPackageJSON } from 'pkg-types';
const args = parseArgs({
allowPositionals: true,
@@ -35,7 +35,9 @@ async function main() {
const packageData = await readPackageJSON(path.join(packageRoot, 'package.json'));
const isStimulusBundle = '@symfony/stimulus-bundle' === packageData.name;
const isReactOrVueOrSvelte = ['@symfony/ux-react', '@symfony/ux-vue', '@symfony/ux-svelte'].some(name => packageData.name.startsWith(name));
const isReactOrVueOrSvelte = ['@symfony/ux-react', '@symfony/ux-vue', '@symfony/ux-svelte'].some((name) =>
packageData.name.startsWith(name)
);
const inputCssFile = packageData?.config?.css_source;
const inputFiles = [
@@ -72,7 +74,7 @@ async function main() {
platform: 'browser',
tsconfig: path.join(packageRoot, 'tsconfig.json'),
dts: {
entry: inputFiles.filter(inputFile => !inputFile.endsWith('.css')),
entry: inputFiles.filter((inputFile) => !inputFile.endsWith('.css')),
},
watch: isWatch,
splitting: false,
@@ -90,7 +92,7 @@ async function main() {
*/
name: 'symfony-ux:minify-css',
async renderChunk(code, chunkInfo) {
if (!/\.css$/.test(chunkInfo.path)) {
if (!chunkInfo.path.endsWith('.css')) {
return null;
}
@@ -106,7 +108,7 @@ async function main() {
return {
code: result.code.toString(),
map: result.map ? result.map.toString() : null,
}
};
},
},
@@ -128,8 +130,8 @@ async function main() {
console.info(`[Symfony UX] Renamed ${writtenFile.name} to ${newName}`);
}
}
}
},
},
],
});
}

View File

@@ -1,11 +1,5 @@
import * as path from 'node:path';
import {
Browser,
BrowserTag,
detectBrowserPlatform,
install,
resolveBuildId,
} from '@puppeteer/browsers';
import { Browser, BrowserTag, detectBrowserPlatform, install, resolveBuildId } from '@puppeteer/browsers';
const platform = detectBrowserPlatform();
const installBrowserCommonOpts = {
@@ -30,9 +24,9 @@ export const browsers = {
}),
'chrome@latest': await install({
...installBrowserCommonOpts,
browser: Browser.CHROME,
buildId: await resolveBuildId(Browser.CHROME, platform, BrowserTag.STABLE),
...installBrowserCommonOpts,
browser: Browser.CHROME,
buildId: await resolveBuildId(Browser.CHROME, platform, BrowserTag.STABLE),
}),
// TODO: I don't find a way to install a specific Firefox version and make it usable

View File

@@ -11,17 +11,20 @@
"test": "pnpm run -r --workspace-concurrency=1 test",
"test:unit": "pnpm run -r --aggregate-output test:unit",
"test:browser": "pnpm run -r --workspace-concurrency=1 test:browser",
"check": "biome check",
"ci": "biome ci"
"fmt": "oxfmt",
"fmt:check": "oxfmt --check",
"lint": "oxlint",
"lint:fix": "oxlint --fix"
},
"devDependencies": {
"@biomejs/biome": "^2.3.11",
"@playwright/test": "^1.57.0",
"@puppeteer/browsers": "^2.11.0",
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^6.9.1",
"@types/node": "^22.19.3",
"lightningcss": "^1.30.2",
"oxfmt": "^0.28.0",
"oxlint": "^1.43.0",
"pkg-types": "^2.3.0",
"tinyglobby": "^0.2.15",
"tsup": "^8.5.1",

View File

@@ -16,10 +16,7 @@ import { defineConfig, devices } from '@playwright/test';
import { browsers } from './bin/get_browsers.mjs';
export default defineConfig({
testMatch: [
'**/test/browser/**/*.{test,spec}.ts',
'**/test/**/*.browser.{test,spec}.ts',
],
testMatch: ['**/test/browser/**/*.{test,spec}.ts', '**/test/**/*.browser.{test,spec}.ts'],
reporter: [
['list'],
@@ -34,7 +31,7 @@ export default defineConfig({
screenshot: 'only-on-failure',
video: 'retain-on-failure',
trace: 'retain-on-failure'
trace: 'retain-on-failure',
},
projects: [
@@ -45,7 +42,7 @@ export default defineConfig({
channel: 'chrome',
launchOptions: {
executablePath: browsers['chrome@lowest'].executablePath,
}
},
},
},
{
@@ -55,7 +52,7 @@ export default defineConfig({
channel: 'chrome',
launchOptions: {
executablePath: browsers['chrome@latest'].executablePath,
}
},
},
},
@@ -74,6 +71,6 @@ export default defineConfig({
use: {
...devices['Desktop Firefox'],
},
}
},
],
});

283
pnpm-lock.yaml generated
View File

@@ -18,9 +18,6 @@ importers:
.:
devDependencies:
'@biomejs/biome':
specifier: ^2.3.11
version: 2.3.11
'@playwright/test':
specifier: ^1.57.0
version: 1.57.0
@@ -39,6 +36,12 @@ importers:
lightningcss:
specifier: ^1.30.2
version: 1.30.2
oxfmt:
specifier: ^0.28.0
version: 0.28.0
oxlint:
specifier: ^1.43.0
version: 1.43.0
pkg-types:
specifier: ^2.3.0
version: 2.3.0
@@ -845,63 +848,6 @@ packages:
resolution: {integrity: sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==}
engines: {node: '>=6.9.0'}
'@biomejs/biome@2.3.11':
resolution: {integrity: sha512-/zt+6qazBWguPG6+eWmiELqO+9jRsMZ/DBU3lfuU2ngtIQYzymocHhKiZRyrbra4aCOoyTg/BmY+6WH5mv9xmQ==}
engines: {node: '>=14.21.3'}
hasBin: true
'@biomejs/cli-darwin-arm64@2.3.11':
resolution: {integrity: sha512-/uXXkBcPKVQY7rc9Ys2CrlirBJYbpESEDme7RKiBD6MmqR2w3j0+ZZXRIL2xiaNPsIMMNhP1YnA+jRRxoOAFrA==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [darwin]
'@biomejs/cli-darwin-x64@2.3.11':
resolution: {integrity: sha512-fh7nnvbweDPm2xEmFjfmq7zSUiox88plgdHF9OIW4i99WnXrAC3o2P3ag9judoUMv8FCSUnlwJCM1B64nO5Fbg==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [darwin]
'@biomejs/cli-linux-arm64-musl@2.3.11':
resolution: {integrity: sha512-XPSQ+XIPZMLaZ6zveQdwNjbX+QdROEd1zPgMwD47zvHV+tCGB88VH+aynyGxAHdzL+Tm/+DtKST5SECs4iwCLg==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@biomejs/cli-linux-arm64@2.3.11':
resolution: {integrity: sha512-l4xkGa9E7Uc0/05qU2lMYfN1H+fzzkHgaJoy98wO+b/7Gl78srbCRRgwYSW+BTLixTBrM6Ede5NSBwt7rd/i6g==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@biomejs/cli-linux-x64-musl@2.3.11':
resolution: {integrity: sha512-vU7a8wLs5C9yJ4CB8a44r12aXYb8yYgBn+WeyzbMjaCMklzCv1oXr8x+VEyWodgJt9bDmhiaW/I0RHbn7rsNmw==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
libc: [musl]
'@biomejs/cli-linux-x64@2.3.11':
resolution: {integrity: sha512-/1s9V/H3cSe0r0Mv/Z8JryF5x9ywRxywomqZVLHAoa/uN0eY7F8gEngWKNS5vbbN/BsfpCG5yeBT5ENh50Frxg==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@biomejs/cli-win32-arm64@2.3.11':
resolution: {integrity: sha512-PZQ6ElCOnkYapSsysiTy0+fYX+agXPlWugh6+eQ6uPKI3vKAqNp6TnMhoM3oY2NltSB89hz59o8xIfOdyhi9Iw==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [win32]
'@biomejs/cli-win32-x64@2.3.11':
resolution: {integrity: sha512-43VrG813EW+b5+YbDbz31uUsheX+qFKCpXeY9kfdAx+ww3naKxeVkTD9zLIWxUPfJquANMHrmW3wbe/037G0Qg==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [win32]
'@bundled-es-modules/cookie@2.0.1':
resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==}
@@ -1364,6 +1310,94 @@ packages:
'@orchidjs/unicode-variants@1.1.2':
resolution: {integrity: sha512-5DobW1CHgnBROOEpFlEXytED5OosEWESFvg/VYmH0143oXcijYTprRYJTs+55HzGM4IqxiLFSuqEzu9mPNwVsA==}
'@oxfmt/darwin-arm64@0.28.0':
resolution: {integrity: sha512-jmUfF7cNJPw57bEK7sMIqrYRgn4LH428tSgtgLTCtjuGuu1ShREyrkeB7y8HtkXRfhBs4lVY+HMLhqElJvZ6ww==}
cpu: [arm64]
os: [darwin]
'@oxfmt/darwin-x64@0.28.0':
resolution: {integrity: sha512-S6vlV8S7jbjzJOSjfVg2CimUC0r7/aHDLdUm/3+/B/SU/s1jV7ivqWkMv1/8EB43d1BBwT9JQ60ZMTkBqeXSFA==}
cpu: [x64]
os: [darwin]
'@oxfmt/linux-arm64-gnu@0.28.0':
resolution: {integrity: sha512-TfJkMZjePbLiskmxFXVAbGI/OZtD+y+fwS0wyW8O6DWG0ARTf0AipY9zGwGoOdpFuXOJceXvN4SHGLbYNDMY4Q==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxfmt/linux-arm64-musl@0.28.0':
resolution: {integrity: sha512-7fyQUdW203v4WWGr1T3jwTz4L7KX9y5DeATryQ6fLT6QQp9GEuct8/k0lYhd+ys42iTV/IkJF20e3YkfSOOILg==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxfmt/linux-x64-gnu@0.28.0':
resolution: {integrity: sha512-sRKqAvEonuz0qr1X1ncUZceOBJerKzkO2gZIZmosvy/JmqyffpIFL3OE2tqacFkeDhrC+dNYQpusO8zsfHo3pw==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxfmt/linux-x64-musl@0.28.0':
resolution: {integrity: sha512-fW6czbXutX/tdQe8j4nSIgkUox9RXqjyxwyWXUDItpoDkoXllq17qbD7GVc0whrEhYQC6hFE1UEAcDypLJoSzw==}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxfmt/win32-arm64@0.28.0':
resolution: {integrity: sha512-D/HDeQBAQRjTbD9OLV6kRDcStrIfO+JsUODDCdGmhRfNX8LPCx95GpfyybpZfn3wVF8Jq/yjPXV1xLkQ+s7RcA==}
cpu: [arm64]
os: [win32]
'@oxfmt/win32-x64@0.28.0':
resolution: {integrity: sha512-4+S2j4OxOIyo8dz5osm5dZuL0yVmxXvtmNdHB5xyGwAWVvyWNvf7tCaQD7w2fdSsAXQLOvK7KFQrHFe33nJUCA==}
cpu: [x64]
os: [win32]
'@oxlint/darwin-arm64@1.43.0':
resolution: {integrity: sha512-C/GhObv/pQZg34NOzB6Mk8x0wc9AKj8fXzJF8ZRKTsBPyHusC6AZ6bba0QG0TUufw1KWuD0j++oebQfWeiFXNw==}
cpu: [arm64]
os: [darwin]
'@oxlint/darwin-x64@1.43.0':
resolution: {integrity: sha512-4NjfUtEEH8ewRQ2KlZGmm6DyrvypMdHwBnQT92vD0dLScNOQzr0V9O8Ua4IWXdeCNl/XMVhAV3h4/3YEYern5A==}
cpu: [x64]
os: [darwin]
'@oxlint/linux-arm64-gnu@1.43.0':
resolution: {integrity: sha512-75tf1HvwdZ3ebk83yMbSB+moAEWK98mYqpXiaFAi6Zshie7r+Cx5PLXZFUEqkscenoZ+fcNXakHxfn94V6nf1g==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxlint/linux-arm64-musl@1.43.0':
resolution: {integrity: sha512-BHV4fb36T2p/7bpA9fiJ5ayt7oJbiYX10nklW5arYp4l9/9yG/FQC5J4G1evzbJ/YbipF9UH0vYBAm5xbqGrvw==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxlint/linux-x64-gnu@1.43.0':
resolution: {integrity: sha512-1l3nvnzWWse1YHibzZ4HQXdF/ibfbKZhp9IguElni3bBqEyPEyurzZ0ikWynDxKGXqZa+UNXTFuU1NRVX1RJ3g==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxlint/linux-x64-musl@1.43.0':
resolution: {integrity: sha512-+jNYgLGRFTJxJuaSOZJBwlYo5M0TWRw0+3y5MHOL4ArrIdHyCthg6r4RbVWrsR1qUfUE1VSSHQ2bfbC99RXqMg==}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxlint/win32-arm64@1.43.0':
resolution: {integrity: sha512-dvs1C/HCjCyGTURMagiHprsOvVTT3omDiSzi5Qw0D4QFJ1pEaNlfBhVnOUYgUfS6O7Mcmj4+G+sidRsQcWQ/kA==}
cpu: [arm64]
os: [win32]
'@oxlint/win32-x64@1.43.0':
resolution: {integrity: sha512-bSuItSU8mTSDsvmmLTepTdCL2FkJI6dwt9tot/k0EmiYF+ArRzmsl4lXVLssJNRV5lJEc5IViyTrh7oiwrjUqA==}
cpu: [x64]
os: [win32]
'@pkgjs/parseargs@0.11.0':
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
@@ -2428,6 +2462,7 @@ packages:
glob@10.5.0:
resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==}
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
hasBin: true
gopd@1.2.0:
@@ -2853,6 +2888,21 @@ packages:
outvariant@1.4.3:
resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==}
oxfmt@0.28.0:
resolution: {integrity: sha512-3+hhBqPE6Kp22KfJmnstrZbl+KdOVSEu1V0ABaFIg1rYLtrMgrupx9znnHgHLqKxAVHebjTdiCJDk30CXOt6cw==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
oxlint@1.43.0:
resolution: {integrity: sha512-xiqTCsKZch+R61DPCjyqUVP2MhkQlRRYxLRBeBDi+dtQJ90MOgdcjIktvDCgXz0bgtx94EQzHEndsizZjMX2OA==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
oxlint-tsgolint: '>=0.11.2'
peerDependenciesMeta:
oxlint-tsgolint:
optional: true
pac-proxy-agent@7.2.0:
resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==}
engines: {node: '>= 14'}
@@ -3264,6 +3314,10 @@ packages:
resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==}
engines: {node: ^18.0.0 || >=20.0.0}
tinypool@2.1.0:
resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==}
engines: {node: ^20.0.0 || >=22.0.0}
tinyrainbow@2.0.0:
resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==}
engines: {node: '>=14.0.0'}
@@ -3770,41 +3824,6 @@ snapshots:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
'@biomejs/biome@2.3.11':
optionalDependencies:
'@biomejs/cli-darwin-arm64': 2.3.11
'@biomejs/cli-darwin-x64': 2.3.11
'@biomejs/cli-linux-arm64': 2.3.11
'@biomejs/cli-linux-arm64-musl': 2.3.11
'@biomejs/cli-linux-x64': 2.3.11
'@biomejs/cli-linux-x64-musl': 2.3.11
'@biomejs/cli-win32-arm64': 2.3.11
'@biomejs/cli-win32-x64': 2.3.11
'@biomejs/cli-darwin-arm64@2.3.11':
optional: true
'@biomejs/cli-darwin-x64@2.3.11':
optional: true
'@biomejs/cli-linux-arm64-musl@2.3.11':
optional: true
'@biomejs/cli-linux-arm64@2.3.11':
optional: true
'@biomejs/cli-linux-x64-musl@2.3.11':
optional: true
'@biomejs/cli-linux-x64@2.3.11':
optional: true
'@biomejs/cli-win32-arm64@2.3.11':
optional: true
'@biomejs/cli-win32-x64@2.3.11':
optional: true
'@bundled-es-modules/cookie@2.0.1':
dependencies:
cookie: 0.7.2
@@ -4163,6 +4182,54 @@ snapshots:
'@orchidjs/unicode-variants@1.1.2': {}
'@oxfmt/darwin-arm64@0.28.0':
optional: true
'@oxfmt/darwin-x64@0.28.0':
optional: true
'@oxfmt/linux-arm64-gnu@0.28.0':
optional: true
'@oxfmt/linux-arm64-musl@0.28.0':
optional: true
'@oxfmt/linux-x64-gnu@0.28.0':
optional: true
'@oxfmt/linux-x64-musl@0.28.0':
optional: true
'@oxfmt/win32-arm64@0.28.0':
optional: true
'@oxfmt/win32-x64@0.28.0':
optional: true
'@oxlint/darwin-arm64@1.43.0':
optional: true
'@oxlint/darwin-x64@1.43.0':
optional: true
'@oxlint/linux-arm64-gnu@1.43.0':
optional: true
'@oxlint/linux-arm64-musl@1.43.0':
optional: true
'@oxlint/linux-x64-gnu@1.43.0':
optional: true
'@oxlint/linux-x64-musl@1.43.0':
optional: true
'@oxlint/win32-arm64@1.43.0':
optional: true
'@oxlint/win32-x64@1.43.0':
optional: true
'@pkgjs/parseargs@0.11.0':
optional: true
@@ -5861,6 +5928,30 @@ snapshots:
outvariant@1.4.3:
optional: true
oxfmt@0.28.0:
dependencies:
tinypool: 2.1.0
optionalDependencies:
'@oxfmt/darwin-arm64': 0.28.0
'@oxfmt/darwin-x64': 0.28.0
'@oxfmt/linux-arm64-gnu': 0.28.0
'@oxfmt/linux-arm64-musl': 0.28.0
'@oxfmt/linux-x64-gnu': 0.28.0
'@oxfmt/linux-x64-musl': 0.28.0
'@oxfmt/win32-arm64': 0.28.0
'@oxfmt/win32-x64': 0.28.0
oxlint@1.43.0:
optionalDependencies:
'@oxlint/darwin-arm64': 1.43.0
'@oxlint/darwin-x64': 1.43.0
'@oxlint/linux-arm64-gnu': 1.43.0
'@oxlint/linux-arm64-musl': 1.43.0
'@oxlint/linux-x64-gnu': 1.43.0
'@oxlint/linux-x64-musl': 1.43.0
'@oxlint/win32-arm64': 1.43.0
'@oxlint/win32-x64': 1.43.0
pac-proxy-agent@7.2.0:
dependencies:
'@tootallnate/quickjs-emscripten': 0.23.0
@@ -6367,6 +6458,8 @@ snapshots:
tinypool@1.1.1: {}
tinypool@2.1.0: {}
tinyrainbow@2.0.0: {}
tinyspy@4.0.4: {}

View File

@@ -1,24 +1,24 @@
packages:
- src/*/assets
- src/*/src/Bridge/*/assets
- src/*/assets
- src/*/src/Bridge/*/assets
linkWorkspacePackages: true
overrides:
'@swup/plugin>@swup/browserslist-config': link:node_modules/.ignored
'@swup/plugin>@swup/prettier-config': link:node_modules/.ignored
'@swup/plugin>microbundle': link:node_modules/.ignored
'@swup/plugin>prettier': link:node_modules/.ignored
'@swup/plugin>shelljs': link:node_modules/.ignored
'@swup/plugin>shelljs-live': link:node_modules/.ignored
'@swup/plugin>@swup/browserslist-config': link:node_modules/.ignored
'@swup/plugin>@swup/prettier-config': link:node_modules/.ignored
'@swup/plugin>microbundle': link:node_modules/.ignored
'@swup/plugin>prettier': link:node_modules/.ignored
'@swup/plugin>shelljs': link:node_modules/.ignored
'@swup/plugin>shelljs-live': link:node_modules/.ignored
packageExtensions:
'@symfony/ux-google-map':
dependencies:
'@symfony/ux-map': 'workspace:*'
dependencies:
'@symfony/ux-map': 'workspace:*'
'@symfony/ux-leaflet-map':
dependencies:
'@symfony/ux-map': 'workspace:*'
dependencies:
'@symfony/ux-map': 'workspace:*'
minimumReleaseAge: 1440

View File

@@ -1,5 +1,4 @@
Please do not submit any Pull Requests here. They will be closed.
---
## Please do not submit any Pull Requests here. They will be closed.
Please submit your PR here instead:
https://github.com/symfony/ux

View File

@@ -1,20 +1,20 @@
name: Close Pull Request
on:
pull_request_target:
types: [opened]
pull_request_target:
types: [opened]
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!

View File

@@ -1,3 +1,3 @@
branches: ["2.x"]
maintained_branches: ["2.x"]
doc_dir: "doc"
branches: ['2.x']
maintained_branches: ['2.x']
doc_dir: 'doc'

View File

@@ -2,15 +2,16 @@
## 2.30
- Ensure compatibility with PHP 8.5
- Ensure compatibility with PHP 8.5
## 2.29.0
- Add Symfony 8 support
- Add Symfony 8 support
## 2.28.0
- Default plugins like `clear_button` or `remove_button` can now be removed when setting their value to `false` in the `tom_select_options.plugins` option, for example:
- Default plugins like `clear_button` or `remove_button` can now be removed when setting their value to `false` in the `tom_select_options.plugins` option, for example:
```php
<?php
#[AsEntityAutocompleteField]
@@ -38,101 +39,101 @@ class IngredientAutocompleteType extends AbstractType
## 2.25.0
- Escape `querySelector` dynamic selector with `CSS.escape()` #2663
- Escape `querySelector` dynamic selector with `CSS.escape()` #2663
## 2.23.0
- Deprecate `ExtraLazyChoiceLoader` in favor of `Symfony\Component\Form\ChoiceList\Loader\LazyChoiceLoader`
- Reset TomSelect when updating url attribute #1505
- Add `getAttributes()` method to define additional attributes for autocomplete results #2541
- Deprecate `ExtraLazyChoiceLoader` in favor of `Symfony\Component\Form\ChoiceList\Loader\LazyChoiceLoader`
- Reset TomSelect when updating url attribute #1505
- Add `getAttributes()` method to define additional attributes for autocomplete results #2541
## 2.22.0
- Take `labelField` TomSelect option into account #2382
- Take `labelField` TomSelect option into account #2382
## 2.21.0
- Translate the `option_create` option from TomSelect with remote data setup #2279
- Add one missing Dutch translation #2279
- Translate the `option_create` option from TomSelect with remote data setup #2279
- Add one missing Dutch translation #2279
## 2.20.0
- Translate the `option_create` option from TomSelect #2108
- Translate the `option_create` option from TomSelect #2108
## 2.17.0
- Allow `choice_value` option in entity autocomplete fields #1723
- Allow `choice_value` option in entity autocomplete fields #1723
## 2.16.0
- Missing translations added for many languages #1527 #1528 #1535
- Missing translations added for many languages #1527 #1528 #1535
## 2.15.0
- Add doctrine/orm 3 support #1468
- Allow passing extra options to the autocomplete fields #1322
- Fix 2 bugs where TomSelect would reset when not necessary #1502
- Add one missing German translation #1521
- Add doctrine/orm 3 support #1468
- Allow passing extra options to the autocomplete fields #1322
- Fix 2 bugs where TomSelect would reset when not necessary #1502
- Add one missing German translation #1521
## 2.14.0
- Fixed behavior of Autocomplete when the underlying `select` or `option`
elements were modified to hopefully, more reliably, reset the autocomplete
instance. This is particularly important with LiveComponents.
- Add support for the `render.loading_more` Tom Select Virtual Scroll option (`loading_more_text`)
- Avoid losing the selected options when the Stimulus component is disconnected
and reconnected to the DOM.
- Added `tom-select/dist/css/tom-select.bootstrap4.css` to `autoimport` - this
will cause this to appear in your `controllers.json` file by default, but disabled
see.
- Allow passing `extra_options` key in an array passed as a `3rd` argument of the `->add()` method.
It will be used during the Ajax call to fetch results.
- Fixed behavior of Autocomplete when the underlying `select` or `option`
elements were modified to hopefully, more reliably, reset the autocomplete
instance. This is particularly important with LiveComponents.
- Add support for the `render.loading_more` Tom Select Virtual Scroll option (`loading_more_text`)
- Avoid losing the selected options when the Stimulus component is disconnected
and reconnected to the DOM.
- Added `tom-select/dist/css/tom-select.bootstrap4.css` to `autoimport` - this
will cause this to appear in your `controllers.json` file by default, but disabled
see.
- Allow passing `extra_options` key in an array passed as a `3rd` argument of the `->add()` method.
It will be used during the Ajax call to fetch results.
## 2.13.2
- Revert "Change JavaScript package to `type: module`"
- Revert "Change JavaScript package to `type: module`"
## 2.13.0
- Add new BaseEntityAutocompleteType
- Drop symfony 5.4 support.
- Add Symfony 7 support.
- Change JavaScript package to `type: module`
- Add new BaseEntityAutocompleteType
- Drop symfony 5.4 support.
- Add Symfony 7 support.
- Change JavaScript package to `type: module`
## 2.9.0
- Add support for symfony/asset-mapper
- Add support for symfony/asset-mapper
## 2.8.0
- The autocomplete now watches for update to any `option` elements inside of
it change, including the empty / placeholder element. Additionally, if the
`select` or `input` element's `disabled` attribute changes, the autocomplete
instance will update accordingly. This makes Autocomplete work correctly inside
of a LiveComponent. This functionality does _not_ work for `multiple` selects.
- The autocomplete now watches for update to any `option` elements inside of
it change, including the empty / placeholder element. Additionally, if the
`select` or `input` element's `disabled` attribute changes, the autocomplete
instance will update accordingly. This makes Autocomplete work correctly inside
of a LiveComponent. This functionality does _not_ work for `multiple` selects.
- Added support for using [OptionGroups](https://tom-select.js.org/examples/optgroups/).
- Added support for using [OptionGroups](https://tom-select.js.org/examples/optgroups/).
## 2.7.0
- Add `assets/src` to `.gitattributes` to exclude them from the installation
- Add `assets/src` to `.gitattributes` to exclude them from the installation
- Fix minCharacters option default value handling when using a falsy value like 0.
- Fix minCharacters option default value handling when using a falsy value like 0.
- Fix TypeScript types
- Fix TypeScript types
- Add a new `route` parameter to `AsEntityAutocompleteField`, which allows to choose another route for Ajax calls.
- Add a new `route` parameter to `AsEntityAutocompleteField`, which allows to choose another route for Ajax calls.
- Fix minCharacters option default value handling when using a falsy value like 0.
- Fix minCharacters option default value handling when using a falsy value like 0.
- Fix TypeScript types
- Fix TypeScript types
- Add a way to detect if a field is an "autocomplete" field in form themes - #608
- Add a way to detect if a field is an "autocomplete" field in form themes - #608
## 2.6.0
- [BC BREAK]: The path to `routes.php` changed and you should update your
route import accordingly:
- [BC BREAK]: The path to `routes.php` changed and you should update your
route import accordingly:
```diff
# config/routes/ux_autocomplete.yaml
@@ -142,29 +143,29 @@ ux_autocomplete:
prefix: '/autocomplete'
```
- Add support for `tom-select` version `2.2.2` and made this the minimum-supported
version.
- Added support for the `preload` TomSelect option.
- Fix don't add WHERE IN criteria without params (#561).
- Fix issue where `max_results` was not passed as a Stimulus value (#538).
- Add all possible stylesheets for tom-select to the autoimport to choose from.
- Add support for `tom-select` version `2.2.2` and made this the minimum-supported
version.
- Added support for the `preload` TomSelect option.
- Fix don't add WHERE IN criteria without params (#561).
- Fix issue where `max_results` was not passed as a Stimulus value (#538).
- Add all possible stylesheets for tom-select to the autoimport to choose from.
## 2.5.0
- Automatic pagination support added: if the query would return more results
than your limit, when the user scrolls to the bottom of the options, it will
make a second Ajax call to load more.
- Automatic pagination support added: if the query would return more results
than your limit, when the user scrolls to the bottom of the options, it will
make a second Ajax call to load more.
- Added `max_results` option to limit the number of results returned by the
Ajax endpoint - #478.
- Added `max_results` option to limit the number of results returned by the
Ajax endpoint - #478.
- Support added for setting the required minimum search query length (defaults to 3) (#492)
- Support added for setting the required minimum search query length (defaults to 3) (#492)
- Fix support for more complex ids, like UUIDs - #494.
- Fix support for more complex ids, like UUIDs - #494.
- Fixed bug where sometimes an error could occur in the Ajax call related to
the label - #520.
- Fixed bug where sometimes an error could occur in the Ajax call related to
the label - #520.
## 2.4.0
- Component added!
- Component added!

View File

@@ -19,10 +19,10 @@ Help Symfony by [sponsoring][3] its development!
## Resources
- [Documentation](https://symfony.com/bundles/ux-autocomplete/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
- [Documentation](https://symfony.com/bundles/ux-autocomplete/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
[1]: https://symfony.com/backers
[2]: https://mercure.rocks

View File

@@ -6,9 +6,10 @@ JavaScript assets of the [symfony/ux-autocomplete](https://packagist.org/package
This npm package is **reserved for advanced users** who want to decouple their JavaScript dependencies from their PHP dependencies (e.g., when building Docker images, running JavaScript-only pipelines, etc.).
We **strongly recommend not installing this package directly**, but instead install the PHP package [symfony/ux-autocomplete](https://packagist.org/packages/symfony/ux-autocomplete) in your Symfony application with [Flex](https://github.com/symfony/flex) enabled.
We **strongly recommend not installing this package directly**, but instead install the PHP package [symfony/ux-autocomplete](https://packagist.org/packages/symfony/ux-autocomplete) in your Symfony application with [Flex](https://github.com/symfony/flex) enabled.
If you still want to install this package directly, please make sure its version exactly matches [symfony/ux-autocomplete](https://packagist.org/packages/symfony/ux-autocomplete) PHP package version:
```shell
composer require symfony/ux-autocomplete:2.23.0
npm add @symfony/ux-autocomplete@2.23.0
@@ -18,7 +19,7 @@ npm add @symfony/ux-autocomplete@2.23.0
## Resources
- [Documentation](https://symfony.com/bundles/ux-autocomplete/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
- [Documentation](https://symfony.com/bundles/ux-autocomplete/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)

View File

@@ -20,9 +20,7 @@
"test": "pnpm run test:unit && pnpm run test:browser",
"test:unit": "../../../bin/unit_test_package.sh .",
"test:browser": "playwright test",
"test:browser:ui": "playwright test --ui",
"check": "biome check",
"ci": "biome ci"
"test:browser:ui": "playwright test --ui"
},
"symfony": {
"controllers": {

View File

@@ -1,5 +1,4 @@
Please do not submit any Pull Requests here. They will be closed.
---
## Please do not submit any Pull Requests here. They will be closed.
Please submit your PR here instead:
https://github.com/symfony/ux

View File

@@ -1,20 +1,20 @@
name: Close Pull Request
on:
pull_request_target:
types: [opened]
pull_request_target:
types: [opened]
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!

View File

@@ -1,3 +1,3 @@
branches: ["2.x"]
maintained_branches: ["2.x"]
doc_dir: "doc"
branches: ['2.x']
maintained_branches: ['2.x']
doc_dir: 'doc'

View File

@@ -2,90 +2,90 @@
## 2.30
- Ensure compatibility with PHP 8.5
- Ensure compatibility with PHP 8.5
## 2.29.0
- Add Symfony 8 support
- Add Symfony 8 support
## 2.23.0
- Listen to Stimulus `disconnect` event to destroy the chart #1944
- Listen to Stimulus `disconnect` event to destroy the chart #1944
## 2.18.0
- Replace `chartjs/auto` import with explicit `Chart.register()` call #1263
- Replace `chartjs/auto` import with explicit `Chart.register()` call #1263
## 2.17.0
- Add `chartjs:view-value-change` event #1605
- Add `chartjs:view-value-change` event #1605
## 2.15.0
- Remove restriction that prevented Chart.js 3.9 #1518
- Remove restriction that prevented Chart.js 3.9 #1518
## 2.14.0
- Add support for Chart.js version 4
- Add support for Chart.js version 4
## 2.13.2
- Change "module" key back to "main" in package.json
- Change "module" key back to "main" in package.json
## 2.13.1
- Revert "Change JavaScript package to `type: module`"
- Revert "Change JavaScript package to `type: module`"
## 2.13.0
- Add Symfony 7 support.
- Change JavaScript package to `type: module`
- Add Symfony 7 support.
- Change JavaScript package to `type: module`
## 2.9.0
- Add support for symfony/asset-mapper
- Add support for symfony/asset-mapper
- Add dependency on symfony/stimulus-bundle
- Add dependency on symfony/stimulus-bundle
- Minimum required PHP version is now 8.1.
- Minimum required PHP version is now 8.1.
- Minimum required Symfony version is now 5.4.
- Minimum required Symfony version is now 5.4.
## 2.8.0
- The chart will now automatically re-render if the `view` Stimulus value
(i.e. the `data-symfony--ux-chartjs--chart-view-value` attribute) changes.
This makes Chart.js work perfectly inside of a LiveComponent.
- The chart will now automatically re-render if the `view` Stimulus value
(i.e. the `data-symfony--ux-chartjs--chart-view-value` attribute) changes.
This makes Chart.js work perfectly inside of a LiveComponent.
## 2.7.0
- The `chartjs:connect` JavaScript event now bubbles up.
- The `chartjs:connect` JavaScript event now bubbles up.
- Add `assets/src` to `.gitattributes` to exclude source TypeScript files from
installing.
- Add `assets/src` to `.gitattributes` to exclude source TypeScript files from
installing.
- TypeScript types are now included.
- TypeScript types are now included.
## 2.6.0
- [BC BREAK] The `assets/` directory was moved from `Resources/assets/` to `assets/`. Make
sure the path in your `package.json` file is updated accordingly.
- [BC BREAK] The `assets/` directory was moved from `Resources/assets/` to `assets/`. Make
sure the path in your `package.json` file is updated accordingly.
- The directory structure of the bundle was updated to match modern best-practices.
- The directory structure of the bundle was updated to match modern best-practices.
## 2.0
- Support for `stimulus` version 2 was removed and support for `@hotwired/stimulus`
version 3 was added. See the [@symfony/stimulus-bridge CHANGELOG](https://github.com/symfony/stimulus-bridge/blob/main/CHANGELOG.md#300)
for more details.
- Support added for Symfony 6
- Upgrade Chart.js to version 3
- Support for `stimulus` version 2 was removed and support for `@hotwired/stimulus`
version 3 was added. See the [@symfony/stimulus-bridge CHANGELOG](https://github.com/symfony/stimulus-bridge/blob/main/CHANGELOG.md#300)
for more details.
- Support added for Symfony 6
- Upgrade Chart.js to version 3
## 1.3
- [DEPENDENCY CHANGE] `chart.js` is no longer included automatically (#93)
but `symfony/flex` will automatically add it to your `package.json` file
when upgrading. Additionally `symfony/flex` 1.13 or higher is now required
if installed.
- [DEPENDENCY CHANGE] `chart.js` is no longer included automatically (#93)
but `symfony/flex` will automatically add it to your `package.json` file
when upgrading. Additionally `symfony/flex` 1.13 or higher is now required
if installed.
- Chart.js: add horizontalBar type to chart model #87 - @duboiss
- Chart.js: add horizontalBar type to chart model #87 - @duboiss

View File

@@ -20,10 +20,10 @@ Help Symfony by [sponsoring][3] its development!
## Resources
- [Documentation](https://symfony.com/bundles/ux-chartjs/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
- [Documentation](https://symfony.com/bundles/ux-chartjs/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
[1]: https://symfony.com/backers
[2]: https://mercure.rocks

View File

@@ -6,9 +6,10 @@ JavaScript assets of the [symfony/ux-chartjs](https://packagist.org/packages/sym
This npm package is **reserved for advanced users** who want to decouple their JavaScript dependencies from their PHP dependencies (e.g., when building Docker images, running JavaScript-only pipelines, etc.).
We **strongly recommend not installing this package directly**, but instead install the PHP package [symfony/ux-chartjs](https://packagist.org/packages/symfony/ux-chartjs) in your Symfony application with [Flex](https://github.com/symfony/flex) enabled.
We **strongly recommend not installing this package directly**, but instead install the PHP package [symfony/ux-chartjs](https://packagist.org/packages/symfony/ux-chartjs) in your Symfony application with [Flex](https://github.com/symfony/flex) enabled.
If you still want to install this package directly, please make sure its version exactly matches [symfony/ux-chartjs](https://packagist.org/packages/symfony/ux-chartjs) PHP package version:
```shell
composer require symfony/ux-chartjs:2.23.0
npm add @symfony/ux-chartjs@2.23.0
@@ -18,7 +19,7 @@ npm add @symfony/ux-chartjs@2.23.0
## Resources
- [Documentation](https://symfony.com/bundles/ux-chartjs/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
- [Documentation](https://symfony.com/bundles/ux-chartjs/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)

View File

@@ -20,9 +20,7 @@
"test": "pnpm run test:unit && pnpm run test:browser",
"test:unit": "../../../bin/unit_test_package.sh .",
"test:browser": "playwright test",
"test:browser:ui": "playwright test --ui",
"check": "biome check",
"ci": "biome ci"
"test:browser:ui": "playwright test --ui"
},
"symfony": {
"controllers": {

View File

@@ -1,5 +1,4 @@
Please do not submit any Pull Requests here. They will be closed.
---
## Please do not submit any Pull Requests here. They will be closed.
Please submit your PR here instead:
https://github.com/symfony/ux

View File

@@ -1,20 +1,20 @@
name: Close Pull Request
on:
pull_request_target:
types: [opened]
pull_request_target:
types: [opened]
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!

View File

@@ -1,3 +1,3 @@
branches: ["2.x"]
maintained_branches: ["2.x"]
doc_dir: "doc"
branches: ['2.x']
maintained_branches: ['2.x']
doc_dir: 'doc'

View File

@@ -2,55 +2,55 @@
## 2.30
- Ensure compatibility with PHP 8.5
- Ensure compatibility with PHP 8.5
## 2.29.0
- Add Symfony 8 support
- Add Symfony 8 support
## 2.13.2
- Revert "Change JavaScript package to `type: module`"
- Revert "Change JavaScript package to `type: module`"
## 2.13.0
- Add Symfony 7 support.
- Change JavaScript package to `type: module`
- Add Symfony 7 support.
- Change JavaScript package to `type: module`
## 2.9.0
- Add support for symfony/asset-mapper
- Add support for symfony/asset-mapper
- Minimum required Symfony version is now 5.4
- Minimum required Symfony version is now 5.4
## 2.7.0
- The JavaScript events now bubble up.
- The JavaScript events now bubble up.
- Add `assets/src` to `.gitattributes` to exclude source TypeScript files from
installing.
- Add `assets/src` to `.gitattributes` to exclude source TypeScript files from
installing.
- TypeScript types are now included.
- TypeScript types are now included.
## 2.6.0
- [BC BREAK] The `assets/` directory was moved from `Resources/assets/` to `assets/`. Make
sure the path in your `package.json` file is updated accordingly.
- [BC BREAK] The `assets/` directory was moved from `Resources/assets/` to `assets/`. Make
sure the path in your `package.json` file is updated accordingly.
- The directory structure of the bundle was updated to match modern best-practices.
- The directory structure of the bundle was updated to match modern best-practices.
## 2.0
- Support for `stimulus` version 2 was removed and support for `@hotwired/stimulus`
version 3 was added. See the [@symfony/stimulus-bridge CHANGELOG](https://github.com/symfony/stimulus-bridge/blob/main/CHANGELOG.md#300)
for more details.
- The individual Cropper.js options in `CropperType` were moved under
a single `cropper_options` option.
- Support added for Symfony 6
- Support for `stimulus` version 2 was removed and support for `@hotwired/stimulus`
version 3 was added. See the [@symfony/stimulus-bridge CHANGELOG](https://github.com/symfony/stimulus-bridge/blob/main/CHANGELOG.md#300)
for more details.
- The individual Cropper.js options in `CropperType` were moved under
a single `cropper_options` option.
- Support added for Symfony 6
## 1.3
- [DEPENDENCY CHANGE] `cropperjs` is no longer included automatically (#93)
but `symfony/flex` will automatically add it to your `package.json` file
when upgrading. Additionally `symfony/flex` 1.13 or higher is now required
if installed.
- [DEPENDENCY CHANGE] `cropperjs` is no longer included automatically (#93)
but `symfony/flex` will automatically add it to your `package.json` file
when upgrading. Additionally `symfony/flex` 1.13 or higher is now required
if installed.

View File

@@ -20,10 +20,10 @@ Help Symfony by [sponsoring][3] its development!
## Resources
- [Documentation](https://symfony.com/bundles/ux-cropperjs/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
- [Documentation](https://symfony.com/bundles/ux-cropperjs/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
[1]: https://symfony.com/backers
[2]: https://mercure.rocks

View File

@@ -6,9 +6,10 @@ JavaScript assets of the [symfony/ux-cropperjs](https://packagist.org/packages/s
This npm package is **reserved for advanced users** who want to decouple their JavaScript dependencies from their PHP dependencies (e.g., when building Docker images, running JavaScript-only pipelines, etc.).
We **strongly recommend not installing this package directly**, but instead install the PHP package [symfony/ux-cropperjs](https://packagist.org/packages/symfony/ux-cropperjs) in your Symfony application with [Flex](https://github.com/symfony/flex) enabled.
We **strongly recommend not installing this package directly**, but instead install the PHP package [symfony/ux-cropperjs](https://packagist.org/packages/symfony/ux-cropperjs) in your Symfony application with [Flex](https://github.com/symfony/flex) enabled.
If you still want to install this package directly, please make sure its version exactly matches [symfony/ux-cropperjs](https://packagist.org/packages/symfony/ux-cropperjs) PHP package version:
```shell
composer require symfony/ux-cropperjs:2.23.0
npm add @symfony/ux-cropperjs@2.23.0
@@ -18,7 +19,7 @@ npm add @symfony/ux-cropperjs@2.23.0
## Resources
- [Documentation](https://symfony.com/bundles/ux-cropperjs/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
- [Documentation](https://symfony.com/bundles/ux-cropperjs/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)

View File

@@ -23,9 +23,7 @@
"test": "pnpm run test:unit && pnpm run test:browser",
"test:unit": "../../../bin/unit_test_package.sh .",
"test:browser": "playwright test",
"test:browser:ui": "playwright test --ui",
"check": "biome check",
"ci": "biome ci"
"test:browser:ui": "playwright test --ui"
},
"symfony": {
"controllers": {

View File

@@ -1,5 +1,4 @@
Please do not submit any Pull Requests here. They will be closed.
---
## Please do not submit any Pull Requests here. They will be closed.
Please submit your PR here instead:
https://github.com/symfony/ux

View File

@@ -1,20 +1,20 @@
name: Close Pull Request
on:
pull_request_target:
types: [opened]
pull_request_target:
types: [opened]
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!

View File

@@ -1,3 +1,3 @@
branches: ["2.x"]
maintained_branches: ["2.x"]
doc_dir: "doc"
branches: ['2.x']
maintained_branches: ['2.x']
doc_dir: 'doc'

View File

@@ -2,48 +2,48 @@
## 2.30
- Ensure compatibility with PHP 8.5
- Ensure compatibility with PHP 8.5
## 2.29.0
- Add Symfony 8 support
- Add Symfony 8 support
## 2.20
- Enable file replacement via "drag-and-drop"
- Enable file replacement via "drag-and-drop"
## 2.13.2
- Revert "Change JavaScript package to `type: module`"
- Revert "Change JavaScript package to `type: module`"
## 2.13.0
- Add Symfony 7 support.
- Change JavaScript package to `type: module`
- Add Symfony 7 support.
- Change JavaScript package to `type: module`
## 2.9.0
- Add support for symfony/asset-mapper
- Add support for symfony/asset-mapper
## 2.7.0
- The JavaScript events now bubble up.
- The JavaScript events now bubble up.
- Add `assets/src` to `.gitattributes` to exclude source TypeScript files from
installing.
- Add `assets/src` to `.gitattributes` to exclude source TypeScript files from
installing.
- TypeScript types are now included.
- TypeScript types are now included.
## 2.6.0
- [BC BREAK] The `assets/` directory was moved from `Resources/assets/` to `assets/`. Make
sure the path in your `package.json` file is updated accordingly.
- [BC BREAK] The `assets/` directory was moved from `Resources/assets/` to `assets/`. Make
sure the path in your `package.json` file is updated accordingly.
- The directory structure of the bundle was updated to match modern best-practices.
- The directory structure of the bundle was updated to match modern best-practices.
## 2.0
- Support for `stimulus` version 2 was removed and support for `@hotwired/stimulus`
version 3 was added. See the [@symfony/stimulus-bridge CHANGELOG](https://github.com/symfony/stimulus-bridge/blob/main/CHANGELOG.md#300)
for more details.
- Support added for Symfony 6
- Support for `stimulus` version 2 was removed and support for `@hotwired/stimulus`
version 3 was added. See the [@symfony/stimulus-bridge CHANGELOG](https://github.com/symfony/stimulus-bridge/blob/main/CHANGELOG.md#300)
for more details.
- Support added for Symfony 6

View File

@@ -23,10 +23,10 @@ Help Symfony by [sponsoring][3] its development!
## Resources
- [Documentation](https://symfony.com/bundles/ux-dropzone/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
- [Documentation](https://symfony.com/bundles/ux-dropzone/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
[1]: https://symfony.com/backers
[2]: https://mercure.rocks

View File

@@ -6,9 +6,10 @@ JavaScript assets of the [symfony/ux-dropzone](https://packagist.org/packages/sy
This npm package is **reserved for advanced users** who want to decouple their JavaScript dependencies from their PHP dependencies (e.g., when building Docker images, running JavaScript-only pipelines, etc.).
We **strongly recommend not installing this package directly**, but instead install the PHP package [symfony/ux-dropzone](https://packagist.org/packages/symfony/ux-dropzone) in your Symfony application with [Flex](https://github.com/symfony/flex) enabled.
We **strongly recommend not installing this package directly**, but instead install the PHP package [symfony/ux-dropzone](https://packagist.org/packages/symfony/ux-dropzone) in your Symfony application with [Flex](https://github.com/symfony/flex) enabled.
If you still want to install this package directly, please make sure its version exactly matches [symfony/ux-dropzone](https://packagist.org/packages/symfony/ux-dropzone) PHP package version:
```shell
composer require symfony/ux-dropzone:2.23.0
npm add @symfony/ux-dropzone@2.23.0
@@ -18,7 +19,7 @@ npm add @symfony/ux-dropzone@2.23.0
## Resources
- [Documentation](https://symfony.com/bundles/ux-dropzone/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
- [Documentation](https://symfony.com/bundles/ux-dropzone/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)

View File

@@ -23,9 +23,7 @@
"test": "pnpm run test:unit && pnpm run test:browser",
"test:unit": "../../../bin/unit_test_package.sh .",
"test:browser": "playwright test",
"test:browser:ui": "playwright test --ui",
"check": "biome check",
"ci": "biome ci"
"test:browser:ui": "playwright test --ui"
},
"symfony": {
"controllers": {

View File

@@ -60,7 +60,7 @@
}
.dropzone-preview-button::before {
content: "×";
content: '×';
padding: 3px 7px;
cursor: pointer;
}

View File

@@ -1,5 +1,4 @@
Please do not submit any Pull Requests here. They will be closed.
---
## Please do not submit any Pull Requests here. They will be closed.
Please submit your PR here instead:
https://github.com/symfony/ux

View File

@@ -1,20 +1,20 @@
name: Close Pull Request
on:
pull_request_target:
types: [opened]
pull_request_target:
types: [opened]
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!

View File

@@ -1,3 +1,3 @@
branches: ["2.x"]
maintained_branches: ["2.x"]
doc_dir: "doc"
branches: ['2.x']
maintained_branches: ['2.x']
doc_dir: 'doc'

View File

@@ -2,33 +2,33 @@
## 2.30
- Ensure compatibility with PHP 8.5
- Ensure compatibility with PHP 8.5
## 2.29.0
- Add Symfony 8 support
- Add Symfony 8 support
## 2.25.0
- Improve DX when `symfony/http-client` is not installed.
- Improve DX when `symfony/http-client` is not installed.
## 2.24.0
- Add `xmlns` attribute to icons downloaded with Iconify, to correctly render icons browser as an external file, in SVG editors, and in files explorers or text editors previews.
It **may breaks your pipeline** if you assert on `ux_icon()` or `<twig:ux:icon>` output in your tests, and forgot [to lock your icons](https://symfony.com/bundles/ux-icons/current/index.html#locking-on-demand-icons).
We recommend you to **lock** your icons **before** upgrading to UX Icons 2.24. We also suggest you to to **force-lock** your icons **after** upgrading to UX Icons 2.24, to add the attribute `xmlns` to your icons already downloaded from Iconify.
- Add `xmlns` attribute to icons downloaded with Iconify, to correctly render icons browser as an external file, in SVG editors, and in files explorers or text editors previews.
It **may breaks your pipeline** if you assert on `ux_icon()` or `<twig:ux:icon>` output in your tests, and forgot [to lock your icons](https://symfony.com/bundles/ux-icons/current/index.html#locking-on-demand-icons).
We recommend you to **lock** your icons **before** upgrading to UX Icons 2.24. We also suggest you to to **force-lock** your icons **after** upgrading to UX Icons 2.24, to add the attribute `xmlns` to your icons already downloaded from Iconify.
## 2.20.0
- Add `aliases` configuration option to define icon alternative names.
- Add support for `int` and `float` attribute values in `<twig:ux:icon />`.
- Add support for Icon sets, configurable with `icon_sets` option.
- Add `aliases` configuration option to define icon alternative names.
- Add support for `int` and `float` attribute values in `<twig:ux:icon />`.
- Add support for Icon sets, configurable with `icon_sets` option.
## 2.19.0
- Add `ignore_not_found` option to silence error during rendering if the
icon is not found.
- Add `ignore_not_found` option to silence error during rendering if the
icon is not found.
## 2.17.0
- Add component
- Add component

View File

@@ -35,10 +35,10 @@ Help Symfony by [sponsoring][3] its development!
## Resources
- [Documentation](https://symfony.com/bundles/ux-icons/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
- [Documentation](https://symfony.com/bundles/ux-icons/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
[1]: https://symfony.com/backers
[2]: https://mercure.rocks

View File

@@ -1,5 +1,4 @@
Please do not submit any Pull Requests here. They will be closed.
---
## Please do not submit any Pull Requests here. They will be closed.
Please submit your PR here instead:
https://github.com/symfony/ux

View File

@@ -1,20 +1,20 @@
name: Close Pull Request
on:
pull_request_target:
types: [opened]
pull_request_target:
types: [opened]
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!

View File

@@ -1,3 +1,3 @@
branches: ["2.x"]
maintained_branches: ["2.x"]
doc_dir: "doc"
branches: ['2.x']
maintained_branches: ['2.x']
doc_dir: 'doc'

View File

@@ -2,58 +2,58 @@
## 2.30
- Ensure compatibility with PHP 8.5
- Ensure compatibility with PHP 8.5
## 2.29.0
- Add Symfony 8 support
- Add Symfony 8 support
## 2.26.0
- Deprecate the package
- Deprecate the package
## 2.17.0
- Add support for `intervention/image` 3.0+
- Add support for `intervention/image` 3.0+
## 2.13.2
- Revert "Change JavaScript package to `type: module`"
- Revert "Change JavaScript package to `type: module`"
## 2.13.0
- Add Symfony 7 support.
- Change JavaScript package to `type: module`
- Add Symfony 7 support.
- Change JavaScript package to `type: module`
## 2.9.0
- Add support for symfony/asset-mapper
- Add support for symfony/asset-mapper
- Minimum required Symfony version is now 5.4
- Minimum required Symfony version is now 5.4
## 2.7.0
- The JavaScript events now bubble up.
- The JavaScript events now bubble up.
- Add `assets/src` to `.gitattributes` to exclude source TypeScript files from
installing.
- Add `assets/src` to `.gitattributes` to exclude source TypeScript files from
installing.
- TypeScript types are now included.
- TypeScript types are now included.
## 2.6.0
- [BC BREAK] The `assets/` directory was moved from `Resources/assets/` to `assets/`. Make
sure the path in your `package.json` file is updated accordingly.
- [BC BREAK] The `assets/` directory was moved from `Resources/assets/` to `assets/`. Make
sure the path in your `package.json` file is updated accordingly.
- The directory structure of the bundle was updated to match modern best-practices.
- The directory structure of the bundle was updated to match modern best-practices.
## 2.0
- Support for `stimulus` version 2 was removed and support for `@hotwired/stimulus`
version 3 was added. See the [@symfony/stimulus-bridge CHANGELOG](https://github.com/symfony/stimulus-bridge/blob/main/CHANGELOG.md#300)
for more details.
- The `data-hd-src` attribute was changed to use a Stimulus value called `src`. See the
updated README for usage.
- For both JavaScript events - `lazy-image:connect` and `lazy-image:ready` -
the `event.detail.hd` `Image` instance was moved to `event.detail.image`.
- Support added for Symfony 6
- Support for `stimulus` version 2 was removed and support for `@hotwired/stimulus`
version 3 was added. See the [@symfony/stimulus-bridge CHANGELOG](https://github.com/symfony/stimulus-bridge/blob/main/CHANGELOG.md#300)
for more details.
- The `data-hd-src` attribute was changed to use a Stimulus value called `src`. See the
updated README for usage.
- For both JavaScript events - `lazy-image:connect` and `lazy-image:ready` -
the `event.detail.hd` `Image` instance was moved to `event.detail.image`.
- Support added for Symfony 6

View File

@@ -15,8 +15,8 @@ image loading performance. It is part of [the Symfony UX initiative](https://ux.
It provides two key features:
- a Stimulus controller to load lazily heavy images, with a placeholder
- a [BlurHash implementation](https://blurha.sh/) to create data-uri thumbnails for images
- a Stimulus controller to load lazily heavy images, with a placeholder
- a [BlurHash implementation](https://blurha.sh/) to create data-uri thumbnails for images
**This repository is a READ-ONLY sub-tree split**. See
https://github.com/symfony/ux to create issues or submit pull requests.
@@ -35,10 +35,10 @@ Help Symfony by [sponsoring][3] its development!
## Resources
- [Documentation](https://symfony.com/bundles/ux-lazy-image/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
- [Documentation](https://symfony.com/bundles/ux-lazy-image/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
[1]: https://symfony.com/backers
[2]: https://mercure.rocks

View File

@@ -6,9 +6,10 @@ JavaScript assets of the [symfony/ux-lazy-image](https://packagist.org/packages/
This npm package is **reserved for advanced users** who want to decouple their JavaScript dependencies from their PHP dependencies (e.g., when building Docker images, running JavaScript-only pipelines, etc.).
We **strongly recommend not installing this package directly**, but instead install the PHP package [symfony/ux-lazy-image](https://packagist.org/packages/symfony/ux-lazy-image) in your Symfony application with [Flex](https://github.com/symfony/flex) enabled.
We **strongly recommend not installing this package directly**, but instead install the PHP package [symfony/ux-lazy-image](https://packagist.org/packages/symfony/ux-lazy-image) in your Symfony application with [Flex](https://github.com/symfony/flex) enabled.
If you still want to install this package directly, please make sure its version exactly matches [symfony/ux-lazy-image](https://packagist.org/packages/symfony/ux-lazy-image) PHP package version:
```shell
composer require symfony/ux-lazy-image:2.23.0
npm add @symfony/ux-lazy-image@2.23.0
@@ -18,7 +19,7 @@ npm add @symfony/ux-lazy-image@2.23.0
## Resources
- [Documentation](https://symfony.com/bundles/ux-lazy-image/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
- [Documentation](https://symfony.com/bundles/ux-lazy-image/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)

View File

@@ -18,9 +18,7 @@
"build": "tsx ../../../bin/build_package.ts .",
"watch": "tsx ../../../bin/build_package.ts . --watch",
"test": "pnpm run test:unit",
"test:unit": "../../../bin/unit_test_package.sh .",
"check": "biome check",
"ci": "biome ci"
"test:unit": "../../../bin/unit_test_package.sh ."
},
"symfony": {
"controllers": {

View File

@@ -1,5 +1,4 @@
Please do not submit any Pull Requests here. They will be closed.
---
## Please do not submit any Pull Requests here. They will be closed.
Please submit your PR here instead:
https://github.com/symfony/ux

View File

@@ -1,20 +1,20 @@
name: Close Pull Request
on:
pull_request_target:
types: [opened]
pull_request_target:
types: [opened]
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!

View File

@@ -1,3 +1,3 @@
branches: ["2.x"]
maintained_branches: ["2.x"]
doc_dir: "doc"
branches: ['2.x']
maintained_branches: ['2.x']
doc_dir: 'doc'

View File

@@ -2,7 +2,8 @@
## 2.31
- Add browser events assertions in `InteractsWithLiveComponents`:
- Add browser events assertions in `InteractsWithLiveComponents`:
```php
$testComponent = $this->createLiveComponent(name: 'MyComponent');
@@ -21,20 +22,20 @@ $this->assertComponentNotDispatchBrowserEvent($render, 'another-browser:event');
## 2.30
- Ensure compatibility with PHP 8.5
- Ensure compatibility with PHP 8.5
## 2.29.0
- Add Symfony 8 support
- Add Symfony 8 support
## 2.28.0
- Add new modifiers for input validations, useful to prevent unnecessary HTTP requests:
- Add new modifiers for input validations, useful to prevent unnecessary HTTP requests:
- `min_length` and `max_length`: validate length from textual input elements
- `min_value` and `max_value`: validate value from numeral input elements
- Add new `mapPath` options (default `false`) to `UrlMapping` of a `LiveProp`
to allow the prop to be mapped to the path instead of the query in the url.
- Add new `mapPath` options (default `false`) to `UrlMapping` of a `LiveProp`
to allow the prop to be mapped to the path instead of the query in the url.
```twig
<!-- Do not trigger model update until 3 characters are typed -->
@@ -46,7 +47,8 @@ $this->assertComponentNotDispatchBrowserEvent($render, 'another-browser:event');
## 2.27.0
- Add events assertions in `InteractsWithLiveComponents`:
- Add events assertions in `InteractsWithLiveComponents`:
```php
$testComponent = $this->createLiveComponent(name: 'MyComponent');
@@ -65,51 +67,51 @@ $this->assertComponentNotEmitEvent($render, 'another-event');
## 2.26.0
- `LiveProp`: Pass the property name as second parameter of the `modifier` callable
- Add compatibility layer to fix deprecation with `Symfony\Component\PropertyInfo\PropertyInfoExtractor::getTypes()`.
If you use PHP 8.2 or higher, we recommend you to update dependency `symfony/property-info` to at least 7.1.0
- `LiveProp`: Pass the property name as second parameter of the `modifier` callable
- Add compatibility layer to fix deprecation with `Symfony\Component\PropertyInfo\PropertyInfoExtractor::getTypes()`.
If you use PHP 8.2 or higher, we recommend you to update dependency `symfony/property-info` to at least 7.1.0
## 2.25.0
- Add support for [Symfony UID](https://symfony.com/doc/current/components/uid.html) hydration/dehydration
- `ComponentWithFormTrait` now correctly checks for a `TranslatableInterface` placeholder for `<select>` elements
- Fix `LiveComponentHydrator::hydrateValue()` to hydrate null values
- Add support for [Symfony UID](https://symfony.com/doc/current/components/uid.html) hydration/dehydration
- `ComponentWithFormTrait` now correctly checks for a `TranslatableInterface` placeholder for `<select>` elements
- Fix `LiveComponentHydrator::hydrateValue()` to hydrate null values
## 2.23.0
- Allow configuring the secret used to compute fingerprints and checksums.
- Prevent `__component` property to be serialized when called `JSON.stringify()`
- Allow configuring the secret used to compute fingerprints and checksums.
- Prevent `__component` property to be serialized when called `JSON.stringify()`
## 2.22.0
- Remove CSRF tokens - rely on same-origin/CORS instead
- Remove CSRF tokens - rely on same-origin/CORS instead
## 2.19.0
- Add `submitForm()` to `TestLiveComponent`.
- Add `live_action` Twig function
- Add `submitForm()` to `TestLiveComponent`.
- Add `live_action` Twig function
## 2.18.0
- Add parameter to `TestLiveComponent::call()` to add files to the request
- Add parameter to `TestLiveComponent::call()` to add files to the request
## 2.17.0
- Add `modifier` option in `LiveProp` so options can be modified at runtime.
- Fix collections hydration with serializer in LiveComponents
- Add `loading` attribute to defer the rendering on the component after the
page is rendered, either when the page loads (`loading="defer"`) or when
the component becomes visible in the viewport (`loading="lazy"`).
- Deprecate the `defer` attribute.
- Add `UrlMapping` configuration object for URL bindings in LiveComponents
- Add `modifier` option in `LiveProp` so options can be modified at runtime.
- Fix collections hydration with serializer in LiveComponents
- Add `loading` attribute to defer the rendering on the component after the
page is rendered, either when the page loads (`loading="defer"`) or when
the component becomes visible in the viewport (`loading="lazy"`).
- Deprecate the `defer` attribute.
- Add `UrlMapping` configuration object for URL bindings in LiveComponents
## 2.16.0
- LiveComponents is now stable and no longer experimental 🥳
- [BC BREAK] The `data-action-name` attribute behavior was removed in favor of
using Stimulus "action parameters" and `data-live-action-param`. This is a
breaking change if you were using the `data-action-name` attribute directly
in your templates. #1418
- LiveComponents is now stable and no longer experimental 🥳
- [BC BREAK] The `data-action-name` attribute behavior was removed in favor of
using Stimulus "action parameters" and `data-live-action-param`. This is a
breaking change if you were using the `data-action-name` attribute directly
in your templates. #1418
To upgrade your application, follow these changes:
@@ -145,100 +147,100 @@ $this->assertComponentNotEmitEvent($render, 'another-event');
>Save</button>
```
- [BC BREAK] The `data-event` attribute was removed in favor of using Stimulus
"action parameters": rename `data-event` to `data-live-event-param`. Additionally,
if you were passing arguments to the event name, use action parameter attributes
for those as well - e.g. `data-live-foo-param="bar"`. #1418
- [BC BREAK] The `data-event` attribute was removed in favor of using Stimulus
"action parameters": rename `data-event` to `data-live-event-param`. Additionally,
if you were passing arguments to the event name, use action parameter attributes
for those as well - e.g. `data-live-foo-param="bar"`. #1418
- Reverted setting `ignoreActiveValue: true` in Idiomorph #1548
- New placeholder macro to generate defer/lazy skeleton #1532
- improve TestLiveComponent::actingAs() #1461
- Drop Twig 2 support #1436
- Add better error message when hydrating dates #1431
- Store TemplateMap in build_dir #1525
- Reverted setting `ignoreActiveValue: true` in Idiomorph #1548
- New placeholder macro to generate defer/lazy skeleton #1532
- improve TestLiveComponent::actingAs() #1461
- Drop Twig 2 support #1436
- Add better error message when hydrating dates #1431
- Store TemplateMap in build_dir #1525
## 2.15.0
- [BC BREAK] The `data-live-id` attribute was changed to `id` #1484
- Fixed child handling bug during re-rendering introduced with the
new morphing library in 2.14.0 #1484
- Fix bug where the active input would maintain its value, but lose its cursor position #1501
- Restrict Twig 3.9 for now #1486
- [BC BREAK] The `data-live-id` attribute was changed to `id` #1484
- Fixed child handling bug during re-rendering introduced with the
new morphing library in 2.14.0 #1484
- Fix bug where the active input would maintain its value, but lose its cursor position #1501
- Restrict Twig 3.9 for now #1486
## 2.14.1
- Fixed a regression in the testing tools related to the default HTTP
method change
- Fixed a regression in the testing tools related to the default HTTP
method change
## 2.14.0
- [BC BREAK] DOM morphing changed from `morphdom` to `idiomorph`. As this is
a different morphing library, there may be some edge cases where the
morphing behavior is different.
- Add support for URL binding in `LiveProp`
- Allow multiple `LiveListener` attributes on a single method
- Requests to LiveComponent are sent as POST by default
- Add method prop to AsLiveComponent to still allow GET requests, usage: `#[AsLiveComponent(method: 'get')]`
- Add a new `urlReferenceType` parameter to `AsLiveComponent`, which allows to
generate different type URL (e.g. absolute) for the component Ajax calls
- The `symfony/serializer` dependency is now optional
- Added a `data-skip-morph` attribute to allow skipping morphing of an element
(the element's attributes will be morphed, but its inner HTML will be overwritten
instead of morphed)
- Added an entry to the packages' `package.json` file so that `@symfony/ux-live-component`
will appear in the user's `importmap.php` file if using AssetMapper. This
will allow using the JavaScript from the package without extra setup.
- Fixed edge-case rendering bug where a 2nd Ajax request might start before
the 1st finished processing
- Fix usage of `{% embed %}` with `{% block %}` in `<twig:>` components
- Fixed `data-loading` not working when on root element of a component
- Fixed error when `class` attributes contained a space at start or end
- Fixed loading directives being matched in a child component
- [BC BREAK] DOM morphing changed from `morphdom` to `idiomorph`. As this is
a different morphing library, there may be some edge cases where the
morphing behavior is different.
- Add support for URL binding in `LiveProp`
- Allow multiple `LiveListener` attributes on a single method
- Requests to LiveComponent are sent as POST by default
- Add method prop to AsLiveComponent to still allow GET requests, usage: `#[AsLiveComponent(method: 'get')]`
- Add a new `urlReferenceType` parameter to `AsLiveComponent`, which allows to
generate different type URL (e.g. absolute) for the component Ajax calls
- The `symfony/serializer` dependency is now optional
- Added a `data-skip-morph` attribute to allow skipping morphing of an element
(the element's attributes will be morphed, but its inner HTML will be overwritten
instead of morphed)
- Added an entry to the packages' `package.json` file so that `@symfony/ux-live-component`
will appear in the user's `importmap.php` file if using AssetMapper. This
will allow using the JavaScript from the package without extra setup.
- Fixed edge-case rendering bug where a 2nd Ajax request might start before
the 1st finished processing
- Fix usage of `{% embed %}` with `{% block %}` in `<twig:>` components
- Fixed `data-loading` not working when on root element of a component
- Fixed error when `class` attributes contained a space at start or end
- Fixed loading directives being matched in a child component
## 2.13.2
- Revert "Change JavaScript package to `type: module`"
- Revert "Change JavaScript package to `type: module`"
## 2.13.0
- Add deferred/lazy rendering of Live Components.
- Fix option tag synchronization.
- Handle array-like objects when working with checkboxes.
- Add Symfony 7 support.
- Normalize "true" & "false" model values
- Fix DTO hydration from phpdoc typehints.
- Fix instantiating LiveComponentMetadata multiple times.
- Change JavaScript package to `type: module`.
- Throwing an error when setting an invalid model name.
- Add deferred/lazy rendering of Live Components.
- Fix option tag synchronization.
- Handle array-like objects when working with checkboxes.
- Add Symfony 7 support.
- Normalize "true" & "false" model values
- Fix DTO hydration from phpdoc typehints.
- Fix instantiating LiveComponentMetadata multiple times.
- Change JavaScript package to `type: module`.
- Throwing an error when setting an invalid model name.
## 2.12.0
- Add support for (de)hydrating DTO classes in `LiveProp`.
- Fixed `emit()` method of `TestLiveComponent` to properly test events.
- Add `actionAs()` to `TestLiveComponent`.
- Fixed rendering bug when using Chrome's translation feature.
- Add `onUpdated()` hook for `LiveProp`.
- Fix support for Alpine.js & live components.
- Add support for (de)hydrating DTO classes in `LiveProp`.
- Fixed `emit()` method of `TestLiveComponent` to properly test events.
- Add `actionAs()` to `TestLiveComponent`.
- Fixed rendering bug when using Chrome's translation feature.
- Add `onUpdated()` hook for `LiveProp`.
- Fix support for Alpine.js & live components.
## 2.11.0
- Add helper for testing live components.
- Add initial file upload support.
- Respect `data-turbo="false"` when handling redirects.
- Fix checksum calculation for deeply nested data.
- Add helper for testing live components.
- Add initial file upload support.
- Respect `data-turbo="false"` when handling redirects.
- Fix checksum calculation for deeply nested data.
## 2.9.0
- Add support for symfony/asset-mapper
- Add support for symfony/asset-mapper
## 2.8.1
- Increased the priority of `LiveComponentSubscriber` `ControllerEvent` from
0 to 10 to fix incompatibility with SensioFrameworkExtraBundle.
- Increased the priority of `LiveComponentSubscriber` `ControllerEvent` from
0 to 10 to fix incompatibility with SensioFrameworkExtraBundle.
## 2.8.0
- [BC BREAK]: The `exposed` option was changed to `writable` in `LiveProp`:
- [BC BREAK]: The `exposed` option was changed to `writable` in `LiveProp`:
```diff
-#[LiveProp(exposed: ['email', 'plainPassword'])]
@@ -246,83 +248,83 @@ $this->assertComponentNotEmitEvent($render, 'another-event');
public User $user;
```
- [BC BREAK]: `LiveProp` values are no longer automatically (de)hydrated
through Symfony's serializer. Use `LiveProp(useSerializerForHydration: true)`
to activate this. Also, a `serializationContext` option was added to
`LiveProp`.
- [BC BREAK]: `LiveProp` values are no longer automatically (de)hydrated
through Symfony's serializer. Use `LiveProp(useSerializerForHydration: true)`
to activate this. Also, a `serializationContext` option was added to
`LiveProp`.
- [BC BREAK]: Child components are no longer automatically re-rendered when
a parent component re-renders and the value of one of the props passed to
the child has changed. Pass `acceptUpdatesFromParent: true` to any `LiveProp`
on the child component to re-enable this behavior.
- [BC BREAK]: Child components are no longer automatically re-rendered when
a parent component re-renders and the value of one of the props passed to
the child has changed. Pass `acceptUpdatesFromParent: true` to any `LiveProp`
on the child component to re-enable this behavior.
- Non-persisted entity objects can now be used with `LiveProp`: it will be
serialized using the serializer.
- Non-persisted entity objects can now be used with `LiveProp`: it will be
serialized using the serializer.
- Better support for using arrays with `LiveProp`.
- Better support for using arrays with `LiveProp`.
- Smart rendering system! If you have JavaScript that makes changes to
the DOM inside a live component, those changes will now be _kept_ when
the component is re-rendered. This has limitations - see the documentation.
- Smart rendering system! If you have JavaScript that makes changes to
the DOM inside a live component, those changes will now be _kept_ when
the component is re-rendered. This has limitations - see the documentation.
- You can now `emit()` events to communicate between components.
- You can now `emit()` events to communicate between components.
- You can now dispatch DOM/browser events from components.
- You can now dispatch DOM/browser events from components.
- Boolean checkboxes are now supported. Of a checkbox does **not** have a
`value` attribute, then the associated `LiveProp` will be set to a boolean
when the input is checked/unchecked.
- Boolean checkboxes are now supported. Of a checkbox does **not** have a
`value` attribute, then the associated `LiveProp` will be set to a boolean
when the input is checked/unchecked.
- A `format` option was added to `LiveProp` to control how `DateTime`
properties are (de)hydrated.
- A `format` option was added to `LiveProp` to control how `DateTime`
properties are (de)hydrated.
- Added support for setting `writable` to a property that is an object
(previously, only scalar values were supported). The object is passed
through the serializer.
- Added support for setting `writable` to a property that is an object
(previously, only scalar values were supported). The object is passed
through the serializer.
- Invalid data sent by the user is now handled in a robust way. Previously,
if the user sent invalid data (e.g. a string for a `LiveProp` that has
an `int` type), the component update would break. Now, if the new data
cannot be hydrated onto the object during a re-render, the last valid
value is used.
- Invalid data sent by the user is now handled in a robust way. Previously,
if the user sent invalid data (e.g. a string for a `LiveProp` that has
an `int` type), the component update would break. Now, if the new data
cannot be hydrated onto the object during a re-render, the last valid
value is used.
- When using `ValidatableComponentTrait`, a new `_errors` variable is sent
to the template, which is easier to use!
- When using `ValidatableComponentTrait`, a new `_errors` variable is sent
to the template, which is easier to use!
- Several bug fixes to parent - child components - see #700.
- Several bug fixes to parent - child components - see #700.
- Fixed handling of boolean attributes to a component - see #710.
- Fixed handling of boolean attributes to a component - see #710.
- Fixed performance calculating component fingerprint for large components.
- Fixed performance calculating component fingerprint for large components.
## 2.7.0
- [BC BREAK]: The "key" used to load the controller in your `assets/controllers.json`
file changed from `typed` to `live`. Update your `assets/controllers.json`
file to change this key.
- [BC BREAK]: The "key" used to load the controller in your `assets/controllers.json`
file changed from `typed` to `live`. Update your `assets/controllers.json`
file to change this key.
- Add a strategy for adding a Stimulus controller to a Twig component - #589.
- Add a strategy for adding a Stimulus controller to a Twig component - #589.
- Added a new `getCompontent()` function in JavaScript as the best way to find
a Component object for a given element.
- Added a new `getCompontent()` function in JavaScript as the best way to find
a Component object for a given element.
- Fixed various bugs related to child component handling - #596
- Fixed various bugs related to child component handling - #596
- Added a new `route` parameter to `AsLiveComponent`, which allows to choose
another route for Ajax calls.
- Added a new `route` parameter to `AsLiveComponent`, which allows to choose
another route for Ajax calls.
- Add `assets/src` to `.gitattributes` to exclude source TypeScript files from
installing.
- Add `assets/src` to `.gitattributes` to exclude source TypeScript files from
installing.
- TypeScript types are now included.
- TypeScript types are now included.
- Added new `response:error` JavaScript component hook for custom handling Ajax errors - #587.
- Added new `response:error` JavaScript component hook for custom handling Ajax errors - #587.
## 2.6.0
- [BC BREAK]: The path to `live_component.xml` changed _and_ the import now
MUST have a `prefix`: you should update your route import accordingly (the
name of the route also changed to `ux_live_component`):
- [BC BREAK]: The path to `live_component.xml` changed _and_ the import now
MUST have a `prefix`: you should update your route import accordingly (the
name of the route also changed to `ux_live_component`):
```diff
# config/routes/ux_live_component.yaml
@@ -332,21 +334,21 @@ live_component:
+ prefix: /_components
```
- Removed `Content-Type` header when returning the empty response redirect.
- Fixed bug when re-rendering SVG's (.#557)
- Removed `Content-Type` header when returning the empty response redirect.
- Fixed bug when re-rendering SVG's (.#557)
## 2.5.0
- [BEHAVIOR CHANGE] Previously, Ajax calls could happen in parallel (if
you changed a model then triggered an action before the model update Ajax
call finished, the action Ajax call would being in parallel). Now, if
an Ajax call is currently happening, any future requests will wait until
it finishes. Then, all queued changes (potentially multiple model updates
or actions) will be sent all at once on the next request.
- [BEHAVIOR CHANGE] Previously, Ajax calls could happen in parallel (if
you changed a model then triggered an action before the model update Ajax
call finished, the action Ajax call would being in parallel). Now, if
an Ajax call is currently happening, any future requests will wait until
it finishes. Then, all queued changes (potentially multiple model updates
or actions) will be sent all at once on the next request.
- [BEHAVIOR CHANGE] Fields with `data-model` will now have their `value` set
automatically when the component initially loads and re-renders. For example,
previously you needed to manually set the value in your component template:
- [BEHAVIOR CHANGE] Fields with `data-model` will now have their `value` set
automatically when the component initially loads and re-renders. For example,
previously you needed to manually set the value in your component template:
```twig
<!-- BEFORE -->
@@ -361,63 +363,63 @@ live_component:
<input data-model="firstName">
```
- [BEHAVIOR CHANGE] The way that child components re-render when a parent re-renders
has changed, but shouldn't be drastically different. Child components will now
avoid re-rendering if no "input" to the component changed _and_ will maintain
any writable `LiveProp` values after the re-render. Also, the re-render happens
in a separate Ajax call after the parent has finished re-rendering.
- [BEHAVIOR CHANGE] The way that child components re-render when a parent re-renders
has changed, but shouldn't be drastically different. Child components will now
avoid re-rendering if no "input" to the component changed _and_ will maintain
any writable `LiveProp` values after the re-render. Also, the re-render happens
in a separate Ajax call after the parent has finished re-rendering.
- [BEHAVIOR CHANGE] If a model is updated, but the new value is equal to the old
one, a re-render will now be avoided.
- [BEHAVIOR CHANGE] If a model is updated, but the new value is equal to the old
one, a re-render will now be avoided.
- [BEHAVIOR CHANGE] Priority of `DoctrineObjectNormalizer` changed from 100 to -100
so that any custom normalizers are used before trying `DoctrineObjectNormalizer`.
- [BEHAVIOR CHANGE] Priority of `DoctrineObjectNormalizer` changed from 100 to -100
so that any custom normalizers are used before trying `DoctrineObjectNormalizer`.
- [BC BREAK] The `live:update-model` and `live:render` events are not longer
dispatched. You can now use the "hook" system directly on the `Component` object/
- [BC BREAK] The `live:update-model` and `live:render` events are not longer
dispatched. You can now use the "hook" system directly on the `Component` object/
- [BC BREAK] The `LiveComponentHydrator::dehydrate()` method now returns a
`DehydratedComponent` object.
- [BC BREAK] The `LiveComponentHydrator::dehydrate()` method now returns a
`DehydratedComponent` object.
- Added a new JavaScript `Component` object, which is attached to the `__component`
property of all root component elements.
- Added a new JavaScript `Component` object, which is attached to the `__component`
property of all root component elements.
- the ability to add `data-loading` behavior, which is only activated
when a specific **action** is triggered - e.g. `<span data-loading="action(save)|show">Loading</span>`.
- the ability to add `data-loading` behavior, which is only activated
when a specific **action** is triggered - e.g. `<span data-loading="action(save)|show">Loading</span>`.
- Added the ability to add `data-loading` behavior, which is only activated
when a specific **model** has been updated - e.g. `<span data-loading="model(firstName)|show">Loading</span>`.
- Added the ability to add `data-loading` behavior, which is only activated
when a specific **model** has been updated - e.g. `<span data-loading="model(firstName)|show">Loading</span>`.
- Unexpected Ajax errors are now displayed in a modal to ease debugging! #467.
- Unexpected Ajax errors are now displayed in a modal to ease debugging! #467.
- Fixed bug where sometimes a live component was broken after hitting "Back:
in your browser - #436.
- Fixed bug where sometimes a live component was broken after hitting "Back:
in your browser - #436.
## 2.4.0
- [BC BREAK] Previously, the `id` attribute was used with `morphdom` as the
"node id" when updating the DOM after a render. This has changed to
`data-live-id`. This is useful when maintaining the correct order of a list
of elements.
- [BC BREAK] Previously, the `id` attribute was used with `morphdom` as the
"node id" when updating the DOM after a render. This has changed to
`data-live-id`. This is useful when maintaining the correct order of a list
of elements.
- [BC BREAK] If using `LiveCollectionType`, the name of the remove field changed
from `button_delete_prototype` to `button_delete` and the add field changed
from `button_add_prototype` to `button_add`. Additionally, the `allow_add`
and `allow_delete` default values were changed from `false` to `true`.
- [BC BREAK] If using `LiveCollectionType`, the name of the remove field changed
from `button_delete_prototype` to `button_delete` and the add field changed
from `button_add_prototype` to `button_add`. Additionally, the `allow_add`
and `allow_delete` default values were changed from `false` to `true`.
- [BEHAVIOR CHANGE] If an action Ajax call is still processing and a
model update occurs, the component will _no_ longer re-render. The
model will be updated internally, but not re-rendered (so, any
model updates would effectively have the `|norender` modifier). See #419.
- [BEHAVIOR CHANGE] If an action Ajax call is still processing and a
model update occurs, the component will _no_ longer re-render. The
model will be updated internally, but not re-rendered (so, any
model updates would effectively have the `|norender` modifier). See #419.
## 2.3.0
- [BC BREAK] The `data-action="live#update"` attribute must now be
removed from **nearly** all elements. This is because LiveComponents
now automatically listens to the `input` event on all elements
with a `data-model` attribute and updates the data. If you previously
used `data-action="change->live#update"` to list on the `change`
event, now you should use the `on(change)` modifier inside `data-model`.
- [BC BREAK] The `data-action="live#update"` attribute must now be
removed from **nearly** all elements. This is because LiveComponents
now automatically listens to the `input` event on all elements
with a `data-model` attribute and updates the data. If you previously
used `data-action="change->live#update"` to list on the `change`
event, now you should use the `on(change)` modifier inside `data-model`.
```twig
<!-- BEFORE -->
@@ -432,9 +434,9 @@ live_component:
>
```
- [BC BREAK] The `live#updateDefer` action was removed entirely.
Now, to update a model without triggering a re-render, use the
`norender` modifier for `data-model`:
- [BC BREAK] The `live#updateDefer` action was removed entirely.
Now, to update a model without triggering a re-render, use the
`norender` modifier for `data-model`:
```twig
<!-- BEFORE -->
@@ -449,13 +451,13 @@ live_component:
>
```
- [BC BREAK] The `name` attribute is no longer automatically used to
update a model when a parent component has `data-action="change->live#update"`.
To make a form's fields behave like "model" fields (but using the
`name` attribute instead of `data-model`) you need to add a `data-model`
attribute to the `<form>` element around your fields (NOTE: the
new attribute is automatically added to your `form` element when
using `ComponentWithFormTrait`):
- [BC BREAK] The `name` attribute is no longer automatically used to
update a model when a parent component has `data-action="change->live#update"`.
To make a form's fields behave like "model" fields (but using the
`name` attribute instead of `data-model`) you need to add a `data-model`
attribute to the `<form>` element around your fields (NOTE: the
new attribute is automatically added to your `form` element when
using `ComponentWithFormTrait`):
```twig
<!-- BEFORE -->
@@ -475,72 +477,72 @@ live_component:
## 2.2.0
- The bundle now properly exposes a `live` controller, which can be
imported via your `assets/controllers.json` file (like any other
UX package). Previously, the controller needed to be imported and
registered with Stimulus directly (usually in your `assets/bootstrap.js`
file). That is no longer needed.
- The bundle now properly exposes a `live` controller, which can be
imported via your `assets/controllers.json` file (like any other
UX package). Previously, the controller needed to be imported and
registered with Stimulus directly (usually in your `assets/bootstrap.js`
file). That is no longer needed.
- Add a generic `LiveCollectionType` and `LiveCollectionTrait`
- Allow to disable CSRF per component
- Add a generic `LiveCollectionType` and `LiveCollectionTrait`
- Allow to disable CSRF per component
## 2.1.0
- Your component's live "data" is now send over Ajax as a JSON string.
Previously data was sent as pure query parameters or as pure POST data.
However, this made it impossible to keep certain data types, like
distinguishing between `null` and `''`. This has no impact on end-users.
- Your component's live "data" is now send over Ajax as a JSON string.
Previously data was sent as pure query parameters or as pure POST data.
However, this made it impossible to keep certain data types, like
distinguishing between `null` and `''`. This has no impact on end-users.
- Added `data-live-ignore` attribute. If included in an element, that element
will not be updated on re-render.
- Added `data-live-ignore` attribute. If included in an element, that element
will not be updated on re-render.
- `ComponentWithFormTrait` no longer has a `setForm()` method. But there
is also no need to call it anymore. To pass an already-built form to
your component, pass it as a `form` var to `component()`. If you have
a custom `mount()`, you no longer need to call `setForm()` or anything else.
- `ComponentWithFormTrait` no longer has a `setForm()` method. But there
is also no need to call it anymore. To pass an already-built form to
your component, pass it as a `form` var to `component()`. If you have
a custom `mount()`, you no longer need to call `setForm()` or anything else.
- The Live Component AJAX endpoints now return HTML in all situations
instead of JSON.
- The Live Component AJAX endpoints now return HTML in all situations
instead of JSON.
- Ability to send live action arguments to backend
- Ability to send live action arguments to backend
- [BC BREAK] Remove `init_live_component()` twig function, use `{{ attributes }}` instead:
- [BC BREAK] Remove `init_live_component()` twig function, use `{{ attributes }}` instead:
```diff
- <div {{ init_live_component() }}>
+ <div {{ attributes }}>
```
- [BC BREAK] Replace property hydration system with `symfony/serializer` normalizers. This
is a BC break if you've created custom hydrators. They'll need to be converted to
normalizers.
- [BC BREAK] Replace property hydration system with `symfony/serializer` normalizers. This
is a BC break if you've created custom hydrators. They'll need to be converted to
normalizers.
- [BC BREAK] Rename `BeforeReRender` attribute to `PreReRender`.
- [BC BREAK] Rename `BeforeReRender` attribute to `PreReRender`.
## 2.0.0
- Support for `stimulus` version 2 was removed and support for `@hotwired/stimulus`
version 3 was added. See the [@symfony/stimulus-bridge CHANGELOG](https://github.com/symfony/stimulus-bridge/blob/main/CHANGELOG.md#300)
for more details.
- Support for `stimulus` version 2 was removed and support for `@hotwired/stimulus`
version 3 was added. See the [@symfony/stimulus-bridge CHANGELOG](https://github.com/symfony/stimulus-bridge/blob/main/CHANGELOG.md#300)
for more details.
- Require live components have a default action (`__invoke()` by default) to enable
controller annotations/attributes (ie `@Security/@Cache`). Added `DefaultActionTrait`
helper.
- Require live components have a default action (`__invoke()` by default) to enable
controller annotations/attributes (ie `@Security/@Cache`). Added `DefaultActionTrait`
helper.
- When a model is updated, a new `live:update-model` event is dispatched. Parent
components (in a parent-child component setup) listen to this and automatically
try to update any model with a matching name. A `data-model-map` was also added
to map child component model names to a parent - see #113.
- When a model is updated, a new `live:update-model` event is dispatched. Parent
components (in a parent-child component setup) listen to this and automatically
try to update any model with a matching name. A `data-model-map` was also added
to map child component model names to a parent - see #113.
- Child components are now re-rendered if the parent components passes new data
to the child when rendering - see #113.
- Child components are now re-rendered if the parent components passes new data
to the child when rendering - see #113.
- Minimum PHP version was bumped to 8.0 so that PHP 8 attributes could be used.
- Minimum PHP version was bumped to 8.0 so that PHP 8 attributes could be used.
- The `LiveComponentInterface` was dropped and replaced by the `AsLiveComponent` attribute,
which extends the new `AsTwigComponent` from the TwigComponent library. All
other annotations (e.g. `@LiveProp` and `@LiveAction`) were also replaced by
PHP 8 attributes.
- The `LiveComponentInterface` was dropped and replaced by the `AsLiveComponent` attribute,
which extends the new `AsTwigComponent` from the TwigComponent library. All
other annotations (e.g. `@LiveProp` and `@LiveAction`) were also replaced by
PHP 8 attributes.
Before:
@@ -618,4 +620,4 @@ final class NotificationComponent
## Pre-Release
- The LiveComponent library was introduced!
- The LiveComponent library was introduced!

View File

@@ -25,10 +25,10 @@ Help Symfony by [sponsoring][3] its development!
## Resources
- [Documentation](https://symfony.com/bundles/ux-live-component/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
- [Documentation](https://symfony.com/bundles/ux-live-component/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
[1]: https://symfony.com/backers
[2]: https://mercure.rocks

View File

@@ -6,9 +6,10 @@ JavaScript assets of the [symfony/ux-live-component](https://packagist.org/packa
This npm package is **reserved for advanced users** who want to decouple their JavaScript dependencies from their PHP dependencies (e.g., when building Docker images, running JavaScript-only pipelines, etc.).
We **strongly recommend not installing this package directly**, but instead install the PHP package [symfony/ux-live-component](https://packagist.org/packages/symfony/ux-live-component) in your Symfony application with [Flex](https://github.com/symfony/flex) enabled.
We **strongly recommend not installing this package directly**, but instead install the PHP package [symfony/ux-live-component](https://packagist.org/packages/symfony/ux-live-component) in your Symfony application with [Flex](https://github.com/symfony/flex) enabled.
If you still want to install this package directly, please make sure its version exactly matches [symfony/ux-live-component](https://packagist.org/packages/symfony/ux-live-component) PHP package version:
```shell
composer require symfony/ux-live-component:2.23.0
npm add @symfony/ux-live-component@2.23.0
@@ -18,7 +19,7 @@ npm add @symfony/ux-live-component@2.23.0
## Resources
- [Documentation](https://symfony.com/bundles/ux-live-component/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
- [Documentation](https://symfony.com/bundles/ux-live-component/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)

View File

@@ -2503,7 +2503,7 @@ var LoadingPlugin_default = class {
}
getLoadingDirectives(component, element) {
const loadingDirectives = [];
let matchingElements = [...Array.from(element.querySelectorAll("[data-loading]"))];
let matchingElements = Array.from(element.querySelectorAll("[data-loading]"));
matchingElements = matchingElements.filter((elt) => elementBelongsToThisComponent(elt, component));
if (element.hasAttribute("data-loading")) {
matchingElements = [element, ...matchingElements];

View File

@@ -25,9 +25,7 @@
"test": "pnpm run test:unit && pnpm run test:browser",
"test:unit": "../../../bin/unit_test_package.sh .",
"test:browser": "playwright test",
"test:browser:ui": "playwright test --ui",
"check": "biome check",
"ci": "biome ci"
"test:browser:ui": "playwright test --ui"
},
"symfony": {
"controllers": {

View File

@@ -173,7 +173,7 @@ export default class implements PluginInterface {
getLoadingDirectives(component: Component, element: HTMLElement | SVGElement) {
const loadingDirectives: ElementLoadingDirectives[] = [];
let matchingElements = [...Array.from(element.querySelectorAll('[data-loading]'))];
let matchingElements = Array.from(element.querySelectorAll('[data-loading]'));
// ignore elements which are inside a nested "live" component
matchingElements = matchingElements.filter((elt) => elementBelongsToThisComponent(elt, component));

View File

@@ -1,5 +1,5 @@
[data-loading=""],
[data-loading="show"],
[data-loading*="|show"] {
[data-loading=''],
[data-loading='show'],
[data-loading*='|show'] {
display: none;
}

View File

@@ -1,5 +1,4 @@
Please do not submit any Pull Requests here. They will be closed.
---
## Please do not submit any Pull Requests here. They will be closed.
Please submit your PR here instead:
https://github.com/symfony/ux

View File

@@ -1,20 +1,20 @@
name: Close Pull Request
on:
pull_request_target:
types: [opened]
pull_request_target:
types: [opened]
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/ux
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!

View File

@@ -1,3 +1,3 @@
branches: ["2.x"]
maintained_branches: ["2.x"]
doc_dir: "doc"
branches: ['2.x']
maintained_branches: ['2.x']
doc_dir: 'doc'

View File

@@ -2,33 +2,34 @@
## 2.32
- Add `Map::removeAllMarkers()`, `Map::removeAllPolygons()`, `Map::removeAllPolylines()`, `Map::removeAllCircles()` and `Map::removeAllRectangles()` methods
- Add `Map::removeAllMarkers()`, `Map::removeAllPolygons()`, `Map::removeAllPolylines()`, `Map::removeAllCircles()` and `Map::removeAllRectangles()` methods
## 2.31
- Add `fitBoundsToMarkers` parameter to `ux_map()` Twig function
- Add `fitBoundsToMarkers` parameter to `ux_map()` Twig function
## 2.30
- Ensure compatibility with PHP 8.5
- Deprecate option `title` from `Polygon`, `Polyline`, `Rectangle` and `Circle` in favor of `infoWindow`
- Ensure compatibility with PHP 8.5
- Deprecate option `title` from `Polygon`, `Polyline`, `Rectangle` and `Circle` in favor of `infoWindow`
## 2.29.0
- Add Symfony 8 support
- Add `Cluster` class and `ClusteringAlgorithmInterface` with two implementations `GridClusteringAlgorithm` and `MortonClusteringAlgorithm`
- Add Symfony 8 support
- Add `Cluster` class and `ClusteringAlgorithmInterface` with two implementations `GridClusteringAlgorithm` and `MortonClusteringAlgorithm`
## 2.28
- Add `minZoom` and `maxZoom` options to `Map` to set the minimum and maximum zoom levels
- Add `minZoom` and `maxZoom` options to `Map` to set the minimum and maximum zoom levels
## 2.27
- The `fitBoundsToMarkers` option is not overridden anymore when using the `Map` LiveComponent, but now respects the value you defined.
You may encounter unwanted behavior when adding/removing elements to the map.
To use the previous behavior, you must call `$this->getMap()->fitBoundsToMarkers(false)` in your LiveComponent's live actions
- The `fitBoundsToMarkers` option is not overridden anymore when using the `Map` LiveComponent, but now respects the value you defined.
You may encounter unwanted behavior when adding/removing elements to the map.
To use the previous behavior, you must call `$this->getMap()->fitBoundsToMarkers(false)` in your LiveComponent's live actions
- Add support for creating `Circle` by passing a `Point` and a radius (in meters) to the `Circle` constructor, e.g.:
- Add support for creating `Circle` by passing a `Point` and a radius (in meters) to the `Circle` constructor, e.g.:
```php
$map->addCircle(new Circle(
center: new Point(48.856613, 2.352222), // Paris
@@ -36,7 +37,8 @@ $map->addCircle(new Circle(
));
```
- Add support for creating `Rectangle` by passing two `Point` instances to the `Rectangle` constructor, e.g.:
- Add support for creating `Rectangle` by passing two `Point` instances to the `Rectangle` constructor, e.g.:
```php
$map->addRectangle(new Rectangle(
southWest: new Point(48.856613, 2.352222), // Paris
@@ -44,8 +46,9 @@ $map->addRectangle(new Rectangle(
));
```
- Deprecate property `rawOptions` from `ux:map:*:before-create` events, in favor of `bridgeOptions` instead.
- Map options can now be configured and overridden through the `ux:map:pre-connect` event:
- Deprecate property `rawOptions` from `ux:map:*:before-create` events, in favor of `bridgeOptions` instead.
- Map options can now be configured and overridden through the `ux:map:pre-connect` event:
```js
this.element.addEventListener('ux:map:pre-connect', (event) => {
// Override the map center and zoom
@@ -61,11 +64,13 @@ this.element.addEventListener('ux:map:pre-connect', (event) => {
};
});
```
- Add `extra` data support to `Map`, which can be accessed in `ux:map:pre-connect` and `ux:map:connect` events
- Add `extra` data support to `Map`, which can be accessed in `ux:map:pre-connect` and `ux:map:connect` events
## 2.26
- Add support for creating `Polygon` with holes, by passing an array of `array<Point>` as `points` parameter to the `Polygon` constructor, e.g.:
- Add support for creating `Polygon` with holes, by passing an array of `array<Point>` as `points` parameter to the `Polygon` constructor, e.g.:
```php
// Draw a polygon with a hole in it, on the French map
$map->addPolygon(new Polygon(points: [
@@ -89,43 +94,43 @@ $map->addPolygon(new Polygon(points: [
## 2.25
- Downgrade PHP requirement from 8.3 to 8.1
- Downgrade PHP requirement from 8.3 to 8.1
## 2.24
- Installing the package in a Symfony app using Flex won't add the `@symfony/ux-map` dependency to the `package.json` file anymore.
- Add `Icon` to customize a `Marker` icon (URL or SVG content)
- Add parameter `id` to `Marker`, `Polygon` and `Polyline` constructors
- Add method `Map::removeMarker(string|Marker $markerOrId)`
- Add method `Map::removePolygon(string|Polygon $polygonOrId)`
- Add method `Map::removePolyline(string|Polyline $polylineOrId)`
- Installing the package in a Symfony app using Flex won't add the `@symfony/ux-map` dependency to the `package.json` file anymore.
- Add `Icon` to customize a `Marker` icon (URL or SVG content)
- Add parameter `id` to `Marker`, `Polygon` and `Polyline` constructors
- Add method `Map::removeMarker(string|Marker $markerOrId)`
- Add method `Map::removePolygon(string|Polygon $polygonOrId)`
- Add method `Map::removePolyline(string|Polyline $polylineOrId)`
## 2.23
- Add `DistanceUnit` to represent distance units (`m`, `km`, `miles`, `nmi`) and
ease conversion between units.
- Add `DistanceCalculatorInterface` interface and three implementations:
`HaversineDistanceCalculator`, `SphericalCosineDistanceCalculator` and `VincentyDistanceCalculator`.
- Add `CoordinateUtils` helper, to convert decimal coordinates (`43.2109`) in DMS (`56° 78' 90"`)
- Add `DistanceUnit` to represent distance units (`m`, `km`, `miles`, `nmi`) and
ease conversion between units.
- Add `DistanceCalculatorInterface` interface and three implementations:
`HaversineDistanceCalculator`, `SphericalCosineDistanceCalculator` and `VincentyDistanceCalculator`.
- Add `CoordinateUtils` helper, to convert decimal coordinates (`43.2109`) in DMS (`56° 78' 90"`)
## 2.22
- Add method `Symfony\UX\Map\Renderer\AbstractRenderer::tapOptions()`, to allow Renderer to modify options before rendering a Map.
- Add `ux_map.google_maps.default_map_id` configuration to set the Google ``Map ID``
- Add `ComponentWithMapTrait` to ease maps integration in [Live Components](https://symfony.com/bundles/ux-live-component/current/index.html)
- Add `Polyline` support
- Add method `Symfony\UX\Map\Renderer\AbstractRenderer::tapOptions()`, to allow Renderer to modify options before rendering a Map.
- Add `ux_map.google_maps.default_map_id` configuration to set the Google `Map ID`
- Add `ComponentWithMapTrait` to ease maps integration in [Live Components](https://symfony.com/bundles/ux-live-component/current/index.html)
- Add `Polyline` support
## 2.20
- Deprecate `render_map` Twig function (will be removed in 2.21). Use
`ux_map` or the `<twig:ux:map />` Twig component instead.
- Add `ux_map` Twig function (replaces `render_map` with a more flexible
interface)
- Add `<twig:ux:map />` Twig component
- The importmap entry `@symfony/ux-map/abstract-map-controller` can be removed
from your importmap, it is no longer needed.
- Add `Polygon` support
- Deprecate `render_map` Twig function (will be removed in 2.21). Use
`ux_map` or the `<twig:ux:map />` Twig component instead.
- Add `ux_map` Twig function (replaces `render_map` with a more flexible
interface)
- Add `<twig:ux:map />` Twig component
- The importmap entry `@symfony/ux-map/abstract-map-controller` can be removed
from your importmap, it is no longer needed.
- Add `Polygon` support
## 2.19
- Component added
- Component added

View File

@@ -7,7 +7,7 @@ https://github.com/symfony/ux to create issues or submit pull requests.
## Resources
- [Documentation](https://symfony.com/bundles/ux-map/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)
- [Documentation](https://symfony.com/bundles/ux-map/current/index.html)
- [Report issues](https://github.com/symfony/ux/issues) and
[send Pull Requests](https://github.com/symfony/ux/pulls)
in the [main Symfony UX repository](https://github.com/symfony/ux)

Some files were not shown because too many files have changed in this diff Show More