ux icon indicating copy to clipboard operation
ux copied to clipboard

[Svelte] Introduce Svelte UX component

Open ChqThomas opened this issue 3 years ago • 2 comments

Q A
Bug fix? no
New feature? yes
Tickets N/A
License MIT

This PR introduces a UX Svelte component which allows to render Svelte components inside Twig templates, with the ability to pass down props to Svelte components from Twig. It is implemented in the same way as the UX React component and the UX Vue component for coherence.

  1. Install and configure the svelte-loader :
$ yarn add svelte-loader@^3.0.0 --dev

Enable it in your webpack.config.js file : This part could be simplified by adding a .enableSvelteLoader() method to the webpack-encore API.

// webpack.config.js
Encore
    .addLoader(
        {
            test: /\.svelte$/,
            loader: "svelte-loader",
            // Additional options to enable hot reload
            options: {
                compilerOptions: {
                    dev: !Encore.isProduction(),
                },
                hotReload: !Encore.isProduction(),
            },
        },
        {
            // required to prevent errors from Svelte on Webpack 5+, omit on Webpack 4
            test: /node_modules\/svelte\/.*\.mjs$/,
            resolve: {
                fullySpecified: false
            }
        }
    );
        
// At the end of the file, replace this line :
module.exports = Encore.getWebpackConfig();

// With those lines :
let config = Encore.getWebpackConfig();
config.resolve.mainFields = ['svelte', 'browser', 'module', 'main'];
config.resolve.extensions = ['.mjs', '.js', '.svelte'];
let svelte = config.module.rules.pop();
config.module.rules.unshift(svelte);
module.exports = config;
  1. Call registerSvelteControllerComponents in app.js to register Svelte components
import { registerSvelteControllerComponents } from "@symfony/ux-svelte";

registerSvelteControllerComponents(require.context('./svelte/controllers', true, /\.svelte$/));
  1. Create Svelte "controller components" (eg. Hello.svelte) inside the folder specified above (here assets/svelte/controllers)
// assets/svelte/controllers/Hello.svelte
<script>
    export let name = "Symfony";
</script>

<div>Hello {name}</div>

In the same way than the UX React and UX Vue components, there is a Twig helper function provided by the bundle : the first parameter is the name of your component, the second are the props that will be passed down :

<div {{ svelte_component('Hello', { name: 'Symfony UX' }) }}></div>

There is also an optional third parameter called intro that tells the Svelte component to play transitions on initial render

<div {{ svelte_component('HelloWithTransition', { name: 'Symfony UX with intial transition' }, true) }}></div>

The implementation was heavily inspired by the work from @tgalopin in https://github.com/symfony/ux/pull/329 and from @t-richard in https://github.com/symfony/ux/pull/426 !

ChqThomas avatar Oct 09 '22 13:10 ChqThomas

that's really a great PR . as you said this could be simplified by mergin this PR

ahmedyakoubi avatar Oct 09 '22 14:10 ahmedyakoubi

Reorganization done :)

I have issues setting up multiple tests in the same file with jest, Svelte seems not happy when the DOM is cleared before his $destroy method is called, and it crash when it happens two times in a row, haven't figured out why yet ...

ChqThomas avatar Oct 10 '22 20:10 ChqThomas

Hello. Any news on this? This PR looks amazing 😃

YummYume avatar Nov 23 '22 19:11 YummYume

Sorry for the delay on this! @ChqThomas could you also update .github/workflows/test.yaml. Currently, new packages need to be added there to trigger them to build in the CI. Currently, your nice tests aren't running :).

weaverryan avatar Jan 20 '23 16:01 weaverryan

Sorry for the delay on this! @ChqThomas could you also update .github/workflows/test.yaml. Currently, new packages need to be added there to trigger them to build in the CI. Currently, your nice tests aren't running :).

@weaverryan Thanks for the review, I added them ! The low-deps test is failing because in webpack-encore-bundle v1.11.0 the stimulus controller renderer was converting boolean values to integer :

Expected : data-symfony--ux-svelte--svelte-intro-value="true" Actual : data-symfony--ux-svelte--svelte-intro-value="1"

Do you have any idea on how to handle both versions?

ChqThomas avatar Jan 23 '23 20:01 ChqThomas

You can just bump the minimum-required version of Encore in your composer.json to whatever version fixed this :)

weaverryan avatar Jan 24 '23 15:01 weaverryan

Done 👍 If approved, I could take care of the example page for ux.symfony.com in another PR :)

ChqThomas avatar Jan 24 '23 18:01 ChqThomas

Great ! 😁

ChqThomas avatar Feb 07 '23 21:02 ChqThomas

is this ready to be used?

ciprian-marius avatar Feb 24 '23 22:02 ciprian-marius

is this ready to be used?

Hopefully soon!

@weaverryan Should I start writing the example page for ux.symfony.com ?

ChqThomas avatar Mar 21 '23 18:03 ChqThomas

@ChqThomas Sorry for the delay! Yes please! I rebased your work over to #789 but will merge very shortly.

Thank you!

weaverryan avatar Apr 14 '23 13:04 weaverryan