-
Notifications
You must be signed in to change notification settings - Fork 59
This is an early pre-release of Catalyst 2.0, released in order to test for bugs. You should not consider this production ready.
2.0 is a almost-from-the-ground-up rewrite of the core behaviours to make things a bit more consistent and also to allow for more flexibility throughout 2.0. We've also improved the ergonomics and usability of some of the features.
Features
There are many changes and subtle improvements, so we'd recommend sitting down with your favourite beverage and re-reading the guide (NOTE: for pre-releases you'll need to read the v2 branch source. Sorry). Here are some of our favourite new features though:
@attrand@targetcan now be setters, meaning you can trigger behaviour when they change.@attr,@target, and class names now all have consistent dasherized versions for within HTML.- The html literal versions of
@attrdrop thedata-prefix for better ergonomics. - Actions and Targets can now listen to closed shadowroots.
- We've added a new system for Abilities. We'll be adding two new abilities in the 2.0 release:
@loadableand@providable. See the guide for more. - You can create your own abilities for shared functionality!
Breaking Changes
Here's a summary of breaking changes in order of "you'll definitely need to change this" down to "this probably wont effect you".
🔴 @attr is no longer prefixed with data- in HTML
The @attr decorator used to dasherize a JS property name and then prefix it with data- for use in HTML, so in other words @attr fooBar in JS would result in data-foo-bar= in HTML. This is now no longer the case, and instead @attr fooBar will result in an HTML attribute name of foo-bar=. We decided to do this as it is more ergonomic, and less surprising. @attr names now work like class names: they get dasherized, no surprising prefixes.
What's the easiest fix?
The easiest way to handle this change is to prefix your JS properties with data, so @attr fooBar becomes @attr dataFooBar. No changes will need to be made to your HTML, and if you reference the HTML value in your JS (e.g. hasAttribute('data-foo-bar')) then this will also not need to change.
What's a better fix?
Drop the data- prefix from your HTML attributes, as this will be more ergonomic. You might also need to drop the data- prefix in any JS where you reference the literal HTML value in your JS (e.g. hasAttribute('data-foo-bar') should be hasAttribute('foo-bar')).
🔴 @attrs must consist of 2 words (camelcased)
In order to drop the data- prefix, we decided a good trade-off would be to require @attrs to consist of 2 words - in other words the HTML attribute name must have a dash. Names like @attr foo will need to be refactored to include 2 words (or one uppercase character), so for example @attr fooBar is acceptable.
What's the easiest fix?
The easiest way to handle this change is to prefix your JS properties with data which will also get around the dropping of the data prefix, so @attr foo becomes @attr dataFoo. No changes will need to be made to your HTML, and if you reference the HTML value in your JS (e.g. hasAttribute('data-foo-bar')) then this will also not need to change.
What's a better fix?
If you have @attr properties that are one word, you'll need to think of a name for them that consists of two words. Here are some examples to give you some inspiration:
@attr path->@attr pathName@attr valid->@attr isValid@attr changed->@attr hasChanged@attr error->@attr errorMessage@attr src->@attr srcURL@attr content->@attr contentText@attr json-> Literally anything else 😉.
🟡 @attr no longer sets observedAttributes, so attributeChangedCallback won't be fired.
We've changed how @attr updates its attributes, to use a mutationobserver under the hood - instead of attributeChangedCallback. There are many reasons for this change; it was surprising to users to see attributeChangedCallback being called for stuff that isn't in observedAttributes, also attributeChangedCallback didn't correctly coerce values - it's only called with string types. With Catalyst 2.0 you can instead add @attr to a setter, and have that respond to changes to the attribute.
What's the easiest fix?
If you don't have an attributeChangedCallback in your code, forget about it. If you do, then the easiest fix is to manually add observedAttributes to your class, to reflect all of the @attr decorated fields. So e.g. @attr fooBar would need static observedAttributes = ['foo-bar'].
What's a better fix?
Refactor your attributeChangedCallback to remove checks for your @attr decorated attributes, and use setters instead. For example:
🟡 @attr no longer sets the html in the connectedCallback
It was surprising to see attributes sprouting onto an element when it gets connected, and it isn't inline with how built-in elements behave. @attrs now do not set the html attribute value based on the initial value, instead the the html attribute value is used to override the default property value. This works more like built-in HTML elements:
const input = document.createElement('input') console.assert(input.type === 'text') // default value console.assert(input.hasAttribute('type') === false) // no attribute to override input.setAttribute('type', 'number') console.assert(input.type === 'number') // overrides based on attribute input.removeAttribute('type') console.assert(input.type === 'text') // back to default value
What's the easiest fix?
You probably won't need to do anything. If your code depends on the html attribute existing during connectedCallback, then a quick fix is to set the value to itself in your connectedCallback. e.g. if you have an @attr fooBar = 'hello' then in your connectedCallback add the line this.fooBar = this.fooBar.
What's a better fix?
If your code depends on the html attribute existing during connectedCallback, then you should refactor your code. Strategies around this vary, but generally you should refer to the property name rather than the html literal value, alternatively if you still need to access the html literal value you can use a logical OR operator with the @attr default value, for example for an @attr fooBar = 'hello' you could use this.getAttribute('foo-bar') || 'hello'.
🟡 @controllers now will drop the Controller/Element/Component suffix
We've had feedback that Element is a fine suffix to drop, but it'd be nice to have symmetry with other frameworks and drop more suffixes - so in 2.0 we're also dropping Controller and Component suffixes. This means for an element named something like FooBarController in 1.x would be <foo-bar-controller />, it'll be <foo-bar /> in 2.x. Similarly FooBarComponent will also be <foo-bar />.
What's the easiest fix?
We audited all open source Catalyst components (and the closed source ones we had access to) and couldn't find any that end in Component or Controller, so we think it's really unlikely that this will be a problem.
Nevertheless, there's only one type of fix for this - and that's to drop the suffix from your HTML.
What's Changed
- clean up register tests, use register like decorator by @keithamus in clean up register tests, use register like decorator #214
- Expand docs on minification options by @keithamus in Expand docs on minification options #217
- Create guide page for Testing by @keithamus in Create guide page for Testing #218
- improve type definition for custom element class/instance by @keithamus in improve type definition for custom element class/instance #222
- Upgrade outdated packages by @keithamus in Upgrade outdated packages #223
- Improve docs around manual naming to avoid minifier mangling by @keithamus in Improve docs around manual naming to avoid minifier mangling #224
- Update target tests by @koddsson in Update target tests #225
- Support dasherizing symbols by using their descriptions by @keithamus in Support dasherizing symbols by using their descriptions #226
- add marks feature by @keithamus in add marks feature #227
- Cherry-pick attr tests from
use-delegates. by @koddsson in Cherry-pick attr tests fromuse-delegates. #228 - add createAbility by @keithamus in add createAbility #229
- amend attr tests to use two word attrs by @keithamus in amend attr tests to use two word attrs #230
- fix reference to lockfile by @koddsson in fix reference to lockfile #231
- Fix up types in tests by @keithamus in Fix up types in tests #232
- rework tests for bind by @keithamus in rework tests for bind #234
- improve documentation around method/getter/setter decorators by @keithamus in improve documentation around method/getter/setter decorators #235
- add initializer to marks by @keithamus in add initializer to marks #236
- split out ability & controllable by @keithamus in split out ability & controllable #238
- Add providable ability by @keithamus in Add providable ability #241
- Fix typo in providable code sample by @steves in Fix typo in providable code sample #242
- ability subclasses should retain original class name by @keithamus in ability subclasses should retain original class name #244
- add tag observer by @keithamus in add tag observer #245
- Fix providable bugs by @keithamus in Fix providable bugs #243
- ensure marks default to configurable+enumerable by @keithamus in ensure marks default to configurable+enumerable #246
- align jekyll versions to github pages by @keithamus in align jekyll versions to github pages #237
- Upgrade actions runners by @keithamus in Upgrade actions runners #247
- swap
@providabledecorator in docs by @keithamus in swap@providabledecorator in docs #248 - small doc tweaks by @keithamus in small doc tweaks #249
- rename tag-observer exports by @keithamus in rename tag-observer exports #253
- add createAbility docs by @keithamus in add createAbility docs #254
- tweaks to create-ability docs by @keithamus in tweaks to create-ability docs #256
- simplify abilities docs - link to expanded Create Ability docs by @keithamus in simplify abilities docs - link to expanded Create Ability docs #258
- export all v2 functions by @keithamus in export all v2 functions #262
Full Changelog: v1.4.2...v2.0.0-alpha1
This discussion was created from the release v2.0.0-alpha1.
All reactions
Replies: 1 comment 3 replies
Happy to see these changes! Are there plans for a stable release? I see pushes have slowed down in the past year, and currently don't feel confident to adopt the new patterns.
All reactions
Work on Catalyst has been de-prioritized and I don't wish to work on it in my personal time. As it's open source I'd encourage you to fork it and iterate from there.
Personally I'd love to see a spiritual successor to Catalyst that embraces standard ECMAScript decorators.
All reactions
Ah, that's a shame! My understanding was that Catalyst was used internally by GitHub, and the open source library was a reflection of what the team uses. Is this less the case now?
All reactions
There’s lots of the main codebase that uses 1.x and some smaller code bases use the 2.x alpha quite successfully, but in high priority areas teams are using React and consequently that’s where investment has shifted. As it stands catalyst 1.x is deemed sufficient that no further investment is needed and there’s no desire to upgrade the 1.x parts to 2.x due to the shift toward React.