Closed bitpshr closed 6 years ago
Still learning, so some ideas might not make sense!
This GitHub comment outlines my investigation into the mechanisms and potential improvements for theming.
The points below are numbered so you can quickly refer to it in your response.
When theming some widgets, for example built-in Dojo 2 Button widget, you may wish to override the existing styling:
Note: A widget must specify class names as themable so they be overridden.
When you, an end-user, would like to consume a widget and override its themable classes, you might create a new CSS file styles/themes/dark/button.m.css
:
.selector1 {
color: red;
}
.selector2 {
color: blue;
}
The main problem is this: How does an end user know: a) which selectors they can style. b) What part of the widget is affected by such a selector.
As a user, if I were writing a theme CSS file for a widget, it'd be great to get autosuggest values for the available selectors. Some editors do this based on the HTML which is detected.
How: I can only think of users having to install a custom code editor plugin which isn't ideal. So this is probably not feasible.
Just like how there are tools and plugins to convert HTML to CSS, what if we could generate a styles/themes/dark/button.m.css
file automatically, with the selectors already present, and rules ready to be filled in?
How:
To think about:
What if the Dojo CLI logged a message to the terminal to alert the user when they have used a class which is not themeable.
To think about:
What if the browser console logged the available themable classes.
To think about:
Educate and encourage widget authors to add all themable classes to their readme documentation.
To think about:
Inspect and see original class names through a DevTools extension.
To think about:
In a traditional app, if I were using a third party component, I might inspect it with DevTools, see what classes are used, write out the class in my custom.css
file and override things. Dojo 2 users can't do that because the classes have been "scoped" and can change. What if Dojo 2 was rearchitected so original class names were preserved? This would help with the problem being discussed in this comment, but also have improved developer ergonomics in view-source, inspect-element & testing workflows. To achieve the goal of scoping CSS, that could be explored separately (for example something like the scoped attribute - however this was removed from the spec).
To clarify: if we achieve this, the user would then have to 'inspect element' and use the class in their theme, however this doesn't necessarily identify which classes are available for theming and which are not.
To think about:
When exploring themes, I tried to understand how I could extend an existing theme from node_modules
.
The problem is this: If you try to use composes
with compiled/built CSS code:
composes: root from '../../../../node_modules/@dojo/widgets/themes/dojo/button.m.css';
The classes in that file have been 'scoped' and cannot be imported as the user would expect.
Publish the raw CSS files (e.g. to the NPM repository) so they can be 'composed' from directly,
To think about:
Noticed that the raw CSS module turns into a few files, one of which is: node_modules/@dojo/widgets/themes/dojo/button.m.css.js
which has a piece of JSON inside it like this:
{"root":"_1lZxc2Ul","addon":"TAlDrfED","pressed":"_37ji2mWW","popup":"_29G5UqBS","disabled":"GlYj4g4z"," _key":"dojo-button"}
So I wonder if the composes
function (not sure who or what implements it) can somehow be enhanced so if it detects a .js extension:
.selector {
composes: root from '../../../../node_modules/@dojo/widgets/themes/dojo/button.m.js' /* <-- Notice the .js extension */
}
It automatically reads the JSON from that file and figures out which style rule you meant.
When you write composes: root from '../../../../node_modules/@dojo/widgets/themes/dojo/button.m.css';
The composes
function could check if there is a sourcemap, if there is, it extracts the relevant (e.g. root
) selector from the original file since the source map should have this information.
Would be nice to enhance the composes
function so it provides logging if it can not find the class the user is trying to import.
It's probably worth improving the experience of creating theme files. For example:
import * as Header from './Header.m.css';
export default {
'Header': Header
}
If you change 'Header'
-> into 'header'
there are no errors and it can take a while to realize what the problem is.
@agubler @matt-gadd @kitsonk let me know if you have any thoughts/clarifications 👍
Having spent some time looking into this, I think that the problem of scaffolding out a new theme for existing widgets can be achieved by making a few changes to our theming approach:
css
to top level theme
directory_key
created within grunt-dojo2
to use the packagename
from package.json
. For example the Button
key from our widgets
repo would change from dojo-button
to @dojo/widgets/button
.The above changes create a structure which allows for themeable css to be easily located and for it's location to be consistent between both distributable components and a users application.
I have created a command line POC that locates and scaffolds a theme for a user given the packagenames they with to theme and the widgets within those packages. This uses the generate .m.css.d.ts
files.
Links:
POC Video:
This comment is concerning project coordination to enable the theme generation command. This comment is mainly for my benefit. As there are a few 'moving pieces', I really want to make sure my understanding on this is solid, hence the long explanation! There's nothing critical people need to read.
This comment is full of assumptions on my part so I hope people can correct any mistakes you notice! This is my understanding of what we need to do to accomplish this goal:
To run: dojo create app -n my-app
and then dojo create theme
and successfully create a theme file and CSS files.
When the user runs: dojo create app
, the repo dojo/cli-create-app
is used to scaffold out a new app. The package.json of that repo, comes from here: src/templates/package.json
so we need to consider two things here:
"@dojo/widgets": "~0.3.0"
up to date? Will it pull in the latest version of dojo/widgets
?dojo create something
in your brand new Dojo 2 app, it checks for a repo in node_modules
named cli-create-something
. We have created a https://github.com/dojo/cli-create-theme
(PR still needs merging) so we need to add that repo to the devDependencies
of the templated package.json
within cli-create-app
. (question: can we merge it?)The above two points, when executed, should mean: when you run dojo create app -n my-app
, you now get a new command dojo create theme
.
Moving onto the next point: the widgets repo has changed, and as a result, its 'output' (e.g. the artifact) must also change. This will not happen by default. To clarify what the change is: The artifact is a dojo-widgets-0.3.1-rc.1.tgz
file. Unzipping that presents a file like dojo-widgets/dist/package/theme/button/button.m.css.js
which contains a snippet of code like this: " _key":"dojo-button"
. Our goal was to change that so it turns into: " _key":"@dojo/widgets/button"
To achieve this: We must ensure dojo/widgets
pulls in the latest grunt-dojo2
which (I think) it already does as "grunt-dojo2": "latest"
is present in the package.json
file of the dojo/widgets
repo. When it pulls in the latest grunt-dojo2
code (warning: PR still needs to be merged), it will receive new functionality which means means building the widgets repo will in turn create dojo-widgets/dist/package/theme/button/button.m.css.js
files which has this: " _key":"@dojo/widgets/button"
Finally, when we run dojo create theme
, thanks to the points previously mentioned, it should work!
Also can we merge this one? https://github.com/dojo/cli-create-theme/pull/1
We have discussed part of https://github.com/dojo/cli/issues/168#issuecomment-354773648 and agreed that when scaffolding out a new app, we will not bundle this new create theme
command with it.
Would still appreciate a review on https://github.com/dojo/cli-create-theme/pull/1 !
Can we start 'releasing' projects? More so that I and others can test the feature out end-to-end and we could do some QA on it! Do we have any resources that explain the whole process? Like when do we release and how does it work, and who does it?
I think we can consider this epic as closed now that we have published the initial release of @dojo/cli-create-theme
- All enhancements are now tracked as issues on the cli-create-theme repo.
Enhancement
We should create a tool that helps with theme generation. Specifically, the tool should help improve the following processes:
Package Version: rc