Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Modern UIs with UX, a little JS & Zero Node

Modern UIs with UX, a little JS & Zero Node

Ready to build a highly-interactive, modern UI? Me too! But hold up, do we really need to install Node & Webpack to pull this off? Not anymore! With PHP, Twig, and just a pinch of JavaScript magic, we can create something truly special.

In this talk, we'll embark on a journey using the new Symfony UX experience, one *without* Node and Webpack. We'll conquer common UI challenges like modals, notifications, and filterable tables, wielding the power of Turbo & Stimulus while writing minimal JavaScript.

For the grand finale, we'll tackle the most interactive situations using only PHP & Twig, thanks to the LiveComponents. With *huge* changes over the past few months, this is finally ready for the big leagues.

Avatar for weaverryan

weaverryan

June 16, 2023
Tweet

More Decks by weaverryan

Other Decks in Technology

Transcript

  1. > Member of the Symfony docs team > Husband of

    the talented and beloved @leannapelham symfonycasts.com twitter.com/weaverryan Howdy there!! I’m Ryan! > Author person at SymfonyCasts.com
  2. export default class { constructor(name) { this.name = name; }

    quack() { console.log(`${this.name} says: Quack!`); } } public/duck.js
  3. All browsers now support import, ES6 class syntax, etc** **

    Ok, not IE11, but that is less than 0.5%!
  4. Two Problems 1) Versioned Filenames 2) Importing 3rd Party Packages

    <link href="/assets/app.1234.css"> import 'https://cdn.jsdelivr.net/npm/[email protected]/+esm';
  5. How… did that work? /assets/* is served by an internal

    Symfony listener dev: prod: Run php bin/console asset-map:compile to physically write all fi les into the public/assets/ directory /assets/images/duck-3c16d9220694.png
  6. ???

  7. Now this works ✅ import { Alert } from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm';

    import { Alert } from 'bootstrap'; const alert = new Alert(element);
  8. return [ 'app' => [ 'path' => 'app.js', ], 'bootstrap'

    => [ 'url' => 'https://cdn.jsdelivr.net/npm/[email protected]/+esm', ], ]; importmap.php
  9. {% block javascripts %} {{ importmap() }} {% endblock %}

    base.html.twig <script type="importmap">{ "imports": { "app": "/assets/app-4e986c1a2318dd050b1d47db8d856278.js", "bootstrap": "https://cdn.jsdelivr.net/npm/[email protected]/+esm" } }</script>
  10. /* assets/styles/app.css */ body { background: skyblue; } .quack {

    background-image: url('../images/duck.png'); } {% block stylesheets %} <link rel="stylesheet" href="{{ asset('styles/app.css') }}"> {% endblock %}
  11. Sass? Tailwind? ✅ (see docs about building) JSX, Vue, TypeScript?

    ❌ (actually, yes, but a build system may be better) Production Ready? ✅ (and performant) Works on all browsers? ✅ (except for ancient browsers, like IE 11)
  12. gzip/compress Assets Do it on your web server / Cloud

    fl are Combining Assets Not needed** Use an HTTP/2 powered web server / Cloud fl are ** not combining can even *help* performance: if a single fi le is changed, users will only need to download that one fi le.
  13. Create rich frontends while minimizing the need for custom JavaScript

    Goal ✅ Asset Mapper: Ciao node! s Turbo + Sprinkle of Stimulus square Live Components
  14. Two New Components symfony/ux-translator symfony/ux-svelte import { trans, NUM_OF_APPLES }

    from '../translator'; trans(NUM_OF_APPLES, { apples: 2 })
  15. Live Components * Smart Rendering System 
 * Communication between

    components: emit() 
 * First class data serializing & invalid data handling 
 
 * … lot's more!
  16. HTML Twig Syntax {% component Alert { type: 'success', closeable:

    allowClose } %} {% block body %}Quack!{% endblock %} {% endcomponent %}
  17. UX 2.9 StimulusBundle AssetMapper Support! {{ stimulus_* }} functions moved

    out of WebpackEncoreBundle and into StimulusBundle.
  18. #[AsLiveComponent()] class DonutChart { use DefaultActionTrait; #[LiveProp(writable: true)] public int

    $slices = 5; public function __construct( private ChartBuilderInterface $chartBuilder, ) { } public function getChart(): Chart { $chart = $this->chartBuilder->createChart('doughnut'); $chart->setData(...); return $chart; } }
  19. RIP Build Systems? React, Vue, Next.js, etc Tailwind / Sass

    TypeScript use their tools to build use its tools to build best served using their build system / a build system
  20. LiveComponents Swiss-Army Knife: Make your Twig templates reload live on

    the site. 🗡 Symfonycasts tutorial coming soon!