Needs work
Project:
Project Browser
Version:
1.0.x-dev
Component:
Code
Priority:
Normal
Category:
Plan
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
15 Jun 2022 at 16:35 UTC
Updated:
28 Nov 2023 at 20:53 UTC
Jump to comment: Most recent
Comments
Comment #2
bnjmnmThe
add-conditions-in-preprocessor-approachis an attempt at the first approach mentioned in the issue summary: using Svelte compile preprocessors to add conditionals to templates that have identified overrides. It's doesn't currently There's some comments in there regarding where it is at and what additional steps would be needed.And to restate: there's no agreed upon approach yet, this branch exists to build a prototype of one possible approach. Determining the best way to make Project Browser themeable is still very much a discussion.
Comment #4
bnjmnmThe
overrideAttributesMR proposes an approach that provides less themeability than render arrays or twig templates, while still giving themes the ability to have a resonable level of control over the appearance.The
Drupal.svAttr()function sends an array of attributes for potential processing. For example<div {...Drupal.svAttr('pbMainContainer', { class: 'container-1' })}> checks for the existience of a <code>Drupal.svAttr.pbMainContainer()function. If present, Project Browser will use the return value of that function to set attributes instead of the default values (which are{ class: 'container-1' })The MR currently demonstrates two overrides, but we could have this throughout the application
Comment #5
tim.plunkettComment #6
tim.plunkettReady for review (does contain some debug code, but the overall approach is ready)
Comment #7
chrisfromredfinAdding some clarity that there is code for TWO different approaches, as described above, but as there's just one open MR, you cannot easily see both.
For approach 1 (allow overriding whole Svelte components, but requires an app rebuild): https://git.drupalcode.org/issue/project_browser-3285889/-/compare/1.0.x...
For approach 2 (allow pushing classes down into the markup, does not require app rebuild): https://git.drupalcode.org/project/project_browser/-/merge_requests/176/...
Comment #8
chrisfromredfinI had a third hare-brained idea but I think I think might kind of work. Please help me compare and contrast with the other two available options. Here's my summary:
1. The first approach gives the most amount of control to the theme, but requires a rebuild of the main project browser app, and results in different / conditional markup.
2. The second approach sacrifices the maximum flexibility for the ability to provide its own classes, but does not require rebuilds (which I do like).
3. However, with second approach, is it not feasible for us to just provide one top-level class at the app level with the theme machine name... like on the App component or div wrapper, just provide `theme--olivero` or whatever? Then they can just style `.project-browser.theme--olivero anything { ... }`
4. A third approach. At the end of the day, the Svelte app is compiled to a bundle.js and a bundle.css. We provide it as a library, which means it could be overridden. Could we provide a tool which scans the current theme for .svelte files, fills in the rest of the holes with the "main" project browser, and recompiles the css/js into that theme's folder to serve their alternative app, fully-compiled? (I'm thinking of something as a yarn script that would copy the OG project browser code into temp path, then copy the overrides over those, then compile it, then copy the bundles to a specified location.)
...the above reminds me of the way Gin is a sort of permanent-enhancement of Claro.
Potential caveats/upsides/downsides of this approach:
- once you override, you've taken ownership. As things change, you might need to manually merge those changes into your override. (However, this doesn't seem radically different from how Twig templates are overridden now)
- it does give max flexibility - "alternative frontends" are entirely possible with a base provided.
- this flexibility increases the risk surface for breaking changes
- building this way just to provide your own styling/classes and not really changing the markup causes a large subset of overrides to maintain (for this reason, I might still suggest having my approach (3) above be also available
It would be nice to get this done as a potential third proof of concept.
The only other thing I looked at was potentially changing the paths of import statements during compile time, and though that is theoretically possible, it cannot use variables in the name of course: https://github.com/sveltejs/svelte/issues/6702 - there are some extensions that give you _some_ flexibility there, but the names need to be predictable: https://www.npmjs.com/package/@rollup/plugin-dynamic-import-vars
I think a total-app-rebuild works around these issues by merging the files in a temporary location to build the bundles.
Comment #9
bnjmnmGlad to see some take on this!
If this top level class was helpful it could be added automatically in
BrowserControllerregardless of theme. It would make targeting project-browser specific styling pretty easy, but this would likely have to be in addition to another approach as there needs to be a way to implement a theme's existing styles. Adding Claro specific classes while in Claro lets use existing styles only when Claro is is in use instead of making every admin theme look like Claro and we don't need to recreate styles that are already present in Claro's CSS.I tried this and it may be in one of the branches/histories. I was able to make entire
.sveltefile overridable, but I don't like the thought of someone having to reproduce an entire set of JS, HTML and CSS to make a small change to one of those. I spent some time looking into AST parsing to see if I could make specific sections overridable without success. I didn't get to a point where I could determine if this not happening was due to a technical or skills limitation.Another approach that might be feasible but could take some adjusting is splitting the svelte files into
theName.js.svelte,theName.css.svelteandtheName.html.sveltefiles. The build process would then concatenate the three into a .svelte file, and using overriden versions if found in a theme.Comment #10
chrisfromredfinI don't necessarily dislike the idea of splitting the pieces out, because it keeps hands out of the js to some extent, which is probably desirable. But then I'm not sure if that's adding more work / burden to do theming if you are wanting to change styles and markup. Not sure what the most common use case is - is it just changing markup & classes? If so, then themes can ship their own theName.html.svelte for most of it, which I do like.
I don't like that it sort of flies in the face of one of Svelte's core tenets, though - of single-file components. There are some use cases in Svelte (we haven't hit them, but some day we might) where there are multiple script tags of differing types, but I suppose that could all still get pulled into the same .js.svelte so probably that doesn't matter.
Comment #13
bnjmnmAlright! New MR
working_overrides_with_tests. As the name suggests, it includes test coverage!Here's a bit from the readme explaining how it works
Comment #14
effulgentsia commentedVery nice to see how far this issue has come already! I haven't reviewed it yet, but just a quick drive by:
My knee-jerk reaction is that I agree with this, and also the mentioned use-case of wanting to override html and css together in the same file, but without overriding the js.
I found https://github.com/homer0/svelte-extend, which seems to have done some thinking in this problem space, and at least superficially, I like the approach of keeping everything in a .svelte file, but having syntax within that file that clarifies what to override vs. what to use from the base component. I wonder if it would make sense to either use that library as-is or to incorporate some of its syntax into our custom approach.
Comment #15
bnjmnmI'd looked at https://github.com/homer0/svelte-extend in the past and based on my understanding of it (which may of course be wrong), there are two major things that suggest it is not applicable for the theming needs here.
<extend from="./base-component.svelte" html="before" />, extending a component requires knowing the exact location of the base component relative to the extender. This can differ depending on the site, and there's currently no discovery process. That's one of the reasons I went with a naming convention approach & require the over-riders to be specified in the build commandThat said, the current MR could function a bit more like this without too much trouble. The single .svelte file is already an option, and it wouldn't require too much additional logic to check which aspect(s) are being overidden and change only those. The
extendattribute would not be difficult to add either, and that seems like a very useful feature that would avoid unnecessary duplication. The only part I'm not yet sure about effort-wise is extending JS - svelte-extend appears to dynamically replace anything with matching variable names, but keeps the rest intact. There's an open source example I can reference if necessary, so it seems feasible.I am partial to having the .css .js .html options, as a means of quickly seeing what parts of the .svelte component are actually being overridden, but it's far away from any hill I'd die on.
Comment #19
chrisfromredfinAt a discussion at DrupalCon NA 2023 in Pittsburgh, the follow people met to discuss themability and the approaches proposed by Ben Mullins in this issue:
While there, the approaches were discussed, and the following decisions made:
Comment #20
chrisfromredfinComment #21
chrisfromredfinComment #22
mherchel+1 on @chrisfromredfin's comment in #19. I also want to state that there was consensus at the table that "perfect is the enemy of good" and if the insertion of markup into a component prefix/suffix is too time consuming, it should not block beta or stability.
Comment #23
chrisfromredfinAdding stable-blocking here, but noting from Mike's comment that we will split prefix & suffix out to a non-blocker if it proves too time-consuming.
Comment #24
andy-blumIs this issue still relevant after #3394904: Move styles out of svelte bundle to traditional Drupal library
Comment #25
chrisfromredfinYes, still relevant. Though moving it out, and that does enhance themability, we still want to convert values to custom properties, do BEM syntax, and ideally #3 if possible, allow prefix/suffix inserting with Drupal.theme().
Comment #26
andy-blumIs this necessary since the classes aren't obfuscated, the styles are BEMified, and everything is brought in via the Library API? I think once the plan outlined in #3394904 is done and the styles in PB are reduced to just basic layout styles (similar to the views module when viewed in Stark), admin themes will be responsible for theming the PB UI.
This probably needs someone investigating if this can be done safely. I imagine Drupal.theme() will break a lot of the svelte event bindings.