|
| 1 | +## 9.0.0 (2025-09-15) |
| 2 | + |
| 3 | +### Features |
| 4 | + |
| 5 | +- **Type registration via decorators** (e.g., `Decorators.registerClass`, `Decorators.registerEditor`, etc.) is now deprecated (it still works but is not recommended): |
| 6 | + |
| 7 | + ```ts |
| 8 | + import { Decorators, Widget } from "@serenity-is/corelib"; |
| 9 | + |
| 10 | + @Decorators.registerClass("MyProject") |
| 11 | + export class MyType extends Widget<any> { |
| 12 | + } |
| 13 | + ``` |
| 14 | + |
| 15 | + Instead, use a static `[Symbol.typeInfo]` property declaration: |
| 16 | + |
| 17 | + ```ts |
| 18 | + import { Widget } from "@serenity-is/corelib"; |
| 19 | +
|
| 20 | + export class MyType extends Widget<any> { |
| 21 | + static [Symbol.typeInfo] = |
| 22 | + this.registerClass("MyProject.MyModule.MyType"); |
| 23 | + } |
| 24 | + ``` |
| 25 | + |
| 26 | + This new approach offers several advantages over decorators. Most importantly, decorator information is not emitted by TypeScript in declaration files (e.g., `.d.ts`), making it difficult or impossible to identify registration names for referenced project/npm package types. |
| 27 | + |
| 28 | + Another reason for this change is a longstanding bug in esbuild ([see issue](https://github.com/evanw/esbuild/issues/4087)) with decorators and property initializers, which currently only has a workaround by using `experimentalDecorators: true` in `tsconfig.json`. |
| 29 | + |
| 30 | + The new registration methods also support passing interfaces or attributes as an array in the second argument. For example, to set `@Decorators.panel(true)` on a class, you can do: |
| 31 | + |
| 32 | + ```ts |
| 33 | + import { Widget, PanelAttribute } from "@serenity-is/corelib"; |
| 34 | +
|
| 35 | + export class MyType extends Widget<any> { |
| 36 | + static [Symbol.typeInfo] = |
| 37 | + this.registerClass("MyProject.MyModule.MyType", |
| 38 | + [new PanelAttribute(true)]); |
| 39 | + } |
| 40 | + ``` |
| 41 | + |
| 42 | + Note: When using this new registration method, TypeScript will not allow any decorators on the containing type, as the `this` expression is referenced in a static field initializer. If you need to use third-party decorators, you can use an alternative registration style: |
| 43 | + |
| 44 | + ```ts |
| 45 | + import { Widget, classTypeInfo, registerType } from "@serenity-is/corelib"; |
| 46 | +
|
| 47 | + @someCustomDecorator("test") |
| 48 | + export class MyType extends Widget<any> { |
| 49 | + static [Symbol.typeInfo] = |
| 50 | + classTypeInfo("MyProject.MyModule.MyType"); |
| 51 | + static { registerType(this); } |
| 52 | + } |
| 53 | + ``` |
| 54 | + |
| 55 | + This is equivalent to `this.registerType`, as the `registerType` static method in `Widget` calls `classTypeInfo` and `registerType` internally. |
| 56 | + |
| 57 | + This style is also useful for formatter registration, as formatters typically do not have a base type and cannot simply call `this.registerType` like widget subclasses: |
| 58 | + |
| 59 | + ```ts |
| 60 | + export class MyFormatter implements Formatter { |
| 61 | + static [Symbol.typeInfo] = |
| 62 | + formatterTypeInfo("MyProject.MyModule.MyFormatter"); |
| 63 | + static { registerType(this); } |
| 64 | + } |
| 65 | + ``` |
| 66 | + |
| 67 | + For consistency, you may also choose to extend the new `FormatterBase` class: |
| 68 | + |
| 69 | + ```ts |
| 70 | + export class MyFormatter extends FormatterBase implements Formatter { |
| 71 | + static [Symbol.typeInfo] = |
| 72 | + this.registerFormatter("MyProject.MyModule.MyFormatter"); |
| 73 | + } |
| 74 | + ``` |
| 75 | + |
| 76 | + For all registration styles, you can now pass only the namespace ending with a dot (the enclosing type name will be auto-appended): |
| 77 | + |
| 78 | + ```ts |
| 79 | + import { Widget } from "@serenity-is/corelib"; |
| 80 | +
|
| 81 | + export class MyType extends Widget<any> { |
| 82 | + static [Symbol.typeInfo] = this.registerClass("MyProject.MyModule."); |
| 83 | + } |
| 84 | + ``` |
| 85 | + |
| 86 | + Sergen / Serenity.Pro.Coder now also generates namespace constants under the `Modules/ServerTypes/Namespaces.ts` file, so you can use them to avoid typos: |
| 87 | + |
| 88 | + ```ts |
| 89 | + import { Widget } from "@serenity-is/corelib"; |
| 90 | + import { nsMyModule } from "../../ServerTypes/Namespaces"; |
| 91 | +
|
| 92 | + export class MyType extends Widget<any> { |
| 93 | + static [Symbol.typeInfo] = this.registerClass(nsMyModule); |
| 94 | + } |
| 95 | + ``` |
| 96 | + |
| 97 | + We hope this will reduce mistakes when renaming classes or using a namespace with mismatched casing. |
| 98 | + |
| 99 | +- Added an `EditLink` function that can be used instead of `SlickHelpers.itemLink` with JSX elements. The `DataGrid` also has an `EditLink` arrow function for use in formatters. |
| 100 | +- The row type itself is now used as the base row type if a row type is passed to the `PropertyItemProvider`. |
| 101 | +- Imports generated by `ServerTypingsGenerator` are now ordered and organized. |
| 102 | +- You can now pass `formatterType` by reference in `PropertyItem`. |
| 103 | +- Added a `value` argument to the `Validator.optional` method, allowing validation methods to be called without an element—just a value—when desired. |
| 104 | +- Adjusted the `Validator`'s `onfocusout` method: if a required input is cleared and loses focus, it is still validated if it has a "required" rule. Otherwise, errors were not shown until the form is saved. |
| 105 | +- Introduced a new Inline Editing sample in the Grid Editor (StartSharp). |
| 106 | +- Added new options and improved features in `GridEditController` (StartSharp): |
| 107 | + - New `getPropertyItem` option to optionally override the column item. |
| 108 | + - The `bulkSaveHandler` option now works. |
| 109 | + - The `saveHandler` callback receives an `args` argument with a `defaultHandler` property, allowing you to call the default save handler when needed. |
| 110 | +- Splitted WizardDialog's renderContents method into renderButtons, renderCancelButton, renderBackButton, renderNextButton etc. to make it easier to modify/inject content (StartSharp) |
| 111 | + |
1 | 112 | ## 8.8.9 (2025-09-03) |
2 | 113 |
|
3 | 114 | ## Features |
|
0 commit comments