Codex ships the Link Component as a Less mixin as opposed to a Vue component. In the future other components may be implemented in this way as well.
Unfortunately, this mixin cannot currently be used inside other Less files that are processed using MediaWiki's ResourceLoader feature. This is because the link.less file beings with the following @import rule:
@import ( reference ) '@wikimedia/codex-design-tokens/theme-wikimedia-ui.less';
This import rule assumes that the Codex Design Tokens package has been installed using Node.js; ResourceLoader is not aware of these paths and doesn't know where to find the token files.
A similar problem affects the css-icon.less file: it imports from @wikimedia/codex-design-tokens/..., and it also imports @wikimedia/codex-icons/dist/codex-icon-paths.less, which ResourceLoader also won't be able to find.
Additionally, Less files in MW need to be able to import the mixin file itself. Our options for this are:
- Use a direct file path. This would look ugly: in extensions it'd look something like @import '../../../../../resources/lib/codex-design-tokens/mixins/link.less';
- Add resources/lib/codex-design-tokens/mixins to the list of default import paths, so that @import 'link.less'; works. However, this makes it unclear that it's being imported from Codex, and the names are so generic that they might be shadowed by files in the same directory that happen to have the same name.
- Make @import ( reference ) '@wikimedia/codex/mixins/link.less'; work. This has the benefit that the Codex docs would be accurate for MW use too.
I think we should do #3.
Solution
The fact that the public mixin files import the tokens is a problem for a different reason too: consumers of these mixins should be able to choose which theme to use, but the import statement in these mixin files hard-codes a theme name, forcing that theme to be used even if the consumer chose a different one (and overriding the consumer's theme choice for everything that comes below its import of the mixin file!). We can solve both this problem and the "MediaWiki doesn't know how to import from @wikimedia/codex-design-tokens" problem by removing these token imports from the public mixin files, and instead making the consumer responsible for importing the tokens.
Example usage in MediaWiki:
// Import the Codex tokens from the correct theme for the current skin, once T325237 is done. @import ( reference ) 'mediawiki.skin.variables.less'; @import ( reference ) '@wikimedia/codex/mixins/link.less';
Example usage outside of MediaWiki:
// Import the Codex tokens from whichever theme the caller wants. @import ( reference ) '@wikimedia/codex-design-tokens/theme-wikimedia-ui.less'; @import ( reference ) '@wikimedia/codex/mixins/link.less';
To make the import path of the mixins themselves work, we should alias @wikimedia/codex/ to resources/lib/codex. Less.php doesn't support aliases out of the box, but it's relatively straightforward to implement this by passing in a function to SetImportDirs. Using the same technique, we should alias @wikimedia/codex-icons/ to resources/lib/codex-icons, so that the import from the icons package in css-icon.less will work.
We can also use the import callback function to intercept imports from @wikimedia/codex-design-tokens/. These imports already won't work and will throw an error, but it would be nice if the error message could be something like "you can't import from @wikimedia/codex-design-tokens, import mediawiki.skin.variables.less if you want the tokens" as opposed to a generic and more confusing error message like "file not found".
Acceptance criteria
- Remove token imports from the public mixin files in Codex, and document that callers are responsible for importing the tokens https://gerrit.wikimedia.org/r/c/design/codex/+/890147/
- Make Codex's public Less mixins compatible with the older (PHP-based) version of the Less compiler that is used in MediaWiki https://gerrit.wikimedia.org/r/896197
- In MediaWiki, add a Less import callback that remaps imports from @wikimedia/codex/ to resources/lib/codex/, and from @wikimedia/codex-icons/ to resources/lib/codex-icons/ https://gerrit.wikimedia.org/r/c/mediawiki/core/+/890145
- In that same Less import callback, throw a descriptive error when an import from @wikimedia/codex-design-tokens/ is attempted https://gerrit.wikimedia.org/r/c/mediawiki/core/+/890146
After the next Codex release:
- Add the mixin files to foreign-resources.yaml so they are placed in resources/lib/codex/mixins/ https://gerrit.wikimedia.org/r/c/mediawiki/core/+/894132
- Test that the link and css-icon mixins can be imported and work
- Document how to use Codex mixins in MW on mw:Codex