@ethlete/core 5.0.0-next.61 → 5.0.0-next.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +56 -0
- package/fesm2022/ethlete-core.mjs +774 -405
- package/fesm2022/ethlete-core.mjs.map +1 -1
- package/generators/generators.json +10 -0
- package/generators/migrate-create-destroy/create-destroy.js +317 -0
- package/generators/migrate-create-destroy/migration.js +46 -0
- package/generators/migrate-create-destroy/schema.json +26 -0
- package/generators/migrate-legacy-color-themes/legacy-color-themes.js +123 -0
- package/generators/migrate-legacy-color-themes/migration.js +93 -0
- package/generators/migrate-legacy-color-themes/schema.json +26 -0
- package/generators/migrate-to-v5/removed-exports.js +94 -6
- package/migrations/legacy-color-themes.md +38 -0
- package/migrations/seo-directive-removed.md +2 -1
- package/migrations.json +15 -0
- package/package.json +11 -11
- package/types/ethlete-core.d.ts +269 -174
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
2
|
import { collectFiles } from './migration-files.js';
|
|
3
|
-
const REMOVED_EXPORTS = new Map([
|
|
4
|
-
...['Memo', 'MemoConfig', 'MemoResolver', 'MapLike'].map((name) => [name, 'the @Memo decorator']),
|
|
3
|
+
export const REMOVED_EXPORTS = new Map([
|
|
4
|
+
...['Memo', 'MemoConfig', 'MemoResolver', 'MapLike'].map((name) => [name, 'together with the @Memo decorator and has no replacement.']),
|
|
5
5
|
...[
|
|
6
6
|
'createProps',
|
|
7
7
|
'createHostProps',
|
|
@@ -29,7 +29,95 @@ const REMOVED_EXPORTS = new Map([
|
|
|
29
29
|
'PropHandlers',
|
|
30
30
|
'BindPropsOptions',
|
|
31
31
|
'UnbindPropsOptions',
|
|
32
|
-
].map((name) => [name, 'the props module']),
|
|
32
|
+
].map((name) => [name, 'together with the props module and has no replacement.']),
|
|
33
|
+
...['LetDirective', 'LetContext'].map((name) => [
|
|
34
|
+
name,
|
|
35
|
+
"in v5. Use Angular's `@let`. `@ethlete/cdk:migrate-to-v5` rewrites `*etLet` templates; without the cdk, rewrite them by hand.",
|
|
36
|
+
]),
|
|
37
|
+
...['IsActiveElementDirective', 'IS_ACTIVE_ELEMENT', 'IsElementDirective', 'IS_ELEMENT'].map((name) => [
|
|
38
|
+
name,
|
|
39
|
+
'in v5. Inside a scrollable, use `ScrollableIsActiveChildDirective`; `@ethlete/cdk:migrate-to-v5` rewrites it.',
|
|
40
|
+
]),
|
|
41
|
+
...['ObserveResizeDirective', 'ResizeObserverService', 'ResizeObserverFactory', 'createResizeObservable'].map((name) => [name, 'in v5. Use `signalElementDimensions()`.']),
|
|
42
|
+
...['ObserveContentDirective', 'ContentObserverService', 'MutationObserverFactory', 'createMutationObservable'].map((name) => [name, 'in v5. Use `signalElementMutations()`.']),
|
|
43
|
+
...[
|
|
44
|
+
'ObserveVisibilityDirective',
|
|
45
|
+
'OBSERVE_VISIBILITY_TOKEN',
|
|
46
|
+
'ObserveVisibilityChange',
|
|
47
|
+
'IntersectionObserverService',
|
|
48
|
+
'IntersectionObserverFactory',
|
|
49
|
+
'getIntersectionInfo',
|
|
50
|
+
'signalVisibilityChangeClasses',
|
|
51
|
+
].map((name) => [name, 'in v5. Use `signalElementIntersection()`.']),
|
|
52
|
+
...[
|
|
53
|
+
'ObserveScrollStateDirective',
|
|
54
|
+
'OBSERVE_SCROLL_STATE',
|
|
55
|
+
'ScrollObserverFirstElementDirective',
|
|
56
|
+
'ScrollObserverLastElementDirective',
|
|
57
|
+
'ScrollObserverIgnoreTargetDirective',
|
|
58
|
+
'SCROLL_OBSERVER_FIRST_ELEMENT_CLASS',
|
|
59
|
+
'SCROLL_OBSERVER_IGNORE_TARGET_CLASS',
|
|
60
|
+
'SCROLL_OBSERVER_LAST_ELEMENT_CLASS',
|
|
61
|
+
'SCROLL_OBSERVER_OBSERVING_FIRST_ELEMENT_CLASS',
|
|
62
|
+
'SCROLL_OBSERVER_OBSERVING_LAST_ELEMENT_CLASS',
|
|
63
|
+
'ScrollObserverScrollState',
|
|
64
|
+
'ObservedScrollableChild',
|
|
65
|
+
'areScrollStatesEqual',
|
|
66
|
+
].map((name) => [
|
|
67
|
+
name,
|
|
68
|
+
'in v5. Use `signalElementScrollState()`, or `ScrollableScrollState` of the `@ethlete/components` scrollable.',
|
|
69
|
+
]),
|
|
70
|
+
...['CursorDragScrollDirective', 'CURSOR_DRAG_SCROLLING_CLASS', 'CURSOR_DRAG_SCROLLING_PREPARED_CLASS'].map((name) => [name, 'in v5. Use `useCursorDragScroll()`.']),
|
|
71
|
+
...['RootBoundaryDirective', 'ROOT_BOUNDARY_TOKEN'].map((name) => [name, 'in v5. Use `provideBoundaryElement()`.']),
|
|
72
|
+
...['DelayableDirective', 'DELAYABLE_TOKEN'].map((name) => [name, 'in v5. Use `provideInfinityQueryResponseDelay()` from `@ethlete/query`.']),
|
|
73
|
+
...[
|
|
74
|
+
'SeoDirective',
|
|
75
|
+
'SEO_DIRECTIVE_TOKEN',
|
|
76
|
+
'SeoConfig',
|
|
77
|
+
'mergeSeoConfig',
|
|
78
|
+
'OpenGraph',
|
|
79
|
+
'TwitterCard',
|
|
80
|
+
'FacebookCard',
|
|
81
|
+
'AlternateLink',
|
|
82
|
+
].map((name) => [name, 'in v5. Use the `apply*Binding` functions; the SEO guide has a per-key migration table.']),
|
|
83
|
+
...['AnimatedOverlayDirective', 'AnimatedOverlayComponentBase'].map((name) => [
|
|
84
|
+
name,
|
|
85
|
+
'in v5. It moved to `@ethlete/cdk`; `@ethlete/components` overlays use the overlay strategy controller.',
|
|
86
|
+
]),
|
|
87
|
+
...[
|
|
88
|
+
'SelectionModel',
|
|
89
|
+
'ActiveSelectionModel',
|
|
90
|
+
'SelectionModelBinding',
|
|
91
|
+
'SelectionModelOptionValueFn',
|
|
92
|
+
'SelectionModelPropertyPath',
|
|
93
|
+
'SelectionModelTypes',
|
|
94
|
+
].map((name) => [name, 'in v5. It moved into the `@ethlete/cdk` select and has no public replacement.']),
|
|
95
|
+
...['FocusVisibleService'].map((name) => [name, 'in v5. Use `injectFocusVisibleTracker()`.']),
|
|
96
|
+
...['createMediaQueryObservable'].map((name) => [name, 'in v5. Use `injectBreakpointIsMatched()` or the other media query signals.']),
|
|
97
|
+
...['createReactiveBindings', 'ReactiveAttributes', 'ReactiveBindingResult'].map((name) => [name, 'in v5. Use `signalHostClasses()` / `signalHostAttributes()`.']),
|
|
98
|
+
...['debouncedControlValueSignal', 'DebouncedControlValueSignalOptions'].map((name) => [name, 'in v5. Debounce the `controlValueSignal()` value with `toObservable()` and `debounceTime()`.']),
|
|
99
|
+
...['ProviderResult', 'RootProviderResult', 'StaticProviderResult', 'CreateProviderOptions'].map((name) => [
|
|
100
|
+
name,
|
|
101
|
+
'in v5. It belonged to the removed `create*Provider` factories, which `@ethlete/core:migrate-provider-shape` rewrites.',
|
|
102
|
+
]),
|
|
103
|
+
...['VIEWPORT_CONFIG'].map((name) => [name, 'in v5. Use `provideViewportConfig()`.']),
|
|
104
|
+
...[
|
|
105
|
+
'ClickObserverService',
|
|
106
|
+
'ClickObserverFactory',
|
|
107
|
+
'DebugDirective',
|
|
108
|
+
'DEBUG_TOKEN',
|
|
109
|
+
'HostDirective',
|
|
110
|
+
'MaybeObservable',
|
|
111
|
+
'Primitive',
|
|
112
|
+
'Reference',
|
|
113
|
+
'Size',
|
|
114
|
+
'Validators',
|
|
115
|
+
'isEmptyArray',
|
|
116
|
+
'isObjectArray',
|
|
117
|
+
'isPrimitiveArray',
|
|
118
|
+
'ScrollEnhancementsConfig',
|
|
119
|
+
'SmartBlockScrollStrategy',
|
|
120
|
+
].map((name) => [name, 'in v5. It has no replacement.']),
|
|
33
121
|
]);
|
|
34
122
|
const ET_PROPS_ATTRIBUTE = /\betProps\b/;
|
|
35
123
|
export default async function reportRemovedExports(tree, scope) {
|
|
@@ -57,9 +145,9 @@ function findRemovedImports(tree, filePath) {
|
|
|
57
145
|
continue;
|
|
58
146
|
for (const element of bindings.elements) {
|
|
59
147
|
const name = (element.propertyName ?? element.name).text;
|
|
60
|
-
const
|
|
61
|
-
if (
|
|
62
|
-
messages.push(`${name} was removed from @ethlete/core
|
|
148
|
+
const successor = REMOVED_EXPORTS.get(name);
|
|
149
|
+
if (successor) {
|
|
150
|
+
messages.push(`${name} was removed from @ethlete/core ${successor}`);
|
|
63
151
|
}
|
|
64
152
|
}
|
|
65
153
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Move the runtime color theming to Tailwind 4
|
|
2
|
+
|
|
3
|
+
`provideColorThemes()` injects the color theme CSS at runtime and pairs with a Tailwind 3 config built from
|
|
4
|
+
`createTailwindColorThemes()`. It is deprecated: `@ethlete/components` expects
|
|
5
|
+
`provideColorThemesWithTailwind4()`, the CSS the Tailwind 4 generators emit, and a set of surface themes.
|
|
6
|
+
|
|
7
|
+
The theme data carries over unchanged. A codemod does the mechanical part; the rest is setup that depends
|
|
8
|
+
on the app.
|
|
9
|
+
|
|
10
|
+
## What to change
|
|
11
|
+
|
|
12
|
+
1. Run the codemod:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
nx g @ethlete/core:migrate-legacy-color-themes
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
It rewrites every `provideColorThemes(X)` imported from `@ethlete/core` into
|
|
19
|
+
`provideColorThemesWithTailwind4(X)`, fixes the import, and writes
|
|
20
|
+
`legacy-color-themes-migration-tasks.md` at the workspace root. Pass `--projects` or `--include` to
|
|
21
|
+
migrate one app at a time.
|
|
22
|
+
|
|
23
|
+
2. Work through `legacy-color-themes-migration-tasks.md`. It lists, per call site, the
|
|
24
|
+
`tailwind-4-color-theme` generator run that replaces the runtime styles, every Tailwind 3 helper left
|
|
25
|
+
in a config, and - when no app provides any yet - the surface themes to build.
|
|
26
|
+
|
|
27
|
+
3. Move the Tailwind 3 config to Tailwind 4, run both generators, and import the generated `.css` in each
|
|
28
|
+
app's global stylesheet. Keep the prefix the Tailwind 3 config used, so the utility names stay.
|
|
29
|
+
|
|
30
|
+
4. Derive the first surface themes from the app's existing page background, text, muted text and border
|
|
31
|
+
colors. Ask the user before inventing colors the app does not have.
|
|
32
|
+
|
|
33
|
+
5. Search the app's own CSS for `--et-color-alt-`. Those variables are not emitted any more; move the
|
|
34
|
+
region into its own `etProvideColor` scope and read `--et-color-primary` there.
|
|
35
|
+
|
|
36
|
+
6. Build the app and compare a page against the old one: the colors must match.
|
|
37
|
+
|
|
38
|
+
The guide is at <https://ethlete-sdk-docs.web.app/core/theming#migrating-from-runtime-theming>.
|
|
@@ -9,7 +9,8 @@ function call. Both are decisions about the call site.
|
|
|
9
9
|
|
|
10
10
|
## What to change
|
|
11
11
|
|
|
12
|
-
1. Find every component that injects `SeoDirective` or
|
|
12
|
+
1. Find every component that injects `SeoDirective` or `SEO_DIRECTIVE_TOKEN`, or lists the directive in
|
|
13
|
+
`hostDirectives` or `imports`.
|
|
13
14
|
2. Remove the directive from the component.
|
|
14
15
|
3. Replace the `updateConfig({ … })` call with one `apply*Binding` call per key it set.
|
|
15
16
|
4. Turn an Observable value into a signal: `toSignal()` at the edge of the component, or a
|
package/migrations.json
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
"name": "to-v5",
|
|
5
5
|
"version": "5.0.0-beta.11",
|
|
6
6
|
"kind": "auto",
|
|
7
|
+
"level": "required",
|
|
7
8
|
"description": "Rewrite the v4 core API into its v5 shape.",
|
|
8
9
|
"generator": "@ethlete/core:migrate-to-v5"
|
|
9
10
|
},
|
|
@@ -11,6 +12,7 @@
|
|
|
11
12
|
"name": "provider-shape",
|
|
12
13
|
"version": "5.0.0-next.37",
|
|
13
14
|
"kind": "auto",
|
|
15
|
+
"level": "required",
|
|
14
16
|
"description": "Rewrite destructured provider tuples into the tree-shakeable definition shape.",
|
|
15
17
|
"generator": "@ethlete/core:migrate-provider-shape",
|
|
16
18
|
"docs": "/core/providers"
|
|
@@ -19,6 +21,7 @@
|
|
|
19
21
|
"name": "seo-directive-removed",
|
|
20
22
|
"version": "5.0.0-next.41",
|
|
21
23
|
"kind": "assisted",
|
|
24
|
+
"level": "required",
|
|
22
25
|
"description": "SeoDirective and SeoConfig are gone. Every call site moves to the apply*Binding function for its key.",
|
|
23
26
|
"instructions": "./migrations/seo-directive-removed.md",
|
|
24
27
|
"docs": "/core/seo"
|
|
@@ -27,6 +30,7 @@
|
|
|
27
30
|
"name": "surface-interaction-swatch",
|
|
28
31
|
"version": "5.0.0-next.46",
|
|
29
32
|
"kind": "auto",
|
|
33
|
+
"level": "required",
|
|
30
34
|
"description": "Rewrite surface theme interactionColor maps into the { color, onColor, inkColor } swatch shape.",
|
|
31
35
|
"generator": "@ethlete/core:migrate-surface-interaction-swatch",
|
|
32
36
|
"docs": "/core/theming"
|
|
@@ -35,9 +39,20 @@
|
|
|
35
39
|
"name": "surface-theme-regenerate",
|
|
36
40
|
"version": "5.0.0-next.46",
|
|
37
41
|
"kind": "manual",
|
|
42
|
+
"level": "required",
|
|
38
43
|
"description": "Regenerate the surface theme stylesheet, so the new swatch reaches the CSS variables.",
|
|
39
44
|
"instructions": "./migrations/surface-theme-regenerate.md",
|
|
40
45
|
"docs": "/core/theming"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "legacy-color-themes",
|
|
49
|
+
"version": "5.0.0-next.62",
|
|
50
|
+
"kind": "assisted",
|
|
51
|
+
"level": "recommended",
|
|
52
|
+
"description": "Move the runtime color theming to Tailwind 4: provideColorThemes becomes provideColorThemesWithTailwind4, and the generated CSS and surface themes replace the runtime styles.",
|
|
53
|
+
"scan": "@ethlete/core:migrate-legacy-color-themes",
|
|
54
|
+
"instructions": "./migrations/legacy-color-themes.md",
|
|
55
|
+
"docs": "/core/theming#migrating-from-runtime-theming"
|
|
41
56
|
}
|
|
42
57
|
]
|
|
43
58
|
}
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ethlete/core",
|
|
3
|
-
"version": "5.0.0-next.
|
|
3
|
+
"version": "5.0.0-next.63",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"peerDependencies": {
|
|
7
|
-
"@angular/common": "22.1.
|
|
8
|
-
"@angular/core": "22.1.
|
|
9
|
-
"@angular/forms": "22.1.
|
|
10
|
-
"@angular/platform-browser": "22.1.
|
|
11
|
-
"@angular/router": "22.1.
|
|
7
|
+
"@angular/common": "^22.1.0",
|
|
8
|
+
"@angular/core": "^22.1.0",
|
|
9
|
+
"@angular/forms": "^22.1.0",
|
|
10
|
+
"@angular/platform-browser": "^22.1.0",
|
|
11
|
+
"@angular/router": "^22.1.0",
|
|
12
12
|
"@ethlete/types": "^2.0.0-beta.4",
|
|
13
|
-
"@floating-ui/dom": "1.
|
|
14
|
-
"@nx/devkit": "23.
|
|
15
|
-
"rxjs": "7.8.
|
|
16
|
-
"ts-morph": "21.0.
|
|
17
|
-
"typescript": "6.0.
|
|
13
|
+
"@floating-ui/dom": "^1.6.0",
|
|
14
|
+
"@nx/devkit": "^23.0.0",
|
|
15
|
+
"rxjs": "^7.8.0",
|
|
16
|
+
"ts-morph": "^21.0.0",
|
|
17
|
+
"typescript": "^6.0.0"
|
|
18
18
|
},
|
|
19
19
|
"peerDependenciesMeta": {
|
|
20
20
|
"@nx/devkit": {
|