Giter Site home page Giter Site logo

symfony / ux Goto Github PK

View Code? Open in Web Editor NEW
778.0 35.0 272.0 32.48 MB

Symfony UX initiative: a JavaScript ecosystem for Symfony

Home Page: https://ux.symfony.com/

License: MIT License

PHP 66.07% JavaScript 1.56% CSS 0.07% Twig 7.83% TypeScript 21.37% SCSS 2.93% Vue 0.01% Svelte 0.08% HTML 0.01% Shell 0.09%
symfony javascript

ux's Introduction

Symfony Logo

Symfony UX: a JavaScript ecosystem for Symfony

Symfony UX is an initiative and set of libraries to seamlessly integrate JavaScript tools into your application. For example, want to render a chart with Chart.js? Use UX Chart.js to build the chart in PHP. The JavaScript is handled for you automatically.

That's Symfony UX.

Symfony UX leverages Stimulus for JavaScript and can integrate with Webpack Encore (with the help of Stimulus Bridge) or with AssetMapper

Resources

Let's build an amazing ecosystem together

Symfony UX is an initiative: its aim is to build an ecosystem. To achieve this, we need your help: what other packages could we create in Symfony UX? What about a library that automatically adds an input mask to the text fields of your Symfony forms? Or the ability to make the EntityType render with AJAX auto-completion? Anything you do in JavaScript could be done streamlined as a UX package.

We have some ideas, and we will release more packages in the coming days. The rest is on you: let's create an amazing ecosystem together!

Sponsor

The Symfony UX packages are backed by Mercure.rocks.

Create real-time experiences in minutes! Mercure.rocks provides a realtime API service that is tightly integrated with Symfony: create UIs that update in live with UX Turbo, send notifications with the Notifier component, expose async APIs with API Platform and create low level stuffs with the Mercure component. We maintain and scale the complex infrastructure for you!

Help Symfony by sponsoring its development!

Contributing

If you want to test your code in an existing project that uses Symfony UX packages, you can use the link utility provided in this Git repository (that you have to clone). This tool scans the vendor/ directory of your project, finds Symfony UX packages it uses, and replaces them by symbolic links to the ones in the Git repository.

# Install required dependencies
$ composer install

# And link Symfony UX packages to your project
$ php link /path/to/your/project

ux's People

Contributors

1ed avatar 94noni avatar bocharsky-bw avatar chalasr avatar chqthomas avatar dafish avatar dunglas avatar evertharmeling avatar fabpot avatar feymo avatar htmlshaman1 avatar janklan avatar javiereguiluz avatar jmsche avatar kbond avatar kocal avatar lustmored avatar nicolas-grekas avatar norkunas avatar onexhovia avatar seb-jean avatar simondaigre avatar smnandre avatar sneakyvv avatar spomky avatar squrious avatar tgalopin avatar weaverryan avatar webmamba avatar yceruto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ux's Issues

Chart.js - Charts are no longer displayed

Hey! Since the last version of Symfony and therefore the update of Symfony UX, it seems that there is a problem to display charts with Chart.js

I haven't touched anything on my previous code. But when I return a chart, it no longer appears :

<div id="reports_charts">
    <div class="chart-container chart">
        {{ render_chart(chartOne) }}
    </div>
    <div class="chart-container chart">
        {{ render_chart(chartTwo) }}
    </div>
</div>

image

I asked comrades, same problem for them

LazyImage: cache blurhash

The docs say:

You should try to generate small BlurHash images as generating the image can be CPU-intensive.

So it would be nice if the hashes could be cached somehow :)

[LiveComponent] How to use a DTO instead of an entity

I've just been playing around with the Live Component functionality. It's basically totally awesome, but I got completely stuck when trying to use a form data class instead of an entity.

I see in #102 there is a note about Document using a DTO is a LiveProp / the dehydration system.. This is exactly what I'm stuck on trying to use a DTO rather than an entity, and getting an error message saying something like "dehydration not available".

Can anyone point me in the right direction? If I can get it working I will do a PR to update the readme with the new info. Thanks

[Chart.js] v3 support

Currently Symfony UX offers version 2.9.4 of Chart.js.
In december and the beginning of 2021 it was good.

But since april version 3 has been released. And we are already at 3.2 as I write this.

I also think it would be a good idea to specify on the repository readme (for each integration) which version is supported (or did I not see it?).
It would have saved me a few hours of trying to figure out why certain options weren't working.

Migration guide

Can you tell us what the procedure would be for the update?

[TwigComponent] Improvements suggestion

First I want to thanks and congratulates @weaverryan and all people involved in making those 2 new components 👏!

I just start a fresh new project, using the Twig Component. and it's already saving me some extra work, this is really appreciate.

Here is a list of some suggestions that could improve this package:

Default path

Add a Bundle configuration parameter default_path, similar to the one for Twig, to define where components are stored.

default_path: '%kernel.project_dir%/templates/components' # default value

Additional paths

Be able to defined multiple Component paths. This can be useful in applications where we want to split each parts:

component_paths: 
 - '%kernel.project_dir%/templates/website/components'
 - '%kernel.project_dir%/templates/admin/components'
 - '%kernel.project_dir%/templates/common/components'

When rendering, it will parse each path to find the component template then fallback to default_path if none is found.

Prefix

It's a common practice to prefix "partial" twig template with _ (e.g. _form_delete.html.twig). Being able to define a "global" prefix without having to specified it in the getComponentName method will be great. The prefix will be concatenate with the component name.

component_prefix: '_' # optional, none by default

Alternate templates

Sometimes, depending on the context, it can be useful to display the component with a different template.

public function getComponentTemplate(): string
{
    return match(this->context) {
        $this->foo() => 'bar',
        $this->bar() => 'foo',
    };
}

Maker command

I'm pretty sure this one is already in the pipe, but having a make:component command to quickly build a component will save some extra work!

WDYT ?

Proposal: Datepicker

Hello,

Native date picker are not the same on every browser, I personally use Litepicker and it will be good to have one, maybe with this package.

Swup: reload Javascript

Hi guys,

Swup works amazingly. It pulls every linked asset as required, but the javascript code is not executed.
The swup documentation suggests using
swup.on('contentReplaced', init);
but I can't get it to work.
Any help would be greatly appreciated!

Feature request: remove final from TurboStreamResponse

If final is removed, it would be easy to stream, redirect and force reload of frames in single response.

Example:

// some controller
return new TurboResponse(
    redirectUrl: $this->generateUrl('basket'),
    reloadFrames: ['shopping-cart-frame', 'some-other-frame'],  // ids of frames
);

and some glue js:

app.js
// listen for turbo events
document.addEventListener('turbo:before-fetch-response', (event) => {
  let redirectUrl = event.detail.fetchResponse.header('Turbo-Redirect');
  if (redirectUrl) {
    Turbo.visit(redirectUrl);
  }

  let framesToReload = event.detail.fetchResponse.header('Turbo-Reload-Frame');
  if (framesToReload) {
    framesToReload.trim().split(/\s*,\s*/).forEach((name) => {
      document.getElementById(name)?.reload();
    });
  }
});

and custom response class:

App\Response\TurboResponse
class TurboResponse extends TurboStreamResponse
{
    public function __construct(?string $redirectUrl = null, array $reloadFrames = [], ?string $content = null)
    {
        parent::__construct($content);
        if ($redirectUrl) {
            $this->headers->set('turbo-redirect', $redirectUrl);
        }
        foreach ($reloadFrames as $id) {
            $this->headers->set('turbo-reload-frame', $id, false);
        }
    }
}

Mercure component?

I'd be interested in seeing what a client side implementation for the Mercure Bundle might look like.

UX Turbo Mercure - Basic config returns 401

Hi,

I've tried last week to set up a demo project, as simple as possible, to try UX Turbo with Mercure.

Unfortunately, I can't find a way to make this work.
The best I managed to get is a 401 Unauthorized response when the browser tries to connect to the Mercure server, while I seem to manage to connect to it correctly in my terminal using curl.

Here is the reproducer: https://github.com/jmsche/turbo-reproducer
You can read its README to launch it "easily" (using Symfony CLI & Docker Compose).

What I noted though: I don't see any token passed to the XHR request sent to Mercure.

Here is the request I got from Firefox (using right click on the request => copy as curl):

curl 'http://127.0.0.1:3010/.well-known/mercure?topic=chat' -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0' -H 'Accept: text/event-stream' -H 'Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3' --compressed -H 'Origin: https://127.0.0.1:8000' -H 'Connection: keep-alive' -H 'Pragma: no-cache' -H 'Cache-Control: no-cache'

As you can see the request is sent to the correct URL/port; so Symfony CLI does not seem to be the issue here.

Vue Component

Would it be possible to create a component for Symfony UX that does what Inertia JS currently does?

ie, hydrate the props of a Vue component from the server-side with Symfony/PHP, and render that same component in a Twig template with some twig helper function ?

Mail bundle

In the past i have dabbled with the symfony email setup. Tried to implement the foundation for emails and setup the css inliner for the emails. Some setups you can find in the documentation as an example.

So this is not quite a question or issue or just a mention. But a sample for anyone that tries to implement the Mailer.

Forgot the link 🙈
https://github.com/disjfa/mail-bundle

Question : Lazy Image don't seem to work

Hey ! I have recently try to install ux-lazy-image, I followed the tuto but it doesn't seem to be working.. only the image passed in src is displayed.

For exemple my img is :
<img src="https://localhost:8000/media/cache/resolve/thumbnail/uploads/images/quizz/1029784-5ff75d203f265692433515.jpg" data-controller="symfony--ux-lazy-image--lazy-image" data-hd-src="https://localhost:8000/media/cache/thumbnail_quizz/uploads/images/quizz/1029784-5ff75d203f265692433515.jpg" width="320" height="270">

Am is missing something ?

Thanks for help !

Generate code on the console

For lots of applications, the js is separate from the PHP, so I think, it could be interesting to generate code on the console and then pass it to the js app. As Read Admin does with their guesser component. For example, a command can generate a form with dynamic validation in the console, and you just need to pass the result in your js.

Allow events to bubble

Currently, the *:connect events are dispatched as non-bubbling, making them incompatible with event delegation. I think it would make sense to let them bubble instead.

Technology choice (Stimulus)

Thanks a lot for this initiative. It is sorely needed.

I’m curious about the choice of Stimulus over alternatives. For example, it’s not immediately obvious to me that Stimulus is a better fit than Unpoly or htmx.

I think documenting the reasoning behind the choice would make it more motivating for me to use Symfony UX by removing some doubt. It would also be useful when trying to choose between different alternatives.

options are not considered when rendering chart

i tried to set some options for the chart in my controller like this

        $chart->setOptions([
            'title' => ['display'=> true, 'text' => $this->translator->trans('headline', ['%year%' => $year])],
            'legend' => ['display' => true, 'position' => 'bottom'],
        ]);

this is then rendered as

{
  // omitting the data part that works
  "options": {
    "title": {
      "display": true,
      "text": "Statistik 2020"
    },
    "legend": {
      "display": true,
      "position": "bottom"
    }
  }
}

but the check here

if (!payload.options.length) {

replaces the options with an empty object, because payload.options.length is undefined while payload.options contains the options

Swup, main element animation

The setup:
I want to setup my site with my own id names, so i have set up the containers data-containers="#base #nav"

The problem:
Now the swup animation does not work anymore. This is because the animation plugins also use an option on them to name the main element of the animation({{ mainElement: '#swup' }). See documentation.

https://swup.js.org/themes/fade-theme
https://github.com/swup/fade-theme/blob/master/src/index.js#L11

The solution
Add a data-main-element attribute so we can also setup the main elements for the animations.

Proposal: Put back the Annotations and PHP7 compatibility

I noticed that PHP7 support was dropped a few days ago (and annotations support) in favor of PHP8 attributes. In the long run it is a good idea but it will take us a while for transitioning to PHP8 and therefore testing the new UX components will not benefit of community feedback as much as it would if PHP7 would still be an option.

There is a huge trend of pushing the business logic toward Javascript and client-side programming which is somehow abnormal in my opinion. One of the reasons is the lack of alternatives and the UX component is so promising to fill in the gap. But if it takes 1-2 years to become a standard I'm afraid we'll all loose a big opportunity to keep the web programming sane.

After update chart is not loading anymore

After updating to the ux-chartjs to 1.1.0 it does not work anymore 🙈

JS Error

definition.js:20 Uncaught (in promise) TypeError: constructor.bless is not a function
    at blessControllerConstructor (definition.js:20)
    at blessDefinition (definition.js:15)
    at new Module (module.js:6)
    at Router.push../node_modules/@stimulus/core/dist/src/router.js.Router.loadDefinition (router.js:54)
    at application.js:81
    at Array.forEach (<anonymous>)
    at Application.push../node_modules/@stimulus/core/dist/src/application.js.Application.load (application.js:81)
    at Application.push../node_modules/@stimulus/core/dist/src/application.js.Application.register (application.js:72)
    at index.js:35

What did I run

  • composer update
  • composer recipes:install symfony/web-profiler-bundle --force
  • npm update --force
  • npm run dev

Also npm update without force has very weird error message

❯ npm update
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: undefined@undefined
npm ERR! Found: [email protected]
npm ERR! node_modules/stimulus
npm ERR!   dev stimulus@"^1.1.1" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer stimulus@"^2.0" from @symfony/[email protected]
npm ERR! node_modules/@symfony/stimulus-bridge
npm ERR!   dev @symfony/stimulus-bridge@"^1.0.0" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! See /home/shyim/.npm/eresolve-report.txt for a full report.

I have locked now @symfony/stimulus-bridge in npm and symfony/ux-chartjs in composer to 1.0,0 and it works again for me 😅

Fixed dependence between Composer & NPM/Yarn

The hard linking to the files form "vendor" into the package.json provides a hard dependency between PHP and JS package managers.

Currently, most of our projects deploy through the Bitbucket Pipeline. For this, two different images are used one after the other:

  • node - This is where the assets are built and stored as artifacts. (yarn install && yarn run build)
  • php - Here the project is rolled out with Deployer and the assets are taken along. (php bin/deployer.phar deploy development)

Example

buildAssetsForDevelopment: &buildAssetsForDevelopment
  step:
    name: "Build assets"
    image: node:12.18.3
    caches:
      - node
    script:
      - yarn install
      - yarn run dev
    artifacts:
      - public/build/**

deployToDevelopment: &deployToDevelopment
  step:
    name: "Deploy to development"
    deployment: deployment-development
    image: php:7.4
    script:
      - apt-get update -y && apt-get install -y ssh rsync
      - php bin/deployer.phar deploy development --branch=$BITBUCKET_BRANCH -vvv

pipelines:
  custom:
    deployment-to-dev:
      - <<: *buildAssetsForDevelopment
      - <<: *deployToDevelopment

Now if you want to use UX, you are forced to rely on a more complex image that includes both Node and PHP.

Is it intended to outsource the dependency in symfony/ux-* into a separate symfony/ux-* NPM package?

Problem, ChartBuilderInterface service dosn't exists

Hi, i've got an error with Chart.js

Cannot autowire argument $chartBuilder of "App\Controller\ajax\YearChartController::getYearChart()": it references interface "Symfony\UX\Chartjs\Builder\ChartBuilderInterface" but no such service exists. Did you create a class that implements this interface?

this is my controller ###:

<?php

namespace App\Controller\ajax;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\UX\Chartjs\Builder\ChartBuilderInterface;
use Symfony\UX\Chartjs\Model\Chart;

class YearChartController extends AbstractController
{
    // On active les sessions pour se Controller
    private $session;

    public function __construct(SessionInterface $session)
    {
        $this->session = $session;
    }

     /**
     * Sert à récuperer le graphique sur l'année
     * 
     * @Route("/get-year-chart", name="get_year_chart")
     */
    public function getYearChart(ChartBuilderInterface $chartBuilder){

        $chart = $chartBuilder->createChart(Chart::TYPE_LINE);
        $chart->setData([
            'labels' => ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
            'datasets' => [
                [
                    'label' => 'My First dataset',
                    'backgroundColor' => 'rgb(255, 99, 132)',
                    'borderColor' => 'rgb(255, 99, 132)',
                    'data' => [0, 10, 5, 2, 20, 30, 45],
                ],
            ],
        ]);

        $chart->setOptions([
            'scales' => [
                'yAxes' => [
                    ['ticks' => ['min' => 0, 'max' => 100]],
                ],
            ],
        ]);

        return $this->render('ajax_templates/yearChart.html.twig', [
            'chart' => $chart,
        ]);
    }
}

When using ux-turbo, FormInterface is unabled to detect which button is clicked

Symfony version(s) affected: 5.3+

Description
When UX-TURBO is activated,
$form->get('submit')->isClicked is always returning false
$form->getClickedButton() is always returning null

How to reproduce

  1. Start a full skeleton symfony project,
  2. Create a controller with a form and multiple buttons
  3. In your controller, dump the content $form->getClickedButton, all is working.
  4. Install symfony/ux-turbo
  5. Retry, the content of $form->getClickedButton is now null

Below, all steps are detailed.

symfony new --full issue-ux-turbo
cd issue-ux-turbo
symfony console make:controller Home

Open src/Controller/HomeController and edit it:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class HomeController extends AbstractController
{
    #[Route('/home', name: 'home')]
    public function index(Request $request): Response
    {
        $form = $this->createFormBuilder()
            ->add('task', TextType::class, ['required' => false])
            ->add('save', SubmitType::class, ['label' => 'SAVE'])
            ->add('saveAndAdd', SubmitType::class, ['label' => 'Save and Add'])
            ->getForm();

        $form->handleRequest($request);

        $clicked = "Form wasn't submitted";
        $code = 200;

        if ($form->isSubmitted() && $form->isValid()) {
            $button = $form->getClickedButton();
            if ($button instanceof FormInterface) {
                $clicked = $button->getName();
            } else {
                $clicked = serialize($button); //will return N; (button is null when turbo is running)
            }
            $code = 422;
        }

        $response = new Response(null, $code);

        return $this->render('home/index.html.twig', [
            'clicked' => $clicked,
            'form' => $form->createView(),
            'controller_name' => 'HomeController',
        ], $response);
    }
}

Open templates/home/index.html.twig and edit it to add clicked and form:

{% extends 'base.html.twig' %}

{% block title %}Hello HomeController!{% endblock %}

{% block body %}
<style>
    .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
    .example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
</style>

<div class="example-wrapper">
    <h1>Hello {{ controller_name }}! ✅</h1>

    {{ form(form) }}
    This friendly message is coming from:
    <ul>
        <li>Your controller at <code><a href="{{ '/home/alexandre/PhpstormProjects/issue-ux-turbo/src/Controller/HomeController.php'|file_link(0) }}">src/Controller/HomeController.php</a></code></li>
        <li>Your template at <code><a href="{{ '/home/alexandre/PhpstormProjects/issue-ux-turbo/templates/home/index.html.twig'|file_link(0) }}">templates/home/index.html.twig</a></code></li>
        <li>Clicked button <code>{{ clicked }}</code></li>
    </ul>
</div>
{% endblock %}

Test it, no issues yet.

Install symfony/ux-turbo

symfony composer require symfony/ux-turbo
yarn install --force
yarn run encore dev

Uncomment the Twig helpers in templates/base.html.twig

Test it, the bug appears !
Disable Javascript, the bug disappears, of course.

Possible Solution
This is perhaps a Turbo bug.

Proposal: Tree structures

It would be great to have complex UI for tree structures. There is many jQuery implementations and few vanilla script projects to choose from. I didn't found any stimulus based solutions so far.
I believe this component could work similar to server side chartjs implementation + adapters for doctrine tree extension entities + default stimulus controller to catch events (adding, removing, moving nodes etc).

Provide a test/playground app to facilitate development and contributing

Hi,

For working on #33 (comment), I had to:

  • create a new Symfony app
  • configure Composer repositories for using local Symfony UX packages (src/Dropzone)
  • install and setup webpack encore
  • create a new page for rendering a dropzone

I think this would be really nice to provide a test/playground app for contributors. This way we saves times and energy before really starting to work on Symfony UX.

It would be a fully working Symfony app with:

  • all Symfony UX packages are installed locally
  • webpack Encore is installed
  • test/demo pages for every Symfony UX packages

With this app, everything we have to do is to run the following commands to get ready for working on Symfony UX:

composer install
yarn
yarn dev
symfony serve

WDYT?

[Dropzone] Error selector

Hello, after a fresh install of Dropzone, I have this error in console :

Error connecting controller

 DOMException: Element.matches: '[data-@symfony/ux-dropzone/dropzone-target~="input"]' is not a valid selector 

Do you know how to fix it ?

wierd recipe behavior, package.json modified after every composer update run

Hi!

I have aproject where I already had cropperjs as a dependency.
I added symfony/ux-cropperjs to the project and it added cropperjs as devdependency.
Ok, deleted it from dev and left it in normal dependencies.
But now after a composer update it keeps readding it. Like it works differently than the 'non ux' recipes.

How can I solve this? Do I really need to move cropper as a devdependency with the symfony enforced version?

Dropzone: handle multiple files

It would be nice if Dropzone could handle multiple files.

I was expecting it would as its parent type is the FileType, that allows setting multiple option to true.

Chart JS doesn't work

I'm developing my first Symfony project and just installed all needed packages for Chart JS but I still can't see the example chart, might be a packages problem. The project is located on my repository (AdminHomeController specifically) and I'm using
"@symfony/webpack-encore": "^1.0.0"
"@symfony/stimulus-bridge": "^2.0.0"
"symfony/webpack-encore-bundle": "^1.12"
"stimulus": "^2.0.0"
Thanks a lot in advance.

Suggestion: TailwindCSS integration

Since there seems to be a push for stimulus which is a very simplified JS event system I would suggest matching it with Tailwind which has a very similar philosophy. They also have some of the best documentation out of any project out there.

Tailwind CSS

Tailwind provides a huge number of utility configurations out of the box and on building your project all unused styles are removed so that you have the absolute smallest style sheets possible. This has helped me tremendously in speeding up page loads. You can also easily hook your own style sheets between the TailwindCSS and your site and because it uses postCSS (Already in symfony) you have full support of polyfills and all future css specs.

I already have postCSS and TailwindCSS integrated in my project and the setup was really simple

[LiveComponent] Meta issue for todos, changes & bugs

Hi!

Earlier, the TwigComponent and LiveComponent packages were introduced. Since the community is just getting its first look at these, and because there are known TODOs and ideas, I though it would be best to start with a single meta issue to track things :).

Some of these reference the "Demo" - found here: https://github.com/weaverryan/live-demo

Features

Feature A) Add support for @Security annotation/attribute. Also for @Cache annotation. #116

Feature B) Action arguments - e.g. data-action-name="delete(id=5)". The frontend syntax is already supported. We need to add a way to "allow" certain action arguments to be "passable" from the frontend. #218

Feature C) CSS Transition support for removed/added elements

Feature D) Ability to add cache headers in addition to the @Cache annotation #116

Feature E) Allow loading behavior to be specific to a model or action -e.g. data-loading="action(save)|show" to "show" this element only when the "save" action is loading. #470

Feature F) Ability to control the "route" for a component, instead of using the built-in /_components/{componentName}/{actionName}. And the same for specific actions of a component. WONTFIX unless requested with a good reason.

Feature G) Audit and add more JavaScript events that are dispatched.

Feature H) Testing tools: tools to help you create a component with some data, call actions on it, and assert final things on the rendered HTML.

Feature I) Allow controlling the debounce time on a component and model level.

Feature J) A system to allow for computed properties (e.g. a method that is called only once, then its value is returned every time after)

Feature K) A make:component command

Feature L) Look again at "child" components and how they communicate back and forth

Changes

Change A) Investigate making the initial render a sub-request. This would make initial render more consistent with a re-render, but we need to check the performance penalty. Will not do for now - can revisit later.

Change B) getComponentName() -> getName()

Change C) Investigate removing ComponentInterface and LiveComponentInterface in favor of annotations/attributes. #106

Change D) Consider forcing the template name to be configured (e.g. a template="" option on the annotation/attribute from above #106

Change E) Normalize naming of hooks (Before / Pre/Post) #281

Change F) Change annotation's constructor - #101 (comment)

Change G) Consider eliminating the this. prefix in the template... which may not actually be possible :). UPDATE: this is partially done by making public vars available. But Kevin and I also talked about adding a TemplateVariable attribute to allow you to expose non-public properties, or even methods.

Bugs

Bug A) Proper JavaScript packaging & IE11 support: #101 (comment) #101 (comment) #111

Bug B) Add missing PHP 8 attributes #106

Bug C) Child components don't update their parent component's model - seeable in the /admin forms of the demo https://github.com/weaverryan/live-demo - edit the textarea field, the submit via the "action" button (the new value will not be reflected) #113

Bug D) From the demo - https://github.com/weaverryan/live-demo - if you hit hide/show on the notifications as polling finishes, it's wonky. #278

Bug E) From the demo - https://github.com/weaverryan/live-demo - If you submit a new notification, the previous "message" remains in the input. But if you hit submit again, it submits as an empty string. #250

Bug F) Some way to force a child component to re-render when a parent re-renders. This can be seen if you make a child component - similar to EditPostNoFormComponent on the demo - have a "Deferred" update. Then click a button to trigger an "action". The content field (the textarea) would have an error. But it would not cause the child component to re-render, so the error would not be shown. #113

Bug G) Gracefully handle unexpected errors on the frontend & help the developer debug these. Currently, unexpected errors cause a Javascript error. Also, if you "forget" to set a LiveProp to writable: true and then modify it, this currently results in an "invalid checksum". Better error would be "Did you forget to set writable: true?". #467 and #466

Bug H) Add a way to mark an element as "permanent" so that it won't be replaced on render. This is useful if some other JavaScript has manipulated your element and added something.

Bug I) Check file uploads with actions #289

Bug J) Allow different "display" types with data-loading. Currently, when we "show" an element, we add display: inline-block (to override the display: none in CSS). That should be configurable on a per-element basis.

Bug K) Don't require a checksum on the URL if there are no read-only LiveProp. Or, possibly turning the checksum off for a component would be allowed (I'm thinking of writing your own JavaScript that, as the user types, you make a request to /components/users?email=ryan.

Bug L) What should happen if a deferred model change happens during an Ajax call? We can't simply use the new data from the new Ajax call, as that would replace the deferred model update. This might be a situation where a race condition must be allowed (probably using the new data from the Ajax call as the "source") and controlled by the user (e.g. if it's important, the user would disable a field during loading to avoid it changing).

Documentation

Docs A) Finish LiveComponent README ("hook" system - especially security is needed, also might need to change the "int" type on min and max to avoid problems with super bad values and document why).

Docs B) Some typos from #101 (review) #103

Docs C) Remove relative README links #101 (comment) #107

Docs D) Play with & document rendering problems with lists... and the use of the id attribute to fix. See the description next to getNodeKey() on morphdom: https://github.com/patrick-steele-idem/morphdom#morphdomfromnode-tonode-options--node

Docs E) Document limitations of the CSS that hides data-loading="show" elements, and the workaround. Specifically, if you have any exotic loading mechanism - e.g. data-loading="show addClass(foo)", the CSS would not automatically hide this: https://github.com/symfony/ux/blob/main/src/LiveComponent/assets/styles/live.css#L1 - and so a display: none needs to be manually added.

Docs F) Document using a DTO in a LiveProp / the dehydration system.

Docs G) Document the exposed={} option

Docs H) Add missing Flex recipe & also document "routing" import needed if you're not using Flex. #109

Docs I) Make sure "how to add security" is properly documented

Docs J) Mention that the property accessor is used, so properties can be private with a setter.

Minor

Minor A) See if LiveComponents can support php 7.4, or not. (won't do)

Minor B) Add code to CI to verify that all dist files are built.

Minor C) Consider using JSON.stringify in http_data_helper.js

Minor D) Remove/complete TODO's in LiveComponentHydrator and ComponentRenderer

Minor E) Move "private" methods & code out of live_controller.js

Minor F) Throw an error if args are passed to data-loading with hide/show - e.g. data-loading="hide(me)"

Future Ideas

Future A) A web debug toolbar integration

Future B) A debug:component command

Future C) Mercure support

Future D) Polling enhancements: (1) poll less often when the browser tab is not active and (2) don't start polling until visible

Future E) Add support for different keyup/keydown keys. For example: data-action="keyup->live#action" and data-action-name="key(enter).save key(p).someoneTypedP".

Future F) Add support to add styling for a "dirty" field (a field that has been updated, but a re-render hasn't happened yet, because updateDefer was used) - e.g. data-dirty="addClass(border-red-500)"

Future G) Potentially add support for "lazy" components (they don't load until they are visible) or at least document how one could use a lazy Turbo Frame nicely with a component URL. For example, on page load, a component has a "loading" animation. Then, it loads via Ajax and the area is updated.

Future H) Add support for dehydrating an entity object using something other than the primary key? e.g. UUID

Add getter for data property in Chart.js

It would be interesting to add the getter for the "data" property in the model of the Chart object, in the Chart.js component

For my part I need to access it from my Twig view for something.

For example I need to take all the sum of all the values ​​in data [] to display the total above the graph, like this :

<div class="reports-stats-item card text-white bg-success mb-3">
            <div class="card-body">
              <h2 align="center" class="card-title"> <i class="fas fa-coins"></i>
                {% set total_amount = fullReports.invoices.data.datasets|sumMultiArrays("data") %}
                {{ total_amount }} € générés
              </h2>
            </div>
          </div>

image

ux-dropzone - Error connecting controller

I'm doing something wrong. Once implemented ux-dropzone, I'm getting an error in the browser console:

Error connecting controller

DOMException: Failed to execute 'matches' on 'Element': '[data-@symfony/ux-dropzone/dropzone-target~="input"]' is not a valid > selector.

Use the full power of Stimulus

First thing first, I'm so happy to see this project! It's a huge deal for Stimulus and Symfony!! 👍

Under this title, I mean multiple things.

  1. Using disconnect callback

I think all controllers should use the disconnect callback to destroy instances. Like the Chart one.

If I dynamically remove the node from the DOM, the chart instance will remain loaded.

connect() {
  this.chart = new Chart(this.element.getContext('2d'), payload);
}

disconnect () {
  this.chart.destroy()
  this.chart = undefined
}
  1. Using data maps

Stimulus has a pretty handy API to deal with data: https://stimulusjs.org/reference/data-maps

It's cool because it's name-spaced by default, so it "forces" developer to use it in a more generic way. And it has methods to access datas.

I see lots of this.element.getAttribute('key') but they are not using data-maps

  1. Improve inheritence

All controllers dispatch a custom event "extends" controllers in a some way.

I think it would be more consistent to allow developers to extends these controllers like here with instance variables and so on instead of using custom event. Because sometime, it's useful to override the behavior.

Thanks a lot for this project!

Modify tooltip text with a callback (Chartjs UX)

Hi guys,

It's so hard to work with ChartJs in symfony UX. It's not the same doc than the pure ChartJS, for example I was re-writing the tooltip and the doc in ChartJs is :

options: {
        plugins: {
            tooltip:

and in Symfony :

 $chart->setOptions(
            [
                'legend' => false,
                'tooltips' => [
                    'backgroundColor' => 'red',

plugins has disappeared and tooltip became tooltips, why ? It make me lost a lot of time ...

Anyway, now I'm trying to modify the text in my tooltipS and I'm stuck with the callback, I know it's a syntax problem but I can't find what is wrong :

'tooltips' => [
                    'backgroundColor' => 'red',
                    'callbacks' => [
                        'title' => fn($tooltipItem) => 'Here is my new text'
                    ]

An idea ?

Changelog

Would be nice to have a changelog, either in the main ux repository (root dir or in each component) or in Github's releases page.

Unable to resolve path to module '@symfony/autoimport' with eslint

I have Webpack Encore configured with ESLint and I have the Unable to resolve path to module @symfony/autoimport error both from eslint and my IDE. The "only" issue is ESLint error and red underline in IDE. And with ESLint error, compilation fails.

I've noticed the issue while using web-server inside docker (with the whole project mounted inside the container) and when I dump the assets to the public/build dir. Looking at this I don't think it should matter.

As a dirty fix I used // eslint-disable-line import/no-unresolved. Controllers work fine, no errors in console etc.

After a short discussion on Slack with @tgalopin I know that autoimport is created on compilation by Webpack Encore. I think that dirty fix might be the only fix in that case. I'm not sure if it's possible to ignore a single specified module from .eslintrc.

package.json versions:

        "@symfony/stimulus-bridge": "^1.0.0",
        "@symfony/webpack-encore": "^0.32.0",

composer.json versions:

        "symfony/webpack-encore-bundle": "^1.8",

Symfony 5.2

Integration of a WYSIWYG editor

An WYSIWYG editor is quite often needed in a Symfony application where things has to be administrated. I had hard times to integrate tinymce (in a clean way) into a Symfony application.

First I tried to use stfalcon/tinymce-bundle but it isn't maintained anymore and I think nowadays the way of the integration is not optimal anymore. So i used Encore to achieve that. I think this was a good decision, but it was very tricky. It took some time for me to get it working (here's a small how-to that I have written down: stfalcon/TinymceBundle#221 (comment)).

Of course tinymce is very heavy and there are other editors, which may be enough for most of the projects. I think of

Would be great if at least one editor would be integrated.

Consider moving TwigComponent out of ux

Hi,

As discussed on Slack yesterday I don't see why the TwigComponent is part of the ux initiative, as it's "just" a Symfony bundle.

To quote the UX readme:

Symfony UX is an initiative and set of libraries to seamlessly integrate JavaScript tools into your application.

But the TwigComponent does not include any JavaScript, hence my issue.

I already proposed something like twig/component-extra, but as it is a Symfony bundle, maybe it could be eg. symfony/twig-component-bundle or twig/component-bundle?

Thanks for reading this until the end and taking my proposal in consideration :)

[Question] Contribution guide

Hi,

Thanks for launch this initiative, it's amazing! I am preparing a new library and I would like to confirm that the Symfony Core contribution guide is the reference as a contribution guide for this specific features as a part of Symfony ecosystem.

After verified, fixed comments, and accepted the PR, the new library will be available at UX documentation repository (this repository), but how will the library be published under Symfony organization, for example under https://github.com/symfony/ux-my-awesome-library?

Thanks in advice!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.