Skip to content

Commit 6b496c2

Browse files
authored
feat: add support for standalone angular applications (#994)
* Updated uiSref directive to be an standalone directive * Updated uiSrefActive directive to be a standalone directive * Updated uiSrefStatus directive to be a standalone directive * Updated uiView component to be a standalone component * Imported directives instead of declaring them in UIRouterModule * Created a root provider function for UIRouter. * Fixed bug in uiView component not loading the CommonModule. * Updated downstream sample app for the tests. * Updated UISrefActive to use hostDirectives to implement the UISrefStatus directive. * Added provideUiRouter to global exports. * added a standalone v18 test project. * Added standalone version for downstream projects. * Updated package minor version * Add documentation for provideUIRouter() function. * Revert "Updated downstream sample app for the tests." This reverts commit 2955b86. * updated package version from 14.1.0 to 15.0.0. This change is introducing a potencial breaking change if projects use ui-view component as the bootstrap component.
1 parent e7b978e commit 6b496c2

28 files changed

+531
-7
lines changed

downstream_projects.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"projects": {
44
"sample-app-angular": "https://github.com/ui-router/sample-app-angular.git",
55
"angular18": "./test-angular-versions/v18",
6+
"angular18standalone": "./test-angular-versions/v18-standalone",
67
"typescript54": "./test-typescript-versions/typescript5.4"
78
}
89
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@uirouter/angular",
33
"description": "State-based routing for Angular",
4-
"version": "14.0.0",
4+
"version": "15.0.0",
55
"scripts": {
66
"clean": "shx rm -rf lib lib-esm _bundles _doc dist",
77
"compile": "npm run clean && ngc",

src/directives/uiSref.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ import { ReplaySubject, Subscription } from 'rxjs';
1717
* @internal
1818
* # blah blah blah
1919
*/
20-
@Directive({ selector: 'a[uiSref]' })
20+
@Directive({
21+
selector: 'a[uiSref]',
22+
standalone: true
23+
})
2124
export class AnchorUISref {
2225
constructor(public _el: ElementRef, public _renderer: Renderer2) {}
2326

@@ -78,6 +81,7 @@ export class AnchorUISref {
7881
@Directive({
7982
selector: '[uiSref]',
8083
exportAs: 'uiSref',
84+
standalone: true
8185
})
8286
export class UISref implements OnChanges {
8387
/**

src/directives/uiSrefActive.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ import { Subscription } from 'rxjs';
8282
*/
8383
@Directive({
8484
selector: '[uiSrefActive],[uiSrefActiveEq]',
85+
hostDirectives: [{
86+
directive: UISrefStatus,
87+
outputs: ['uiSrefStatus']
88+
}],
89+
standalone: true
8590
})
8691
export class UISrefActive {
8792
private _classes: string[] = [];

src/directives/uiSrefStatus.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,9 @@ function mergeSrefStatus(left: SrefStatus, right: SrefStatus): SrefStatus {
180180
* This API is subject to change.
181181
*/
182182
@Directive({
183-
selector: '[uiSrefStatus],[uiSrefActive],[uiSrefActiveEq]',
183+
selector: '[uiSrefStatus]',
184184
exportAs: 'uiSrefStatus',
185+
standalone: true
185186
})
186187
export class UISrefStatus {
187188
/** current statuses of the state/params the uiSref directive is linking to */

src/directives/uiView.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
} from '@uirouter/core';
3434
import { Ng2ViewConfig } from '../statebuilders/views';
3535
import { MergeInjector } from '../mergeInjector';
36+
import { CommonModule } from '@angular/common';
3637

3738
/** @hidden */
3839
let id = 0;
@@ -110,6 +111,8 @@ const ng2ComponentInputs = (factory: ComponentFactory<any>): InputMapping[] => {
110111
@Component({
111112
selector: 'ui-view, [ui-view]',
112113
exportAs: 'uiView',
114+
standalone: true,
115+
imports: [CommonModule],
113116
template: `
114117
<ng-template #componentTarget></ng-template>
115118
<ng-content *ngIf="!_componentRef"></ng-content>

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ export * from './statebuilders/lazyLoad';
77
export * from './statebuilders/views';
88
export * from './uiRouterConfig';
99
export * from './uiRouterNgModule';
10+
export * from './provideUiRouter';
1011

1112
export * from '@uirouter/core';

src/provideUiRouter.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { EnvironmentProviders, makeEnvironmentProviders } from "@angular/core";
2+
import { locationStrategy, makeRootProviders, RootModule } from "./uiRouterNgModule";
3+
import { _UIROUTER_INSTANCE_PROVIDERS, _UIROUTER_SERVICE_PROVIDERS } from "./providers";
4+
5+
/**
6+
* Sets up providers necessary to enable UI-Router for the application. Intended as a replacement
7+
* for [[UIRouterModule.forRoot]] in newer standalone based applications.
8+
*
9+
* Example:
10+
* ```js
11+
* const routerConfig = {
12+
* otherwise: '/home',
13+
* states: [homeState, aboutState]
14+
* };
15+
*
16+
* const appConfig: ApplicationConfig = {
17+
* providers: [
18+
* provideZoneChangeDetection({ eventCoalescing: true }),
19+
* provideUIRouter(routerConfig)
20+
* ]
21+
* };
22+
*
23+
* bootstrapApplication(AppComponent, appConfig)
24+
* .catch((err) => console.error(err));
25+
* ```
26+
*
27+
* @param config declarative UI-Router configuration
28+
* @returns an `EnvironmentProviders` which provides the [[UIRouter]] singleton instance
29+
*/
30+
export function provideUIRouter(config: RootModule = {}): EnvironmentProviders {
31+
return makeEnvironmentProviders([
32+
_UIROUTER_INSTANCE_PROVIDERS,
33+
_UIROUTER_SERVICE_PROVIDERS,
34+
locationStrategy(config.useHash),
35+
...makeRootProviders(config),
36+
]);
37+
}

src/uiRouterNgModule.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ import {
77
Injector,
88
APP_INITIALIZER,
99
} from '@angular/core';
10-
import { CommonModule, LocationStrategy, HashLocationStrategy, PathLocationStrategy } from '@angular/common';
10+
import { LocationStrategy, HashLocationStrategy, PathLocationStrategy } from '@angular/common';
1111
import { _UIROUTER_DIRECTIVES } from './directives/directives';
12-
import { UIView } from './directives/uiView';
1312
import { UrlRuleHandlerFn, TargetState, TargetStateDef, UIRouter, TransitionService } from '@uirouter/core';
1413
import { _UIROUTER_INSTANCE_PROVIDERS, _UIROUTER_SERVICE_PROVIDERS } from './providers';
1514

@@ -71,8 +70,9 @@ export function locationStrategy(useHash) {
7170
* This enables UI-Router to automatically register the states with the [[StateRegistry]] at bootstrap (and during lazy load).
7271
*/
7372
@NgModule({
74-
imports: [CommonModule],
75-
declarations: [_UIROUTER_DIRECTIVES],
73+
imports: [
74+
_UIROUTER_DIRECTIVES
75+
],
7676
exports: [_UIROUTER_DIRECTIVES],
7777
})
7878
export class UIRouterModule {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# V18
2+
3+
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.0.7.
4+
5+
## Development server
6+
7+
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
8+
9+
## Code scaffolding
10+
11+
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
12+
13+
## Build
14+
15+
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
16+
17+
## Running unit tests
18+
19+
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
20+
21+
## Running end-to-end tests
22+
23+
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
24+
25+
## Further help
26+
27+
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.

0 commit comments

Comments
 (0)