Stipple.jl
Stipple.jl copied to clipboard
Support for html based incremental UI
This is the follow up from discussion in Discord (https://discord.com/channels/774897545717219328/1056024283790462977) with @AbhimanyuAryan
Context is that I often find myself "fighting" to get the desired layout and styling, which I attribute from the various styles that both Stipple inject by default, plus de ones from Quasar.
In parallel, I found the html generated by GenieBuilder an appealing approach as it allows to write generic html and integrate Quasar elements directly as found from the docs. Ex: https://quasar.dev/vue-components/select#overview
<h3>SubTitle</h3>
<q-select v-model="item" :options="item_options" label="MyLabel"></q-select>
However, the above only works if called through @page or Stipple.Pages.Page, which injects various formating along a Genie footer. Alternatively, if trying to go with the regular html route:
html(
:mini,
:ui;
layout = :app,
context = MiniController,
Model = MiniController.handlers(),
)
It wouldn't display the reactive element (select items) even if the following js and css are added in the ui view:
...
<script src="/stipple.jl/master/assets/js/vue.js"></script>
<script src="/stipple.jl/master/assets/js/stipplecore.js"></script>
<script src="/stippleui.jl/master/assets/js/quasar.umd.min.js"></script>
...
My understanding for the above is that it misses the MiniController.js script that Stipple generates and add to the page.
So in summary, is there way to have a workflow where one could build the UI through straight html, similar to what GenieBuilder generates, while keeping in control of the styling elements? and keeping the traditional Genie structure where controller/views assets are stored under: /app/resources/SomeModule/?
The general idea would be to be able to start from a vanilla styled page (an html based view) and then be able to add a Bootstrap 4 or 5 version as one see fit, or any other assets ones may need.
Another motivation I see is that given the limited resources available to fully document Quasar UI elements, by encouraging such html based UI/Views which are aligned with Quasar actual docs, it may facilitate pilggy-backing on the larger Quasar ecosystem and comprehensive examples. Burden of docs on Stipple side could be limited to defining the scope of the Quasar elements that are accessible.
The tests mentionned are found here: https://github.com/jeremiedb/GenieExperiments.jl/blob/dev/routes.jl Note however that tests such as https://github.com/jeremiedb/GenieExperiments.jl/blob/0ae54adfe3bcb375cfb171ac0c9d111e004ddf74/routes.jl#L47 isn't working as expected (or aspirationally expected!) as the model elements don't get binded to the view
@jeremiedb Yes, definitely, you need the JavaScript/Vue model object that corresponds to the Julia ReactiveModel - this takes care of the data sync and is dynamically generated by the app (as opposed to the rest of the static assets).
However, @page doesn't do anything special, it simply aggregates existing APIs into higher level functionality, to save the users from having to put together chunks of code. More to the point, it automatically renders the UI inside a default layout: https://github.com/GenieFramework/Stipple.jl/blob/04a62b3f3e80b48492a8467858d9040eb1733e77/src/ReactiveTools.jl#L18 which calls the page function https://github.com/GenieFramework/Stipple.jl/blob/04a62b3f3e80b48492a8467858d9040eb1733e77/src/ReactiveTools.jl#L46
The page function https://github.com/GenieFramework/Stipple.jl/blob/04a62b3f3e80b48492a8467858d9040eb1733e77/src/Layout.jl#L84 then calls the layout function https://github.com/GenieFramework/Stipple.jl/blob/04a62b3f3e80b48492a8467858d9040eb1733e77/src/Layout.jl#L90 which ultimately calls Stipple.deps https://github.com/GenieFramework/Stipple.jl/blob/04a62b3f3e80b48492a8467858d9040eb1733e77/src/Layout.jl#L51
This sets up the needed assets and you can call it directly.
That being said, you need to be aware that: a) there is an issue with some of the Quasar CSS classes not working, we're currently investigating b) we have removed Twitter Bootstrap a long time ago as it conflicts with Quasar's styles (especially in regards to layout). So it's best not to use Bootstrap but rely exclusively on the Quasar styles.
Thanks a lot for these feedbacks it really helps better grasp the development logic. In my case, the missing component was figuring out a Stipple compatible layout:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<% Stipple.sesstoken() %>
<title>Hello Genie</title>
<% Genie.Assets.favicon_support() %>
<link rel="stylesheet" href="/css/app.css"> -->
</head>
<body>
<% page(model, partial = true, [@yield]) %>
</body>
</html>
Given the tight integration with Quasar, it effectively makes much sense to me to focus page layout integration with Quasar capabilities, espacially since they look solid. My understanding though is that beyong the row/col features, the q-layout isn't yet supported. Was it high on your radar to have such support? Being able to get started with https://v1.quasar.dev/layout-builder, then copy pasting the result in a view.jl.html such as :
<q-layout view="hHh lpR fFf">
<q-header elevated class="bg-primary text-white">
<q-toolbar>
<q-btn dense flat round icon="menu" @click="left = !left" />
...
</q-layout>
Would be quite a killer feature from my perspective.
I understand though that solving it will likely be tied in some way with https://github.com/GenieFramework/Stipple.jl/issues/115, where pages get injected with a fair amount of default css.
Not sure if it's related to you comment about some current quasar integration limitations, but I noticed that the Quasar's @click as found in the above example @click="left = !left" isn't working. Is it an issue or expected? v-on:click="flag = !flag" does works fine though.
Being able to develop Stipple pages out of html views aligned with original Quasar synthax is bringing a significant workflow improvement. I'll try writing the some blogpost highlighting my experience with it, as well as what I think have been some source of confusions with other new users, such as the @on, @bind @text macros which are less intuitive I believe from those as myself with limited front-end knowledge.
@jeremiedb yes I am aware of this @ issue. A vague guess would be that it's a parsing issue since @ is used by macros in Julia. I'll create a separate issue for this and debug this later
Regarding layout. Do you think the example below is more ideal for DEFAULT_LAYOUT???
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet" type="text/css">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/quasar.prod.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="q-app">
<q-layout view="hHh lpR fFf">
<q-header elevated class="bg-primary text-white">
<q-toolbar>
<q-toolbar-title>
<q-avatar>
<img src="https://cdn.quasar.dev/logo-v2/svg/logo-mono-white.svg">
</q-avatar>
Title
</q-toolbar-title>
</q-toolbar>
</q-header>
<q-page-container>
<router-view />
</q-page-container>
<q-footer elevated class="bg-grey-8 text-white">
<q-toolbar>
<q-toolbar-title>
<q-avatar>
<img src="https://cdn.quasar.dev/logo-v2/svg/logo-mono-white.svg">
</q-avatar>
Title
</q-toolbar-title>
</q-toolbar>
</q-footer>
</q-layout>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/quasar.umd.prod.js"></script>
<script>
const app = Vue.createApp({
setup () {
return {}
}
})
app.use(Quasar)
app.mount('#q-app')
</script>
</body>
</html>
created a separate issue for events: https://github.com/GenieFramework/Stipple.jl/issues/164
@AbhimanyuAryan I have tested the above layout by copy-asting it into a new layout, but it resulted the following:
julia> ┌ Error: 2023-01-19 18:58:27 UndefVarError: q__layout not defined
│ Stacktrace:
│ [1] (::GenieExperiments.UIDemoController.var"#213#228")()
│ @ GenieExperiments.UIDemoController
...
I suppose the q-layout element would need to be registered within StippleUI?
The test was performed with the following route: https://github.com/jeremiedb/GenieExperiments.jl/blob/dev/routes.jl#L35-L42
Layout file: https://github.com/jeremiedb/GenieExperiments.jl/blob/dev/app/layouts/stipple_layout.jl.html
If you launch the app in dev branch (https://github.com/jeremiedb/GenieExperiments.jl/blob/dev), the / is meant to provide a Stipple UI demo / cheatsheet. I shall be able to host, let me know if you see this useful.
The q__layout issue should be solved now, in the latest release.
As I understand from https://github.com/GenieFramework/GenieFramework.jl/commit/9e149daab4681f4e3d6bb4d7da45deaf42067cf7, the import of Stipple and StippleUI should be replaced by GenieFramework.
Doing so resolved the q__layout not defined error, but similar errors were however reported for the of the other quasar compoenents present in the layout: https://github.com/jeremiedb/GenieExperiments.jl/blob/main/app/layouts/stipple_layout.jl.html
This includes:
q__headerq__page__containerrouter__view
And likely the other ones as well.
Should a similar patch as the _q__layout one be done for all of the above?
Yes, I've seen some weird warnings too... I think the same functions are re/exported by multiple packages.