List

Beautiful reactive web UIs, Ruby and you

Beautiful reactive web UIs, Ruby and you

by Jonas Jabari

In the talk "Beautiful Reactive Web UIs, Ruby and You" presented by Jonas Jabari at RailsConf 2021, the speaker explores developing reactive web interfaces using Ruby, showcasing a shift away from JavaScript-heavy approaches. He examines the evolution of UI development within the Rails framework and introduces a library he created, named Mate Stack, which allows developers to build reactive UIs solely in Ruby, enhancing developer happiness without sacrificing functionality.

Key Points Discussed:
- The classification of UI development approaches: the spectrum from low UI and developer happiness to beautiful, reactive UIs that can boost developer satisfaction.
- Traditional Rails views (ERB, Slim) and the challenges of integrating JavaScript, leading to complex state management and unhappy developers.
- Introduction of Hotwire and Stimulus Reflex as tools that help reduce JavaScript in favor of Rails, yet the speaker advocates for even more Ruby-centric solutions.
- The concept of Mate Stack, which completely abstracts UI creation using Ruby code, removing the need for HTML and JavaScript while leveraging Ruby's expressive syntax.
- The structure of Mate Stack components: creating UI components, routing, handling dynamic data without page reloads, and integrating with existing Rails applications seamlessly.
- A live demonstration using pre-built reactive components that mimic functions often requiring JavaScript, such as form submissions, updates, and real-time data syncing among connected clients.
- Pre-built styled components based on Bootstrap allow for faster UI development with minimal writing of HTML or CSS, enhancing productivity.
- Encouragement for developers to contribute to the open-source project, fostering a collaborative community around Mate Stack.

Conclusions and Takeaways:
- Mate Stack enables Rails developers to create beautiful, reactive UIs without delving deep into JavaScript, thus maintaining a focus on Ruby, which many developers favor for its syntax and object-oriented capabilities.
- The library aims to free developers from the complexity of front-end coding, allowing them to build intuitive and responsive applications while enjoying the elegance of Ruby.
- Developers are encouraged to explore, contribute to, and benefit from this open-source project, aimed at enhancing the Rails ecosystem and developer experience.

A lot of life changing things have happened in 2020. And I'm obviously speaking about Stimulus Reflex and Hotwire and how we as Rails devs are finally enabled to skip a lot of JS while implementing reactive web UIs. But what if I told you, there's room for even more developer happiness? Imagine crafting beautiful UIs in pure Ruby, utilizing a library reaching from simple UI components representing basic HTML tags over styled UI concepts based on Bootstrap to something like a collection, rendering reactive data sets. Beautiful, reactive web UIs implemented in pure Ruby are waiting for you!

RailsConf 2021

00:00:05.359 hello everyone glad you decided to watch my talk about beautiful reactive web uis
00:00:11.780 Ruby and you let's jump right into the topic and review the state of UI
00:00:18.600 development for rails developers in 2021 from a very rails developer perspective
00:00:24.960 UI development approaches might be classified like this on the y-axis we start with zero UI
00:00:33.300 to a beautiful reactive UI and the on the x-axis we measure
00:00:39.059 developer happiness starting from low developer happiness speaking of hustling with JavaScript and CSS to high
00:00:46.440 developer happiness caused by the beauty of Ruby
00:00:51.719 implementing Ruby backend code is definitely a fun thing to do
00:00:57.180 but you don't get any UI out of it implementing Red's views like Erb humble
00:01:03.780 or slim probably added with some JavaScript sprinkles might give you a good looking but often wary static UI
00:01:10.500 with many full page reloads required additionally you're definitely leaving
00:01:16.979 your Ruby comfort zone here jumping between rails View files CSS and often
00:01:23.040 widely distributed JavaScript Snippets not too happy with that
00:01:29.220 and what about adding a second front-end application written in JavaScript
00:01:35.280 well have fun handling two states the server side and client-side state synced
00:01:41.100 manually via an API causing headaches due to managing complex data flow and
00:01:47.400 constantly switching between two programming languages and system architectures
00:01:54.299 well luckily last year and brought us tools like hot wire and stimulus reflex
00:02:00.479 shipping some kind of reactivity abstraction helping you to avoid tons of
00:02:07.320 JavaScript and use more rails again great but I'm still missing the developer
00:02:14.340 happiness I experience when writing Ruby backend code things like object-oriented programming
00:02:20.700 class inheritance modules and simply a beautiful syntax leading to a readable
00:02:26.700 and well maintainable code base wouldn't it be cool to have all the
00:02:33.060 benefits of Ruby while implementing beautiful reactive uis
00:02:39.420 that's at least what I thought by the way if you end up down here
00:02:46.019 you're doing it wrong but maybe it's time to introduce myself
00:02:52.140 so hi I'm Jonas I'm a full stack software developer working for various clients in Germany and I'm a huge fan of
00:03:00.300 rails I was always working in a context where a small team with limited time and
00:03:08.040 budget resources wanted or needed to deliver a lot
00:03:13.319 and that's where Ruby itself and rails fitted in perfectly Empower a small team
00:03:19.200 to deliver big things right and I'm super honored to talk at railsconf this year
00:03:26.879 I would have loved to meet all of you in person but well let's meet in Discord and get
00:03:32.700 to know each other better after this talk and by the way I'm recording this talk
00:03:38.760 in my small office in Dresden and that's a picture of me moving in last summer
00:03:44.459 and I'm supported by my beloved espresso machine producing
00:03:50.159 great cappuccino and by the way I've tried my best but I'm still not a lot of art professional
00:03:57.299 well maybe I should stick with software which brings us back to our topic
00:04:04.680 back in 2018 I was traveling through Australia and after a while had a small
00:04:11.280 business idea about a team management software and you it will be shipped as a web app
00:04:17.760 which like quite often required a reactive UI I strictly refused to go for the
00:04:25.800 JavaScript single page application Madness again I suffered way too much
00:04:31.919 the years before I questioned everything I did in order
00:04:37.919 to create reactive web uis and have this idea about reactive web
00:04:43.860 uis implemented in pure Ruby my goals were
00:04:49.080 shipping a peeling react web uis while experiencing High productivity and
00:04:55.680 of course High developer happiness and because that should cause high
00:05:01.259 implementation into regeneration speed so I knew
00:05:06.360 I need to get from here back here and after several iterations and weird
00:05:13.860 implementations I ended up with something that actually worked and I thought was really valuable
00:05:20.460 made stack was born back in Germany I skipped the idea of
00:05:27.180 building this team management software and together with two friends founded a small Tech startup we wanted to build an
00:05:34.020 open source business on top of mate stack I thought the value of mate stack could
00:05:40.020 partially monetize looking at something like sidekick well that didn't work good enough on a
00:05:47.340 business level but it worked very well on a technical level validated in a bunch of real-world
00:05:54.539 applications built on top of mate stack until this point
00:06:00.300 so business was not running that smooth and I realized that growing a company and creating an ambitious open source
00:06:06.600 project at the same time is not my type of tea so just a few months ago I therefore
00:06:13.259 decided to shrink down the company to myself and put myself on a mission
00:06:19.860 grow a team of core contributors in order to build a sustainable UI tool set
00:06:25.259 for rails developers worldwide but before we talk about open source and
00:06:31.740 you my friend how to get from here to here
00:06:37.919 well let's say hello to mate stack
00:06:47.039 so based on a strong Foundation rails with routing controllers and
00:06:53.280 models and so on we want to create a beautiful reactive web UI
00:06:58.680 what do we need well we somehow need HTML
00:07:04.259 we need some JavaScript and finally we need styling
00:07:10.080 instead of writing HTML we will create HTML structures with pure Ruby
00:07:16.500 instead of writing JavaScript we will compose pre-built reactive components in
00:07:22.319 pure Ruby and instead of writing CSS we will compose pre-built styled components in
00:07:29.580 pure Ruby so
00:07:35.280 let's start with the first building block of maidstack
00:07:41.280 HTML structures implemented in pure Ruby
00:07:46.380 first of all we somehow need to render HTML browser that's basically how web browser is working but we can choose how
00:07:54.060 to create this HTML I therefore ask you that question what do you prefer
00:08:01.319 Erv or Ruby Hummel or pure Ruby
00:08:07.979 slim or pure Ruby or in general
00:08:13.740 a limiting templating engine syntax or pure pure Ruby unlocking all features
00:08:19.919 of this powerful language
00:08:25.680 well think of the HTML structure of a bootstrike card component
00:08:33.899 and now watch how the same structure may look like in pure Ruby
00:08:40.260 made sticks made Stacks basic UOB DSL is not abstracting anything
00:08:45.300 still as flexible as pure HTML heads up we will abstract things in a bit by purpose
00:08:51.600 so see some amount of code the same amount of code is still required yet
00:08:59.700 but we're crafting UI code in beautiful Ruby syntax rather than using a templating engine a syntax
00:09:07.260 which soon unlocks some cool features and pure Ruby might already be more
00:09:13.200 enjoyable to write compared to um writing HTML syntax
00:09:19.920 so somehow made Stacks rendering converts pure Ruby
00:09:26.519 into HTML but
00:09:31.560 where to put this code we put this code in a self-contained
00:09:38.760 Ruby class which we call a mate stack component
00:09:44.160 when a new instance of this class is called the main response method will return the
00:09:50.459 desired desired HTML string so
00:09:56.040 let's immediately start refactoring a bit
00:10:02.100 we can simply break out of deeply nested HMS structures and create a flat
00:10:08.760 implementation so we end up splitting your I code into small as magically separate chunks
00:10:16.200 who are just calling Ruby instance methods doing this we increase readability and
00:10:22.560 maintainability of our implementation and that's just a very simple example can you imagine how powerful that is
00:10:29.760 when working on complex uis you can use all kinds of Ruby's language features to craft your HTML structure
00:10:36.720 let that sink in and now let's make it a bit more usable
00:10:43.500 reusable components may take required or optional
00:10:49.980 options in order to dynamically render injected content you just Define a simple component API
00:10:57.660 at the top and use the injected options across your component
00:11:06.000 components may take blocks or even name slots as well making them even more
00:11:11.160 flexible we see an example on that later on
00:11:17.279 and how do we integrate this Ruby class in a rails app well we basically have two integration
00:11:23.100 modes we can use medicine components on Hills views or you can use matric components on made
00:11:30.180 stack pages that sounds interesting but let's start with calling mate stick components on
00:11:36.600 existing rails views we simply call our component class and
00:11:42.660 pass pass in required and optional parameters in this case title and content coming
00:11:49.140 from active record instance or we substitute the complete rails view
00:11:57.480 with a mate stack page same principles as seen on components we
00:12:05.160 create a class a main response method and may use all
00:12:10.560 kind of custom instance method helping us to structure our implementation and for sure we can call our component
00:12:17.160 here as well
00:12:22.680 in order to integrate this made seg page into rails we simply telling a rails
00:12:28.260 controller not to render rails View but I made stack page instead
00:12:34.800 made sick therefore can progressively replace or live side by side with the UI layer of rails
00:12:41.399 all other Concepts like routing controller-based authentication or authorization and so on stay untouched
00:12:53.160 we've not talked about reactivity yet well made stick can actually be used
00:12:59.700 with all kinds of reactivities reactivity systems or none if you wish if you don't need reactivity well you're
00:13:06.360 done but we want to have one holistic solution for creating reactive uis in
00:13:13.500 pure Ruby that's why we decided to ship an optional reactivity system based on vue.js Within mainstact
00:13:22.440 so let's have a look at second building block of matesick pre-built
00:13:28.800 reactive components composed in pure Ruby
00:13:34.800 why won't you do something like that well ninety percent of required
00:13:40.440 reactivity is it based on similar patterns I've created a small Javascript app
00:13:47.160 showcasing these patterns so demo time
00:13:56.420 okay on this little Javascript app written in vue.js I want to showcase the
00:14:02.940 reoccurring patterns when implementing reactive uis so you see a small Twitter clone and we
00:14:08.399 we're going to be able to tweet some tweets and yeah let's just have a look
00:14:13.920 we start at the top we see two buttons
00:14:19.500 and um uh with these buttons I'm navigating uh
00:14:24.779 to another page so for example a profile page and I'm navigating back to the timeline and well see a dynamic page
00:14:32.880 transition a typical feature of a JavaScript driven single page application on the timeline you see a form
00:14:40.560 and if you submit the form with missing input you will see immediately feedback
00:14:50.459 down here and at the form input and um well these error messages came
00:14:59.660 obviously from react to record instance which is requiring this input here but
00:15:06.000 it's shown without a full browser page reload immediately after submitting the form so let's submit the form with the
00:15:14.279 required input so there you go so I've posted something
00:15:20.699 the form resetted itself and the UI below the form was partially
00:15:26.639 updated and we see our new tweet uh we are then able to increase database
00:15:35.899 column of of the tweet in this case a simple likes counter and if I'm clicking
00:15:41.459 it I'm obviously triggering a server-side action incrementing this this database
00:15:47.820 saved likes counter but I see immediately the updated
00:15:53.540 number on the UI without a full browser page reload so this is also a typical
00:15:59.519 requirement of reactive UI um just maybe post something again
00:16:06.839 to have at least some tweets here well when talking about partially eye
00:16:13.740 updates that might also be relevant to toggle the UI state
00:16:19.019 here and there um just based on client-side things for example if I want to do
00:16:26.699 um yeah I have to show an inline editing here and then click on edit and the UI here the UI state was
00:16:35.639 toggled a bit and I see a form enabling me to edit my tweet I know that's not
00:16:41.100 possible on Twitter for the purpose of this example um just want to show you that here and
00:16:47.759 I'm updating my tweet and there you go the UI toggled back so this is also kind
00:16:53.339 of a reoccurring pattern toggling the UI State dynamically without a full browser
00:16:59.339 page reload and while talking about real-time reactive web uis is it's always about
00:17:08.400 like synced web clients so on this demo we want to send multiple clients to see
00:17:15.480 uh immediately when somebody else is tweeting something um so let's see how this is working here
00:17:21.900 so I have two connected web clients and two browsers and well
00:17:28.799 just to eating something again and there you go both clients were synced
00:17:36.360 and I'm also able to sync the um the increments of the likes counter
00:17:43.380 on on each browser and
00:17:49.140 um well sometimes it's might be a really interesting feature to have like lazy
00:17:56.160 loading so let's assume loading of this list would slow
00:18:01.919 down the initial page speed of this Twitter clone so we want to be able to
00:18:07.220 Lazy load all the tweets here and if you watch closely I'm reloading and you saw
00:18:14.940 like the um the form was shown immediately with
00:18:20.940 the initial page load but the tweets were lazy loaded so this speeded up the
00:18:26.700 initial page load in this example so to sum it up we have Dynamic page
00:18:32.400 transitions we have reactive forms with reactive feedback we have partial UI updates we
00:18:40.500 have UI state toggling um and we have assumed multiple clients
00:18:48.660 um yeah so these are all reoccurring patterns of reactive web uis and the sad thing is
00:18:57.120 you have to write a lot of JavaScript to get all these things going well let's see what matesick has to
00:19:03.120 offer when it comes to something like that
00:19:09.419 so again 90 of required reactivity is based on these similar patterns
00:19:17.580 why re-implementing these generic features in JavaScript all the time why not build and maintain these
00:19:23.700 features once and reuse them across all your apps
00:19:29.160 well we already did it and you know what the demo I just showed
00:19:34.799 was created out of these pre-built ugs components I didn't write a single line
00:19:40.440 of custom JavaScript to get all the reactivity you saw in the demo
00:19:47.580 I used the transition component in order to create a dynamic page transition I use the form component for reactive
00:19:54.539 form I used nasunk or a cable component for
00:19:59.940 partial UI updates I used an action component triggering a
00:20:05.220 server set action and a partial UI update afterwards I use it on click component
00:20:11.280 to toggle the UI State somewhere else
00:20:17.880 based on a toggle component and these are just a few examples how
00:20:24.720 you can compose a pretty reactive UI um without writing a single line of
00:20:30.539 JavaScript based on these pre-built components and the best part I just used pure Ruby
00:20:38.460 methods within my components or pages in order to call and configure these components
00:20:44.580 I've really created a pretty reactive UI in pure Ruby
00:20:50.220 how does that work let's review this feature using the on
00:20:55.500 click and toggle component imagine the simple use case you want to
00:21:01.860 click somewhere on the UI and want to toggle The View State somewhere else on the UI it made SEC you would do
00:21:07.860 something like that you just call Ruby methods like on click
00:21:13.740 and toggle and pass in required options
00:21:18.780 and a block they are targeting components like the
00:21:25.620 self-made card component our previous example but in this case this pre-built
00:21:30.840 component knows that it is associated with a viewgis JavaScript counterpart
00:21:36.059 as mentioned earlier the response method of a component or page class returns an HTML string
00:21:43.679 and each vue.js component reference in this case on click and toggle triggers
00:21:48.780 the rendering of a special HTML component tag containing the configuration hash like emit hello and
00:21:55.919 show on hello as tag attributes
00:22:01.799 when this HTML is passed by view Json browser the reference VJs components which are included in mate 6 JavaScript
00:22:08.940 mounted and get the configuration hash injected we then have two vue.js components up
00:22:16.020 and running in the browser additionally an event hub is mounted which enables communication
00:22:22.860 between all components so we defined an UI which will show a
00:22:27.900 button tells says click me and when that button is clicked the event hello is emitted
00:22:36.539 and then received from the toggle component which will show its content in this case
00:22:43.919 a span containing a string hello world just like this
00:22:49.799 the inline edit switch and the demo was implemented and thanks to specific configuration
00:22:55.559 specific blocks in our case at the button and the span
00:23:00.600 you can adjust the behavior and the look of the pre-built reactive components according to your needs
00:23:06.480 and that's true for all pre-built components doing way more complex things
00:23:11.520 for you so let's have a close look at some of
00:23:18.179 these components the action component is designed to call
00:23:23.760 server-side rails controller actions from the web browser think of the like button we use in the demo
00:23:29.520 within your Ruby response of a page or component you simply call the action component unconfigure it with a hash
00:23:36.240 containing the rails controller action path and the desired HTTP method in this case put
00:23:42.780 additionally you're telling the action component to show a simple button with your specific block
00:23:49.500 when this button is clicked the action view.js component performs a background HTTP put request towards the
00:23:56.880 specified path targeting a rails controller action the rails controller action
00:24:01.980 does its thing and that's it
00:24:07.140 let's jump to the form component in pure Ruby we're calling the mate stack form
00:24:12.419 component and pass in a configuration hash this time we're using a hopper method as
00:24:18.000 the configuration hash is a bit longer and but we want to keep a clean UI implementation
00:24:24.120 we're telling the form component to collect user input in this case Vian text input and when submitted
00:24:31.980 perform a background HTTP request containing this user input towards the
00:24:37.320 specified rails control action control action does its thing and may
00:24:43.559 react with a positive or negative status code a negative status code
00:24:50.220 usually will contain server validation messages for example coming from active bracket validation
00:24:56.760 these errors are received from the vue.js component in the browser and then rendered next to the relevant form input
00:25:02.880 Fields you saw that on the demo earlier in our example we configured the form
00:25:07.980 component to emit an event submitted when the form was submitted successfully
00:25:14.400 if the raise control action responds with a positive status code the form component emits the event to the event
00:25:19.799 Hub which can be received by other VHS components in the browser which brings us to the next component
00:25:27.299 async the assume component is designed to perform a partial UI update requesting
00:25:33.840 fresh content from the server think of the Twitter demo we had a form on top and listed all tweets below after form
00:25:41.279 submission the list of tweets was updated without a full browser reload
00:25:46.679 that's because we configured the async component to re-render itself on a specific event
00:25:53.820 when the form was successfully submitted it emits the event submitted which then
00:26:00.360 is received by the async ugs component the assume component then performs a
00:26:06.840 background HTTP request towards rails controller action under control action re-renders the UI
00:26:14.340 on the server side and just sends back the relevant part of the HTML to the
00:26:19.380 assume component in the browser the component can now perform a Dom update rendering the fresh HTML just
00:26:26.940 sent from the server that re-rendering was based on a
00:26:31.980 client-side event coming from the form but in the demo we saw zoomed web clients how does that work
00:26:39.299 the good news are a sync doesn't care where the wind is coming from thanks to a super simple action cable
00:26:45.720 integration events can be broadcasted from the server to all connected web clients and there pass through through
00:26:53.760 to mate sex event hub and then there's some components on all connected web clients are doing their
00:27:00.419 thing requesting a new version of the price control action re-rendering and sending
00:27:08.580 back only the relevant part you might ask hmm why do we need to
00:27:14.880 re-render the whole UI on the server side if we only want to add a new tweet to the list
00:27:20.640 good call if you're into optimizing a partial UI
00:27:25.980 update mechanism you can use mate stick's cable component the cable component in this example is configured
00:27:32.220 to append something on an event called nude tweet well now we use the action cap
00:27:38.940 integration to not only push a simple event made sex event up but render a
00:27:44.520 specific component in this example the custom tweet component rendering only one tweet on the server
00:27:51.840 and push this specific HTML to all connected web clients
00:27:58.260 the cable component in the browser receives the event and the rendered HTML and we'll append this HTML to the
00:28:05.400 current Dom this approach is way more fine-tuned
00:28:10.679 compared to the simple rendering re-rendering mechanism of the assume component but it requires a bit more
00:28:17.700 implementation effort for simple use cases their sync component serves you very well
00:28:24.000 if you need to take care of computation time on the server and scalability towards higher traffic
00:28:30.000 use the cable component and now let's talk about one more
00:28:35.580 pre-built component transitions transition components enabling Dynamic
00:28:42.539 transitions from one page to another without a full browser page reload
00:28:47.700 well you need at least two pages for that to work let's define them we have two rails routes targeting two
00:28:54.840 rails controller actions each responding with a different matesick page
00:29:02.039 but wait there's something else we tell the controller to wrap all page responses in a mate stack app
00:29:09.779 a mate SEC app is there for something like a rails layout like a rails layout yields rails views makes a gap yields
00:29:16.980 made stick pages an app may look like this
00:29:22.140 just like made SEC pages and components we Define a ruby class and a response
00:29:27.240 method in there we're defining navigation on top calling two transition
00:29:32.640 components in our example with different paths start targeting the rails control actions we just saw
00:29:41.580 and we need this yield telling the app
00:29:47.220 where to yield Pages like these two
00:29:54.659 on initial request the requested page and its app will be ranked together and shipped to the web browser
00:30:01.679 ugs then automatically mounts a page content view just component on the spot where we told the app to view pages
00:30:09.240 when we click on the transition view.js component the transition will trigger a
00:30:14.279 background HTTP get request towards the desired rails control action
00:30:19.500 which will only respond with the HTML string generated from the response of
00:30:25.200 the desired main stack page this HTML is then shipped back to the
00:30:31.140 browser and will be picked up by the page content view.js component which then switches the current page with the
00:30:37.559 new one coming from the server the rest of the layers says untouched
00:30:44.760 the nutrition may also emit events telling other components to react to
00:30:52.620 page transition events
00:30:58.080 you saw all kind of generic pre-built reactivity used in pure Ruby
00:31:03.419 that's actually good enough to build 80 to 90 of the required reactivity of a
00:31:08.700 typical web UI matesick invites you to shift your mindset instead of implementing reactive
00:31:16.620 features and taking care front and back-end data flow with JavaScript
00:31:21.720 yourself use mate Stack's growing component library and let them do the work for you
00:31:28.440 the work of implementing JavaScript is already done
00:31:34.260 but if we really need custom reactivity what cannot be built with the built-in
00:31:40.679 components simply add your own vue.js components and let them live side by
00:31:45.899 side with the built-in ones so this is how a custom vue.js component
00:31:53.460 on the Ruby side might look like your referencing a view component name here
00:32:02.159 and you create a pureview.js component with the corresponding name
00:32:08.039 and within this view JS component you can do whatever view has to offer
00:32:13.500 additionally you might call the event Hub API in
00:32:19.260 order to communicate with other VHS components either built-in ones or other
00:32:25.440 self-made UJS components custom bgs components are used like all
00:32:32.460 other components and can you communicate with all other components through the event tab in this case
00:32:40.159 we are calling our you just component here next to a toggle component and our
00:32:45.299 Ruby response and we are meeting an event from our custom component and Trigger our toggle
00:32:52.380 component to show its content on when receiving this event
00:32:57.840 using this approach you are able to fill up the last 10 percent of customer
00:33:03.360 activity your app might need or even not sometimes built-in reactive compounds
00:33:09.120 are enough and do you realize how much JavaScript hustle can be avoided with mate Stacks
00:33:16.260 pre-built reactivity system while still being completely flexible
00:33:21.419 that's what we call flexible abstraction you might ask where is the beauty okay
00:33:29.940 you're right we've talked a lot about reactivity so let's talk about the last bit of mate stack pre-built styled
00:33:37.019 components composed in pure Ruby why do you want to use pre-built style
00:33:42.539 components well how much do you enjoy copy and pasting complex dumb structures
00:33:47.580 and giant chains of CSS classes across your app in order to create a decent
00:33:52.740 looking UI do you remember the bootstrap hard component example from earlier
00:33:58.740 wouldn't it be cool to have all bootstrap components available like that in pure Ruby
00:34:04.919 well today is your lucky day we've already done this let's start simple with a bootstrap
00:34:11.520 button just a simple Ruby method and optional params like a specified variant Evola you save recreating growing dumb
00:34:20.580 structures and CSS classes and start implementing a styled UI in pure Ruby
00:34:26.760 and that's just a simple example if we review the pre-built bootstrap
00:34:33.960 card component you quickly see a one line of Ruby saves you from writing and
00:34:40.080 maintaining six lines of HTML containing various CSS classes and you know for
00:34:46.080 sure that these kind of components are not only used once on the UI we're not talking about saving a few lines of HTML
00:34:52.859 here and there these pre-built style components make a huge difference especially on a growing UI
00:35:00.720 but you might ask what if I want to pass in something more complex than a simple
00:35:06.180 string well do you remember me promising you to show how components may also take blocks
00:35:12.599 or even named slots earlier here you go instead of passing in a string which
00:35:19.440 should be rendered in the card body we're now passing in a custom block which contains a spawn
00:35:26.579 this block will now be rendered instead of the default paragraph while still keeping the wrapping Dom of a card
00:35:33.960 and what if I want to inject multiple custom Dom parts and not only one block
00:35:40.020 well in this case you should use slots following the API documentation of the
00:35:47.099 doc component you're basically passing multiple references to your custom
00:35:52.380 methods enter the pre-built component pre-built component will then render
00:35:58.740 your injected methods defining a custom Dom on specific specific placeholders
00:36:05.400 within the pre-built component layout this approach is super powerful when
00:36:11.820 we're using more complex pre-built components which brings us to the smart collection
00:36:20.280 imagine a pre-built style component rendering a good looking collection of database items
00:36:27.359 applying configurable filters triggering reactive re-rendering of the data set
00:36:32.400 without a full browser page reload applying configurable pagination
00:36:37.760 enabling reactive browsing through large lists of data again without a full browser page reload
00:36:44.280 an additionally enables you to pass in slots called for each row rendering
00:36:49.859 costs custom row actions all without writing a single line of HTML JavaScript and CSS just a few lines of pure Ruby
00:36:58.740 too good to be true no way it's really working call the pre-built component Define the
00:37:05.640 base query configure pagination configure columns rendering configure filters and finally configure custom
00:37:13.560 action rendering to a slot called for each row
00:37:19.260 I think it's time for demo before we see the smart collection in
00:37:26.640 action we should have a look on what's possible to create with mate Stack's pre-built style components
00:37:32.880 this app uses the default theme of bootstrap obviously you can create your custom
00:37:37.980 themes based on bootstrap theming approach to adapt the look and feel to your needs
00:37:43.020 on this dummy app we're using the predefined responsive sidebar and predefined page layout components
00:37:50.099 such as page heading or section cards in order to quickly create a reactive
00:37:58.140 clean and good looking UI without thinking of any CSS or JavaScript easily integratable chart.js components
00:38:06.060 for help us to display data in charts based on the current color theme
00:38:13.800 we're using styled form components for reactive forms
00:38:19.020 and Trigger the built-in toasts for reactive feedback
00:38:27.000 and then finally we utilize the smart collection component in order
00:38:32.579 to quickly create reactive paginated table with filters
00:38:39.000 we can browse through the data set thanks to reactive pagination
00:38:44.880 or filter the data set in this case searching for a customer with a last name Jacobs
00:39:01.440 through custom row actions we implemented a delete action
00:39:06.480 asking for confirmation and re-rentice the data set after
00:39:12.060 successfully deleting the item on the server and if you don't want to display data in
00:39:18.599 a table you can add your own list rendering to an additional slot
00:39:23.760 while still keeping reactive pagination and filtering in this case we're using a slot defining
00:39:30.720 collection item rendering through a bootstrap card instead of rendering a table
00:39:38.940 on top of all what you've seen all bootstrap version 5 components are
00:39:43.980 accessible as made set components in pure Ruby if you're curious how it's implemented head to
00:39:51.320 dummy.maidstack.io enjoy the look and feel of this little dummy app and review the implementation in pure Ruby
00:40:05.579 so wrapping it up now we've managed to skip writing HTML and enjoy implementing
00:40:11.599 HTML structures in pure Ruby instead we've managed to skip writing JavaScript
00:40:18.540 and enjoy implementing reactivity in pure Ruby instead easily extendable with ugs if required
00:40:27.540 and we've managed to skip writing giant dumb structures and CSS class chains
00:40:33.119 across all our apps and enjoy composing style components in pure Ruby instead
00:40:40.440 the first two layers are shipped within the open source gem maesteg UI core
00:40:45.780 and the pre-built styled components are shipped within the open source gem made SEC UI bootstrap both available on
00:40:53.460 GitHub and if you're not into bootstrap why not creating a gem for your Custom
00:40:58.920 Design system which can be reused in all your apps
00:41:04.980 either way I hope matesick will help you escape the front-end Hustle
00:41:13.980 good point we've talked about beautiful reactive web uis implemented in pure Ruby but we haven't talked about you
00:41:22.740 now it's your turn go to GitHub and give made secure core and made seg your
00:41:28.140 bootstrap a star if you like the project follow mate Sega Twitter to get news and
00:41:33.900 helpful tips around mate stack and hatchdocs.maidstack.io and get started
00:41:39.119 without getting started guide building the shown Twitter clone step by step
00:41:44.760 jump on our Discord Discord server and say hello share feedback and get
00:41:49.859 community support and contribute create issues reporting
00:41:56.400 bugs or request missing features get an onboarding from me personally and
00:42:01.980 become a member of the core team and help to build an amazing tool for rail
00:42:07.200 slippers and enable them to have fun again when it comes to building reactive
00:42:12.240 web uis I'm super happy to get to know you better and answer any questions around
00:42:18.960 mate SEC on Discord in my railsconf q a slot starting April 14 2 30 PM eastern
00:42:27.599 time and honestly anytime on online there thanks for listening and have a
00:42:33.480 wonderful race conf experience