Hi all. I’ve tagged a new release of all the @codemirror/...
packages with a 0.18.0
version (they are bumped in sync for breaking changes on 0.x versions). This release improves styling and reconfiguration handling, and introduces a few incompatible changes which I’ll list below. There had been a ton of fixes accumulating on 0.17 minor releases as well, so if you haven’t upgraded for a while, you probably should.
Theming
@codemirror/view
:
The
themeClass
function and ``-style selectors in themes are no longer supported (prefixing withcm-
should be done manually now).Themes must now use
&
(instead of an extra$
) to target the editor wrapper element.The editor no longer adds
cm-light
orcm-dark
classes. Targeting light or dark configurations in base themes should now be done by using a&light
or&dark
top-level selector.
@codemirror/gutter
, @codemirror/panel
, @codemirror/tooltip
:
Extra CSS classes for gutters must now be specified with the
class
option. Thestyle
option no longer exists.
So if you defined your own themes, you can no longer use $
notation for “theme selectors” in the theme, but prefix the class selectors manually ($foo
becomes .cm-foo
). I figured removing one layer of magic, which wasn’t really pulling its weight, should make the system a bit more approachable.
To indicate the place of the top element in a theme selector (for the purpose of inserting the scope class in the right place), you now use &
instead of an extra $
(&
has a precedent as a current-scope placeholder in several CSS preprocessors), or &dark
/&light
if you want to target only editors with a given type of theme in a base theme.
So a theme like this…
EditorView.baseTheme({
"$activeLine": {...},
"$$dark $activeLine": {...}
})
Becomes…
EditorView.baseTheme({
".cm-activeLine": {...},
"&dark .cm-activeLine": {...}
})
When creating DOM elements, also prefix classes manually, since themeClass
no longer exists.
Highlighting
@codemirror/highlight
:
When multiple highlight styles are available in an editor, they will be combined, instead of the highest-precedence one overriding the others.
HighlightStyle.define
now expects an array, not a variable list of arguments.
The first point is unlikely to cause much problems, but if you’re defining a highlight style, you’ll have to type HighlightStyle.define([...])
instead of (without the brackets) HighlightStyle.define(...)
.
New features
Highlighting got some major new features. Beyond multiple highlighters being able to combine, we also have:
It is now possible to map style tags to static class names in
HighlightStyle
definitions with theclass
property.The new
classHighlightStyle
assigns a set of static classes to highlight tags, for use with external CSS.Highlight styles can now be scoped per language.
Reconfiguration
@codemirror/state
:
tagExtension
and thereconfigure
transaction spec property have been replaced with the concept of configuration compartments and reconfiguration effects (seeCompartment
,StateEffect.reconfigure
, andStateEffect.appendConfig
).
If you are doing dynamic reconfiguration, you’ll have to change your code a bit. Roughly, something like this…
const configTag = Symbol("myconfig")
const extension = tagExtension(...)
state.update({reconfigure: {[configTag]: ...}})
Now looks like…
const configCompartment = new Compartment
const extension = configCompartment.of(...)
state.update({effects: configCompartment.reconfigure(...)})
In short, reconfiguration happens through effects, and instead of talking about “tags” the terminology is “compartment” now—you divide your configuration into compartments whose content can later be changed.
Full reconfiguration also happens through effects (TransactionSpec.reconfigure
no longer exists).