diff --git a/apps/daffio/src/app/app-routing.module.ts b/apps/daffio/src/app/app-routing.module.ts index c406671ce1..be013ae9ea 100644 --- a/apps/daffio/src/app/app-routing.module.ts +++ b/apps/daffio/src/app/app-routing.module.ts @@ -7,7 +7,7 @@ import { import { DAFF_DOCS_PATH } from '@daffodil/docs-utils'; import { DaffioMarketingFooterComponent } from './core/footer/marketing-footer/marketing-footer.component'; -import { DaffioNavHeaderContainer } from './core/nav/header/header.component'; +import { DaffioMarketingNavContainer } from './core/nav/marketing/marketing.component'; import { DAFF_NAV_SIDEBAR_REGISTRATION } from './core/nav/sidebar.provider'; import { DaffioRouterNamedViewsEnum } from './core/router/named-views/models/named-views.enum'; import { DaffioRoute } from './core/router/route.type'; @@ -20,7 +20,7 @@ export const appRoutes: Routes = [ component: TemplateComponent, data: { daffNamedViews: { - [DaffioRouterNamedViewsEnum.NAV]: DaffioNavHeaderContainer, + [DaffioRouterNamedViewsEnum.NAV]: DaffioMarketingNavContainer, }, daffioSidebars: { [DAFF_NAV_SIDEBAR_REGISTRATION.id]: DAFF_NAV_SIDEBAR_REGISTRATION, diff --git a/apps/daffio/src/app/core/header/components/header/header-theme.scss b/apps/daffio/src/app/core/header/components/header/header-theme.scss index d3a85f2bb9..01717ddfa4 100644 --- a/apps/daffio/src/app/core/header/components/header/header-theme.scss +++ b/apps/daffio/src/app/core/header/components/header/header-theme.scss @@ -3,7 +3,17 @@ @mixin daffio-header-theme($theme) { $primary: daff-theme.daff-map-get($theme, primary); + $neutral: daff-theme.daff-map-get($theme, 'core', 'neutral'); + $base: daff-theme.daff-map-get($theme, 'core', 'base'); + .daffio-header { + // stylelint-disable selector-class-pattern + &.bordered { + .daffio-header__navbar { + border-bottom: 1px solid daff-theme.daff-illuminate($base, $neutral, 2); + } + } + } .daffio-header-item { &.active { color: daff-theme.daff-color($primary); diff --git a/apps/daffio/src/app/core/header/components/header/header.component.scss b/apps/daffio/src/app/core/header/components/header/header.component.scss index f2006fd66d..9bec21b1a5 100644 --- a/apps/daffio/src/app/core/header/components/header/header.component.scss +++ b/apps/daffio/src/app/core/header/components/header/header.component.scss @@ -3,6 +3,7 @@ :host { $root: '.daffio-header'; display: block; + box-sizing: border-box; ::ng-deep { .daffio-header-item { diff --git a/apps/daffio/src/app/core/header/components/header/header.component.ts b/apps/daffio/src/app/core/header/components/header/header.component.ts index 9e06c82021..f32de431a0 100644 --- a/apps/daffio/src/app/core/header/components/header/header.component.ts +++ b/apps/daffio/src/app/core/header/components/header/header.component.ts @@ -2,6 +2,7 @@ import { Component, HostBinding, ChangeDetectionStrategy, + Input, } from '@angular/core'; @Component({ @@ -13,4 +14,5 @@ import { export class DaffioHeaderComponent { @HostBinding('class.daffio-header') class = true; + @Input() @HostBinding('class.bordered') bordered = false; } diff --git a/apps/daffio/src/app/core/nav/docs/docs.component.html b/apps/daffio/src/app/core/nav/docs/docs.component.html new file mode 100644 index 0000000000..fdb3b9b731 --- /dev/null +++ b/apps/daffio/src/app/core/nav/docs/docs.component.html @@ -0,0 +1,20 @@ + + + + + + @for (link of links$ | async; track $index) { + + @if (link.external) { + {{link.title}} + } @else { + {{ link.title }} + } + + } + + diff --git a/apps/daffio/src/app/core/nav/header/header.component.spec.ts b/apps/daffio/src/app/core/nav/docs/docs.component.spec.ts similarity index 84% rename from apps/daffio/src/app/core/nav/header/header.component.spec.ts rename to apps/daffio/src/app/core/nav/docs/docs.component.spec.ts index ca1e337150..f4cfabdcd7 100644 --- a/apps/daffio/src/app/core/nav/header/header.component.spec.ts +++ b/apps/daffio/src/app/core/nav/docs/docs.component.spec.ts @@ -10,25 +10,25 @@ import { BehaviorSubject } from 'rxjs'; import { DaffRouterDataService } from '@daffodil/router'; -import { DaffioNavHeaderContainer } from './header.component'; -import { DAFFIO_NAV_SIDEBAR_ID } from './sidebar-id'; +import { DaffioDocsNavContainer } from './docs.component'; import { DaffioRoute } from '../../router/route.type'; +import { DAFFIO_DOCS_NAV_SIDEBAR_ID } from '../../sidebar/docs-sidebar-id'; import { DaffioSidebarService } from '../../sidebar/services/sidebar.service'; import { DaffioNavLink } from '../link/type'; @Component({ - template: '', + template: '', standalone: true, imports: [ - DaffioNavHeaderContainer, + DaffioDocsNavContainer, ], }) class WrapperComponent {} -describe('DaffioNavHeaderContainer', () => { +describe('DaffioDocsNavContainer', () => { let component: WrapperComponent; let fixture: ComponentFixture; - let daffioHeaderContainer: DaffioNavHeaderContainer; + let docsNavContainer: DaffioDocsNavContainer; let dataSpy: BehaviorSubject; let sidebarServiceSpy: jasmine.SpyObj; let links: Array; @@ -69,7 +69,7 @@ describe('DaffioNavHeaderContainer', () => { component = fixture.componentInstance; fixture.detectChanges(); - daffioHeaderContainer = fixture.debugElement.query(By.css('daffio-nav-header-container')).componentInstance; + docsNavContainer = fixture.debugElement.query(By.css('daffio-docs-nav-container')).componentInstance; }); it('should create', () => { @@ -88,7 +88,7 @@ describe('DaffioNavHeaderContainer', () => { const sidebarButton = fixture.debugElement.query(By.css('[sidebar-button]')).nativeElement; sidebarButton.click(); - expect(sidebarServiceSpy.open).toHaveBeenCalledWith(DAFFIO_NAV_SIDEBAR_ID); + expect(sidebarServiceSpy.open).toHaveBeenCalledWith(DAFFIO_DOCS_NAV_SIDEBAR_ID); }); }); }); diff --git a/apps/daffio/src/app/core/nav/header/header.component.ts b/apps/daffio/src/app/core/nav/docs/docs.component.ts similarity index 89% rename from apps/daffio/src/app/core/nav/header/header.component.ts rename to apps/daffio/src/app/core/nav/docs/docs.component.ts index 7a07d66f76..1b3b14ae4d 100644 --- a/apps/daffio/src/app/core/nav/header/header.component.ts +++ b/apps/daffio/src/app/core/nav/docs/docs.component.ts @@ -26,15 +26,15 @@ import { import { DaffRouterDataService } from '@daffodil/router'; import { DaffThemeSwitchButtonModule } from '@daffodil/theme-switch'; -import { DAFFIO_NAV_SIDEBAR_ID } from './sidebar-id'; import { DaffioHeaderComponentModule } from '../../header/components/header.module'; import { DaffioRoute } from '../../router/route.type'; import { DaffioSidebarService } from '../../sidebar/services/sidebar.service'; +import { DAFFIO_NAV_SIDEBAR_ID } from '../header/sidebar-id'; import { DaffioNavLink } from '../link/type'; @Component({ - selector: 'daffio-nav-header-container', - templateUrl: './header.component.html', + selector: 'daffio-docs-nav-container', + templateUrl: './docs.component.html', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [ @@ -50,7 +50,7 @@ import { DaffioNavLink } from '../link/type'; AsyncPipe, ], }) -export class DaffioNavHeaderContainer implements OnInit { +export class DaffioDocsNavContainer implements OnInit { faBars = faBars; links$: Observable>; diff --git a/apps/daffio/src/app/core/nav/header/header.component.html b/apps/daffio/src/app/core/nav/marketing/marketing.component.html similarity index 100% rename from apps/daffio/src/app/core/nav/header/header.component.html rename to apps/daffio/src/app/core/nav/marketing/marketing.component.html diff --git a/apps/daffio/src/app/core/nav/marketing/marketing.component.spec.ts b/apps/daffio/src/app/core/nav/marketing/marketing.component.spec.ts new file mode 100644 index 0000000000..09fcdf2bd9 --- /dev/null +++ b/apps/daffio/src/app/core/nav/marketing/marketing.component.spec.ts @@ -0,0 +1,94 @@ +import { Component } from '@angular/core'; +import { + ComponentFixture, + TestBed, + waitForAsync, +} from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { RouterTestingModule } from '@angular/router/testing'; +import { BehaviorSubject } from 'rxjs'; + +import { DaffRouterDataService } from '@daffodil/router'; + +import { DaffioMarketingNavContainer } from './marketing.component'; +import { DaffioRoute } from '../../router/route.type'; +import { DAFFIO_MARKETING_NAV_SIDEBAR_ID } from '../../sidebar/marketing-sidebar-id'; +import { DaffioSidebarService } from '../../sidebar/services/sidebar.service'; +import { DaffioNavLink } from '../link/type'; + +@Component({ + template: '', + standalone: true, + imports: [ + DaffioMarketingNavContainer, + ], +}) +class WrapperComponent {} + +describe('DaffioMarketingNavContainer', () => { + let component: WrapperComponent; + let fixture: ComponentFixture; + let marketingNavContainer: DaffioMarketingNavContainer; + let dataSpy: BehaviorSubject; + let sidebarServiceSpy: jasmine.SpyObj; + let links: Array; + + beforeEach(waitForAsync(() => { + dataSpy = new BehaviorSubject({}); + sidebarServiceSpy = jasmine.createSpyObj('DaffioSidebarService', ['open']); + + TestBed.configureTestingModule({ + imports: [ + RouterTestingModule, + WrapperComponent, + ], + providers: [ + { + provide: DaffRouterDataService, + useValue: jasmine.createSpyObj('DaffRouterDataService', [], { data$: dataSpy }), + }, + { + provide: DaffioSidebarService, + useValue: sidebarServiceSpy, + }, + ], + }) + .compileComponents(); + + links = [ + { title: 'title1', url: 'url1' }, + { title: 'title2', url: 'url2' }, + ]; + dataSpy.next({ + daffioNavLinks: links, + }); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(WrapperComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + + marketingNavContainer = fixture.debugElement.query(By.css('daffio-nav-marketing-container')).componentInstance; + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should render the links', () => { + fixture.debugElement.queryAll(By.css('a[daffioHeaderItem]')).forEach((de, i) => { + expect(de.attributes['ng-reflect-router-link']).toEqual(links[i].url); + expect(de.nativeElement.innerText).toEqual(links[i].title); + }); + }); + + describe('when [sidebar-button] is clicked', () => { + it('should open the nav sidebar', () => { + const sidebarButton = fixture.debugElement.query(By.css('[sidebar-button]')).nativeElement; + sidebarButton.click(); + + expect(sidebarServiceSpy.open).toHaveBeenCalledWith(DAFFIO_MARKETING_NAV_SIDEBAR_ID); + }); + }); +}); diff --git a/apps/daffio/src/app/core/nav/marketing/marketing.component.ts b/apps/daffio/src/app/core/nav/marketing/marketing.component.ts new file mode 100644 index 0000000000..8ef01b7a8c --- /dev/null +++ b/apps/daffio/src/app/core/nav/marketing/marketing.component.ts @@ -0,0 +1,72 @@ +import { + AsyncPipe, + NgFor, +} from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + OnInit, +} from '@angular/core'; +import { + RouterLink, + RouterLinkActive, +} from '@angular/router'; +import { FaIconComponent } from '@fortawesome/angular-fontawesome'; +import { faBars } from '@fortawesome/free-solid-svg-icons'; +import { + Observable, + map, +} from 'rxjs'; + +import { DaffLogoModule } from '@daffodil/branding'; +import { + DaffButtonComponent, + DaffIconButtonComponent, +} from '@daffodil/design/button'; +import { DaffRouterDataService } from '@daffodil/router'; +import { DaffThemeSwitchButtonModule } from '@daffodil/theme-switch'; + +import { DaffioHeaderComponentModule } from '../../header/components/header.module'; +import { DaffioRoute } from '../../router/route.type'; +import { DaffioSidebarService } from '../../sidebar/services/sidebar.service'; +import { DAFFIO_NAV_SIDEBAR_ID } from '../header/sidebar-id'; +import { DaffioNavLink } from '../link/type'; + +@Component({ + selector: 'daffio-nav-marketing-container', + templateUrl: './marketing.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: true, + imports: [ + DaffioHeaderComponentModule, + RouterLink, + RouterLinkActive, + DaffLogoModule, + DaffThemeSwitchButtonModule, + NgFor, + DaffButtonComponent, + DaffIconButtonComponent, + FaIconComponent, + AsyncPipe, + ], +}) +export class DaffioMarketingNavContainer implements OnInit { + faBars = faBars; + + links$: Observable>; + + constructor( + private routerData: DaffRouterDataService, + private sidebarService: DaffioSidebarService, + ) {} + + ngOnInit(): void { + this.links$ = this.routerData.data$.pipe( + map((data) => data.daffioNavLinks), + ); + } + + openSidebar() { + this.sidebarService.open(DAFFIO_NAV_SIDEBAR_ID); + } +} diff --git a/apps/daffio/src/app/docs/components/doc-article/component.scss b/apps/daffio/src/app/docs/components/doc-article/component.scss index facde46e6a..604d9104b0 100644 --- a/apps/daffio/src/app/docs/components/doc-article/component.scss +++ b/apps/daffio/src/app/docs/components/doc-article/component.scss @@ -44,7 +44,6 @@ justify-content: center; background: var(--daff-theme); border: 0; - border-top: 1px solid rgb(var(--daff-theme-contrast-rgb), 0.1); border-bottom: 1px solid rgb(var(--daff-theme-contrast-rgb), 0.1); color: var(--daff-theme-contrast); overflow: auto; diff --git a/apps/daffio/src/app/docs/components/docs-list/docs-list.component.scss b/apps/daffio/src/app/docs/components/docs-list/docs-list.component.scss new file mode 100644 index 0000000000..56f0944ce5 --- /dev/null +++ b/apps/daffio/src/app/docs/components/docs-list/docs-list.component.scss @@ -0,0 +1,4 @@ +:host { + display: block; + padding: 1rem 0 0; +} diff --git a/apps/daffio/src/app/docs/components/docs-list/docs-list.component.ts b/apps/daffio/src/app/docs/components/docs-list/docs-list.component.ts index 5769608417..7d4016f6aa 100644 --- a/apps/daffio/src/app/docs/components/docs-list/docs-list.component.ts +++ b/apps/daffio/src/app/docs/components/docs-list/docs-list.component.ts @@ -39,6 +39,7 @@ const visit = (guide: DaffDocsNavList): DaffTreeData => ({ @Component({ selector: 'daffio-docs-list', templateUrl: './docs-list.component.html', + styleUrl: './docs-list.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [ diff --git a/apps/daffio/src/app/docs/design/design-routing.module.ts b/apps/daffio/src/app/docs/design/design-routing.module.ts index 18e4101780..33c06895ed 100644 --- a/apps/daffio/src/app/docs/design/design-routing.module.ts +++ b/apps/daffio/src/app/docs/design/design-routing.module.ts @@ -15,7 +15,6 @@ import { import { DAFFIO_DOCS_DESIGN_LIST_SIDEBAR_REGISTRATION } from './containers/docs-list/sidebar.provider'; import { DaffioDocsDesignComponentOverviewPageComponent } from './pages/components-overview/component-overview.component'; import { DaffioDocsDesignOverviewPageComponent } from './pages/overview/overview.component'; -import { DAFF_NAV_SIDEBAR_REGISTRATION } from '../../core/nav/sidebar.provider'; import { DaffioRoute } from '../../core/router/route.type'; import { DaffioDocsPageComponent } from '../pages/docs-page/docs-page.component'; import { DocsResolver } from '../resolvers/docs-resolver.service'; @@ -30,7 +29,6 @@ export const docsDesignRoutes: Routes = [ data: { docPrefix: `${DAFF_DOCS_PATH}/${DAFF_DOCS_DESIGN_PATH}`, daffioSidebars: { - [DAFF_NAV_SIDEBAR_REGISTRATION.id]: DAFF_NAV_SIDEBAR_REGISTRATION, [DAFFIO_DOCS_DESIGN_LIST_SIDEBAR_REGISTRATION.id]: DAFFIO_DOCS_DESIGN_LIST_SIDEBAR_REGISTRATION, }, daffioDockedSidebar: DAFFIO_DOCS_DESIGN_LIST_SIDEBAR_REGISTRATION.id, diff --git a/apps/daffio/src/app/docs/docs-routing.module.ts b/apps/daffio/src/app/docs/docs-routing.module.ts index 4f3d39bbfe..adf5658ede 100644 --- a/apps/daffio/src/app/docs/docs-routing.module.ts +++ b/apps/daffio/src/app/docs/docs-routing.module.ts @@ -13,7 +13,7 @@ import { import { DAFFIO_DOCS_LIST_SIDEBAR_REGISTRATION } from './containers/docs-list/sidebar.provider'; import { DaffioSimpleFooterComponent } from '../core/footer/simple-footer/simple-footer.component'; -import { DAFF_NAV_SIDEBAR_REGISTRATION } from '../core/nav/sidebar.provider'; +import { DaffioDocsNavContainer } from '../core/nav/docs/docs.component'; import { DaffioRouterNamedViewsEnum } from '../core/router/named-views/models/named-views.enum'; import { DaffioRoute } from '../core/router/route.type'; @@ -21,6 +21,10 @@ export const docsRoutes: Routes = [ { path: '', data: { + daffNamedViews: { + [DaffioRouterNamedViewsEnum.NAV]: DaffioDocsNavContainer, + [DaffioRouterNamedViewsEnum.FOOTER]: DaffioSimpleFooterComponent, + }, daffioNavLinks: [ { url: `/${DAFF_DOCS_PATH}/${DAFF_DOC_KIND_PATH_SEGMENT_MAP[DaffDocKind.GUIDE]}`, title: 'Guides' }, { url: `/${DAFF_DOCS_PATH}/${DAFF_DOC_KIND_PATH_SEGMENT_MAP[DaffDocKind.PACKAGE]}`, title: 'Packages' }, @@ -28,12 +32,8 @@ export const docsRoutes: Routes = [ { url: `/${DAFF_DOCS_PATH}/${DAFF_DOCS_DESIGN_PATH}`, title: 'Design' }, ], daffioSidebars: { - [DAFF_NAV_SIDEBAR_REGISTRATION.id]: DAFF_NAV_SIDEBAR_REGISTRATION, [DAFFIO_DOCS_LIST_SIDEBAR_REGISTRATION.id]: DAFFIO_DOCS_LIST_SIDEBAR_REGISTRATION, }, - daffNamedViews: { - [DaffioRouterNamedViewsEnum.FOOTER]: DaffioSimpleFooterComponent, - }, }, children: [ {