Closed SamMousa closed 7 months ago
Thanks Sam!
Can you also test the context menu (right click), the modals (sort, transform), and opening a nested editor in a popup (right click on an object -> edit object). I think those need something extra to get the CSS variables.
I've fixed it so that it works, but it is not ideal because it requires internal knowledge of which classes to target. I'd propose a different approach instead, with the following goals in mind:
This means that themes are no longer competing with default styles
Since we cannot change the usage of non-prefixed CSS variables (they are in 3rd party code) this will need some extra work.
containerStyles
(https://github.com/rob-balfre/svelte-select#props)I can make a PR for this, and the nice thing is, it'll not break backwards compatibility, whereas this PR in its current state does (since external themes will not properly be prioritized over the default theme.
Thanks for diving into this Sam!
We indeed need to solve this, and the user shouldn't need to know about the internals. I.e. this example custom_theme_color should keep working.
It would be great if you can work out a solution for this, thanks!
It makes sense to introduce prefixed variants for the svelte-select
variables.
I do not yet understand the need to define everything as default variables as SCSS to be used as a fallback for the CSS variables, can you explain that?
I do not yet understand the need to define everything as default variables as SCSS to be used as a fallback for the CSS variables, can you explain that?
Given the requirements:
:root
:root
Since you cannot set a CSS variable if not set, this is an issue. So instead of initializing our own CSS variables, we shouldn't do that at all. So instead of doing this:
:root {
--jse-color: red;
}
And then using it somewhere like this:
<div class="header">Header</div>
<style>
.header {
color: var(--jse-color);
}
</style>
We should / could be doing this:
$jse-color: red;
<div class="header">Header</div>
<style>
.header {
color: var(--jse-color, $jse-color);
}
</style>
After confirming that we can use SCSS variables like this of course.
Another approach would be to use internal CSS variables and define them instead.
:root {
--jse-internal-color: red;
}
And then using it somewhere like this:
<div class="header">Header</div>
<style>
.header {
color: var(--jse-color, var(--jse-internal-color));
}
</style>
Hope that makes sense
I understand what you mean, that makes sense indeed. Some thoughts:
var(--jse-color, $jse-color)
internally everywhere will indeed work. It will be tricky though to never forget to define the second argument with the default value. I guess in that case we could define internal CSS variables like --jse-color-internal: var(--jse-color, $jse-color)
and use this variable. But in that case it is possible to accidentally use --jse-color
instead of --jse-color-internal
, also not ideal 🤔. Or are there other options?We don't want variables leaking, so we cannot just target :root
That is indeed the ideal solution. However if this leads to more complexity and a harder to maintain code base, we can also accept that the variables are globally defined, as long as they all have a clear --jse-...
prefix to prevent naming collisions (the main goal). This may be a more pragmatic solution. What do you think?
Or are there other options?
I have not thought of other options yet...
This may be a more pragmatic solution. What do you think?
I did think of this option, but this actually will be very complicated for the case of svelte-select
. If we prefix some of their variables people who have a set of svelte-select variables will have to selectively prefix it with --jse-ss-
to work. Alternatively we introduce prefixed versions of all variables, but this is maintenance hell.
For that specific case I'd argue it might be cleaner to just use the no-styles
variant and sit down once to create a JSONEditor theme for it (where we don't support their variables for customization at all, but optionally introduce some of our own).
I even started on a branch that just changed the prefixing of svelte select variables but felt that led nowhere... How do you want to handle 3rd party custom css properties?
In conclusion I think not leaking variables is good, and the issues you describe we can easily catch with code style tools.
For example we could use https://stylelint.io/user-guide/rules/custom-property-pattern to enforce the correct pattern for all our files (forcing them to use --jse-prop-internal
) and apply that to all files except the themes directory.
FYI: I have not used this and am not sure how it'll work together with SCSS, but you get the idea.
True, it should be possible to use some linting tools help using the variables the right way. Intuitively, the var(--jse-color, $jse-color)
solution feels most simple to me than the --jse-color-internal: var(--jse-color, $jse-color)
approach, but I'm not sure how it will work out for real.
Maybe the best approach is to give this a try and see how it works out (not having global variables).
I think svelte-select
inside svelte-jsoneditor
should align and use the styling of svelte-jsoneditor
as much as possible (colors, padding, etc). Only thing is that svelte-jsoneditor
should not expose the variables it sets for svelte-select
globally. We can do something that boils down to .jse-main { --background: var(--jse-input-background) }
. If starting from no-styles
helps here (over tweaking the default styling a bit) I'm ok with that, but the default styling is very good and for svelte-jsoneditor
I only needed to configure a few of the variables. Shall we leave that as it is for now to keep this PR focused on getting rid of the globals, and in a separate PR think though if we can improve how we style svelte-select
?
No need to merge this PR btw, if we're redoing it as SCSS variables the default theme CSS file will disappear (or be transformed to an SCSS file).
Ohh, working on the PR now, found a really clean syntax.
In default-theme-variables.css
we define variables like this:
$tooltip-color: var(--jse-tooltip-color, $text-color);
$tooltip-background: var(--jse-tooltip-background, $modal-background);
$tooltip-border: var(--jse-tooltip-border, $main-border);
$tooltip-action-button-color: var(--jse-tooltip-action-button-color, $text-color-inverse);
$tooltip-action-button-background: var(--jse-tooltip-action-button-background, #4d4d4d);
That is the most ugly part. But now at all usages, we only need to use the $tooltip-color
variable.
This means rules code become easy:
default-theme-variables.scss
with a fallback to a CSS custom propertyPR soon
Tested it via
npm run dev
and then doing a visual inspection.This doesn't change the HTML structure, which is good, however it might break external theme modifications due to selector specificity. Ie someone having their own variables in
:root
vs us having the defaults in.jse-main
. According to the specificity calculator (https://specificity.keegan.st/) it should be fine. Since specificity is equal it is just about ordering.