Skip to content

Commit b17f93b

Browse files
JeanMechekirjs
authored andcommitted
docs(docs-infra): Use category for signal forms guides
1 parent 640693d commit b17f93b

7 files changed

Lines changed: 124 additions & 62 deletions

File tree

adev/shared-docs/components/navigation-list/navigation-list.component.html

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
1-
<ng-template #navigationList let-navigationItems>
1+
<ng-template
2+
#navigationList
3+
let-navigationItems
4+
let-preserveOtherCategoryOrder="preserveOtherCategoryOrder"
5+
>
26
<ul
37
class="docs-navigation-list docs-faceted-list"
48
[class.docs-navigation-list-dropdown]="isDropdownView()"
59
>
6-
@for (itemGroup of groupItems(navigationItems); track $index) {
10+
@for (itemGroup of groupItems(navigationItems, preserveOtherCategoryOrder); track $index) {
711
@let groupLabel = itemGroup[0];
812
@let items = itemGroup[1];
9-
@if (groupLabel) {
10-
<li class="docs-navigation-group">{{ groupLabel | titlecase }}</li>
13+
@let firstItem = items[0];
14+
15+
@if (groupLabel && collapsableLevel() !== firstItem.level && items.length > 1) {
16+
<li class="docs-navigation-group">{{ groupLabel }}</li>
1117
}
1218
@for (item of items; track $index) {
13-
<li class="docs-faceted-list-item">
19+
<li
20+
class="docs-faceted-list-item"
21+
[class.single-entry]="items.length === 1 && item.level !== 1"
22+
>
1423
@let itemLabel = item.label!;
1524
@if (item.path) {
1625
@if (item.isExternal) {
@@ -28,7 +37,6 @@
2837
class="docs-faceted-list-item-text"
2938
>
3039
{{ item.label }}
31-
<ng-container *ngTemplateOutlet="itemStatus; context: {$implicit: item}" />
3240
</span>
3341

3442
@if (item.children && item.level! > 1 && !item.isExpanded) {
@@ -122,7 +130,11 @@
122130
<ng-container
123131
*ngTemplateOutlet="
124132
navigationList;
125-
context: {$implicit: item.children, level: item.level}
133+
context: {
134+
$implicit: item.children,
135+
level: item.level,
136+
preserveOtherCategoryOrder: item.preserveOtherCategoryOrder,
137+
}
126138
"
127139
/>
128140
}
@@ -132,7 +144,15 @@
132144
</ul>
133145
</ng-template>
134146

135-
<ng-container *ngTemplateOutlet="navigationList; context: {$implicit: navigationItems()}" />
147+
<ng-container
148+
*ngTemplateOutlet="
149+
navigationList;
150+
context: {
151+
$implicit: navigationItems(),
152+
preserveOtherCategoryOrder: preserveOtherCategoryOrder(),
153+
}
154+
"
155+
/>
136156

137157
<ng-template let-item #itemStatus>
138158
@if (item.status === 'new') {

adev/shared-docs/components/navigation-list/navigation-list.component.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,7 @@ a,
194194
margin-top: 2rem;
195195
}
196196
}
197+
198+
.single-entry:not(:first-child) {
199+
margin-top: 2rem;
200+
}

adev/shared-docs/components/navigation-list/navigation-list.component.spec.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88

99
import {ComponentFixture, TestBed} from '@angular/core/testing';
1010

11-
import {NavigationList} from './navigation-list.component';
11+
import {signal} from '@angular/core';
1212
import {By} from '@angular/platform-browser';
13-
import {NavigationItem} from '../../interfaces';
1413
import {provideRouter} from '@angular/router';
15-
import {signal} from '@angular/core';
14+
import {NavigationItem} from '../../interfaces';
1615
import {NavigationState} from '../../services';
16+
import {NavigationList} from './navigation-list.component';
1717

1818
const navigationItems: NavigationItem[] = [
1919
{
@@ -42,6 +42,7 @@ describe('NavigationList', () => {
4242
});
4343
fixture = TestBed.createComponent(NavigationList);
4444
fixture.componentRef.setInput('navigationItems', []);
45+
fixture.componentRef.setInput('preserveOtherCategoryOrder', false);
4546

4647
component = fixture.componentInstance;
4748
});

adev/shared-docs/components/navigation-list/navigation-list.component.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9+
import {NgTemplateOutlet} from '@angular/common';
910
import {ChangeDetectionStrategy, Component, inject, input, output} from '@angular/core';
11+
import {MatTooltipModule} from '@angular/material/tooltip';
12+
import {RouterLink, RouterLinkActive} from '@angular/router';
1013
import {NavigationItem} from '../../interfaces/index';
14+
import {IsActiveNavigationItem} from '../../pipes';
1115
import {NavigationState} from '../../services/index';
12-
import {RouterLink, RouterLinkActive} from '@angular/router';
1316
import {IconComponent} from '../icon/icon.component';
14-
import {IsActiveNavigationItem} from '../../pipes';
15-
import {NgTemplateOutlet, TitleCasePipe} from '@angular/common';
16-
import {MatTooltipModule} from '@angular/material/tooltip';
1717

1818
@Component({
1919
selector: 'docs-navigation-list',
@@ -24,14 +24,14 @@ import {MatTooltipModule} from '@angular/material/tooltip';
2424
IsActiveNavigationItem,
2525
NgTemplateOutlet,
2626
MatTooltipModule,
27-
TitleCasePipe,
2827
],
2928
templateUrl: './navigation-list.component.html',
3029
styleUrls: ['./navigation-list.component.scss'],
3130
changeDetection: ChangeDetectionStrategy.OnPush,
3231
})
3332
export class NavigationList {
3433
readonly navigationItems = input.required<NavigationItem[]>();
34+
readonly preserveOtherCategoryOrder = input.required<boolean>();
3535
readonly displayItemsToLevel = input(2);
3636
readonly collapsableLevel = input<number | undefined>();
3737
readonly expandableLevel = input(2);
@@ -62,14 +62,17 @@ export class NavigationList {
6262
return items.some((item) => !!item.category);
6363
}
6464

65-
protected groupItems(items: NavigationItem[]): Map<string, NavigationItem[]> {
65+
protected groupItems(
66+
items: NavigationItem[],
67+
preserveOtherCategoryOrder: boolean,
68+
): Map<string, NavigationItem[]> {
6669
const hasCategories = this.hasCategories(items);
6770
if (hasCategories) {
6871
const others: NavigationItem[] = [];
6972
const categorizedItems = new Map<string, NavigationItem[]>();
7073
for (const item of items) {
7174
const category = item.category || 'Other';
72-
if (category === 'Other') {
75+
if (!preserveOtherCategoryOrder && category === 'Other') {
7376
others.push(item);
7477
continue;
7578
}

adev/shared-docs/interfaces/navigation-item.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ export interface NavigationItem {
1717
contentPath?: string;
1818
status?: 'new' | 'updated';
1919
category?: string;
20+
preserveOtherCategoryOrder?: boolean; // true by default
2021
}

adev/src/app/core/layout/secondary-navigation/secondary-navigation.component.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
[navigationItems]="navigationItems"
1717
[displayItemsToLevel]="maxVisibleLevelsOnSecondaryNav()"
1818
[expandableLevel]="maxVisibleLevelsOnSecondaryNav()"
19+
[preserveOtherCategoryOrder]="true"
1920
(linkClicked)="close()"
2021
/>
2122
}
@@ -26,6 +27,7 @@
2627
[collapsableLevel]="level + maxVisibleLevelsOnSecondaryNav()"
2728
[expandableLevel]="level + maxVisibleLevelsOnSecondaryNav() + 1"
2829
[navigationItems]="[item]"
30+
[preserveOtherCategoryOrder]="item.preserveOtherCategoryOrder ?? false"
2931
[displayItemsToLevel]="level + maxVisibleLevelsOnSecondaryNav() + 1"
3032
(linkClicked)="close()"
3133
/>

adev/src/app/routing/sub-navigation-data.ts

Lines changed: 75 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,23 @@ import {isDevMode} from '@angular/core';
1010
import {NavigationItem} from '@angular/docs';
1111

1212
// These imports are expected to be red because they are generated a build time
13+
// @ts-ignore
1314
import FIRST_APP_TUTORIAL_NAV_DATA from '../../../src/assets/tutorials/first-app/routes.json';
15+
// @ts-ignore
1416
import LEARN_ANGULAR_TUTORIAL_NAV_DATA from '../../../src/assets/tutorials/learn-angular/routes.json';
17+
// @ts-ignore
1518
import DEFERRABLE_VIEWS_TUTORIAL_NAV_DATA from '../../../src/assets/tutorials/deferrable-views/routes.json';
19+
// @ts-ignore
1620
import SIGNALS_TUTORIAL_NAV_DATA from '../../../src/assets/tutorials/signals/routes.json';
21+
// @ts-ignore
1722
import SIGNAL_FORMS_TUTORIAL_NAV_DATA from '../../../src/assets/tutorials/signal-forms/routes.json';
23+
// @ts-ignore
1824
import ERRORS_NAV_DATA from '../../../src/assets/content/reference/errors/routes.json';
25+
// @ts-ignore
1926
import EXT_DIAGNOSTICS_NAV_DATA from '../../../src/assets/content/reference/extended-diagnostics/routes.json';
2027

21-
import {getApiNavigationItems} from '../features/references/helpers/manifest.helper';
2228
import {DEFAULT_PAGES} from '../core/constants/pages';
29+
import {getApiNavigationItems} from '../features/references/helpers/manifest.helper';
2330

2431
interface SubNavigationData {
2532
docs: NavigationItem[];
@@ -430,82 +437,105 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
430437
{
431438
label: 'Forms',
432439
status: 'updated',
440+
preserveOtherCategoryOrder: true,
433441
children: [
434442
{
435443
label: 'Overview',
436444
path: 'guide/forms',
437445
contentPath: 'guide/forms/overview',
438446
},
447+
448+
{
449+
label: 'Overview',
450+
path: 'guide/forms/signals/overview',
451+
contentPath: 'guide/forms/signals/overview',
452+
category: 'Signal Forms',
453+
status: 'new',
454+
},
455+
{
456+
label: 'Form models',
457+
path: 'guide/forms/signals/models',
458+
contentPath: 'guide/forms/signals/models',
459+
category: 'Signal Forms',
460+
status: 'new',
461+
},
462+
{
463+
label: 'Form model design',
464+
path: 'guide/forms/signals/model-design',
465+
contentPath: 'guide/forms/signals/designing-your-form-model',
466+
category: 'Signal Forms',
467+
status: 'new',
468+
},
469+
{
470+
label: 'Field state management',
471+
path: 'guide/forms/signals/field-state-management',
472+
contentPath: 'guide/forms/signals/field-state-management',
473+
category: 'Signal Forms',
474+
status: 'new',
475+
},
476+
{
477+
label: 'Validation',
478+
path: 'guide/forms/signals/validation',
479+
contentPath: 'guide/forms/signals/validation',
480+
category: 'Signal Forms',
481+
status: 'new',
482+
},
439483
{
440-
label: 'Signal forms',
484+
label: 'Custom controls',
485+
path: 'guide/forms/signals/custom-controls',
486+
contentPath: 'guide/forms/signals/custom-controls',
487+
category: 'Signal Forms',
488+
status: 'new',
489+
},
490+
{
491+
label: 'Comparison with other form systems',
492+
path: 'guide/forms/signals/comparison',
493+
contentPath: 'guide/forms/signals/comparison',
494+
category: 'Signal Forms',
495+
status: 'new',
496+
},
497+
{
498+
label: 'Migrating from Legacy Forms',
499+
path: 'guide/forms/signals/migration',
500+
contentPath: 'guide/forms/signals/migration',
501+
category: 'Signal Forms',
441502
status: 'new',
442-
children: [
443-
{
444-
label: 'Overview',
445-
path: 'guide/forms/signals/overview',
446-
contentPath: 'guide/forms/signals/overview',
447-
},
448-
{
449-
label: 'Form models',
450-
path: 'guide/forms/signals/models',
451-
contentPath: 'guide/forms/signals/models',
452-
},
453-
{
454-
label: 'Form model design',
455-
path: 'guide/forms/signals/model-design',
456-
contentPath: 'guide/forms/signals/designing-your-form-model',
457-
},
458-
{
459-
label: 'Field state management',
460-
path: 'guide/forms/signals/field-state-management',
461-
contentPath: 'guide/forms/signals/field-state-management',
462-
},
463-
{
464-
label: 'Validation',
465-
path: 'guide/forms/signals/validation',
466-
contentPath: 'guide/forms/signals/validation',
467-
},
468-
{
469-
label: 'Custom controls',
470-
path: 'guide/forms/signals/custom-controls',
471-
contentPath: 'guide/forms/signals/custom-controls',
472-
},
473-
{
474-
label: 'Comparison with other form systems',
475-
path: 'guide/forms/signals/comparison',
476-
contentPath: 'guide/forms/signals/comparison',
477-
},
478-
{
479-
label: 'Migrating from Legacy Forms',
480-
path: 'guide/forms/signals/migration',
481-
contentPath: 'guide/forms/signals/migration',
482-
},
483-
],
484503
},
485504
{
486505
label: 'Reactive forms',
487506
path: 'guide/forms/reactive-forms',
488507
contentPath: 'guide/forms/reactive-forms',
508+
category: 'Reactive Forms',
489509
},
490510
{
491511
label: 'Strictly typed reactive forms',
492512
path: 'guide/forms/typed-forms',
493513
contentPath: 'guide/forms/typed-forms',
514+
category: 'Reactive Forms',
494515
},
495516
{
496517
label: 'Template-driven forms',
497518
path: 'guide/forms/template-driven-forms',
498519
contentPath: 'guide/forms/template-driven-forms',
520+
category: 'Template driven Forms',
521+
},
522+
{
523+
label: 'Validate form input',
524+
path: 'guide/forms/form-validation',
525+
contentPath: 'guide/forms/form-validation',
526+
category: 'Reactive Forms',
499527
},
500528
{
501529
label: 'Validate form input',
502530
path: 'guide/forms/form-validation',
503531
contentPath: 'guide/forms/form-validation',
532+
category: 'Template driven Forms',
504533
},
505534
{
506535
label: 'Building dynamic forms',
507536
path: 'guide/forms/dynamic-forms',
508537
contentPath: 'guide/forms/dynamic-forms',
538+
category: 'Reactive Forms',
509539
},
510540
],
511541
},
@@ -1262,6 +1292,7 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
12621292
},
12631293
{
12641294
label: 'API Reference',
1295+
preserveOtherCategoryOrder: true,
12651296
children: [
12661297
{
12671298
label: 'Overview',

0 commit comments

Comments
 (0)