@a.nemreen/dga-ui 0.3.1 → 0.3.3
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/README.md +18 -6
- package/fesm2022/a.nemreen-dga-ui-cookies.mjs +303 -0
- package/fesm2022/a.nemreen-dga-ui-date-picker.mjs +385 -0
- package/fesm2022/a.nemreen-dga-ui-header.mjs +2615 -0
- package/fesm2022/a.nemreen-dga-ui.mjs +874 -4512
- package/package.json +20 -4
- package/types/a.nemreen-dga-ui-cookies.d.ts +201 -0
- package/types/a.nemreen-dga-ui-date-picker.d.ts +207 -0
- package/types/a.nemreen-dga-ui-header.d.ts +427 -0
- package/types/a.nemreen-dga-ui.d.ts +218 -1009
|
@@ -0,0 +1,2615 @@
|
|
|
1
|
+
import*as i from"@angular/core";import{Directive as y,inject as g,ElementRef as B,input as n,booleanAttribute as I,model as w,output as u,signal as l,contentChild as M,Injector as Y,DOCUMENT as Q,DestroyRef as W,viewChild as P,computed as s,effect as L,untracked as z,afterNextRender as S,HostListener as b,ChangeDetectionStrategy as K,Component as G}from"@angular/core";import{APP_BASE_HREF as Z,PlatformLocation as X}from"@angular/common";import{dgaSafeHref as O,dgaCx as c,DgaAvatar as A,DgaBadge as E,DgaField as H,DgaFormControl as F,DgaFormEnd as $,DgaIcon as R,DgaIconBadge as j,DgaModal as q,DgaTooltip as V}from"@a.nemreen/dga-ui";function J(k,e="/"){if(typeof window>"u")return!1;const t=O(k.trim(),e);if(!t)return!1;try{const o=new URL(t,window.location.origin);return o.protocol!=="http:"&&o.protocol!=="https:"||o.origin!==window.location.origin?!1:(window.location.assign(`${o.pathname}${o.search}${o.hash}`),!0)}catch{return!1}}class h{static ɵfac=i.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:i,type:h,deps:[],target:i.ɵɵFactoryTarget.Directive});static ɵdir=i.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"22.0.7",type:h,isStandalone:!0,selector:"[dgaHeaderLoginBeforeForm]",ngImport:i})}i.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:i,type:h,decorators:[{type:y,args:[{selector:"[dgaHeaderLoginBeforeForm]",standalone:!0}]}]});class x{static ɵfac=i.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:i,type:x,deps:[],target:i.ɵɵFactoryTarget.Directive});static ɵdir=i.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"22.0.7",type:x,isStandalone:!0,selector:"[dgaHeaderLoginAfterFields]",ngImport:i})}i.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:i,type:x,decorators:[{type:y,args:[{selector:"[dgaHeaderLoginAfterFields]",standalone:!0}]}]});class p{static ɵfac=i.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:i,type:p,deps:[],target:i.ɵɵFactoryTarget.Directive});static ɵdir=i.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"22.0.7",type:p,isStandalone:!0,selector:"[dgaHeaderLoginFooter]",ngImport:i})}i.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:i,type:p,decorators:[{type:y,args:[{selector:"[dgaHeaderLoginFooter]",standalone:!0}]}]});class m{static ɵfac=i.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:i,type:m,deps:[],target:i.ɵɵFactoryTarget.Directive});static ɵdir=i.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"22.0.7",type:m,isStandalone:!0,selector:"[dgaHeaderLoginForm]",ngImport:i})}i.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:i,type:m,decorators:[{type:y,args:[{selector:"[dgaHeaderLoginForm]",standalone:!0}]}]});function ee(k,e){const t=k.trim();if(t.endsWith("rem")){const o=Number.parseFloat(t);return Number.isFinite(o)?o*16:e}if(t.endsWith("px")){const o=Number.parseFloat(t);return Number.isFinite(o)?o:e}return e}const T="group relative inline-flex h-(--size-header-portal) shrink-0 cursor-pointer items-center gap-md rounded-sm px-xl font-sans text-body-md font-medium text-fg hover:bg-neutral-light focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus",te="pointer-events-none absolute start-xl end-xl bottom-0 h-[5px] rounded-full",ie="inline-flex min-h-5xl w-full cursor-pointer flex-col justify-center gap-xxs rounded-sm px-xl py-sm text-start text-body-md font-normal text-fg transition-colors hover:bg-neutral-light focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus",oe="inline-flex min-h-11xl w-full cursor-pointer flex-col justify-center gap-xs rounded-md border border-border bg-card px-2xl py-xl text-start transition-colors hover:border-primary hover:bg-primary-faint focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus",ae="relative flex min-h-7xl w-full cursor-pointer items-center gap-lg rounded-md px-xl py-md text-start text-body-md font-medium text-fg transition-colors hover:bg-neutral-light active:bg-neutral-light focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus",ne="flex min-h-6xl w-full cursor-pointer flex-col justify-center gap-xxs rounded-md px-xl py-md text-start text-body-md text-fg transition-colors hover:bg-neutral-light active:bg-neutral-light focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus";class v{host=g(B);baseHref=g(Z,{optional:!0})??g(X).getBaseHrefFromDOM()??"/";closeTimer=null;dropdownSyncFrame=null;lastDropdownStyleKey="";collapseId="dga-nav-collapse";dropLink=ie;dropTile=oe;mobileLink=ne;brand=n("",...ngDevMode?[{debugName:"brand"}]:[]);brandSlogan=n("",...ngDevMode?[{debugName:"brandSlogan"}]:[]);brandLogo=n("",...ngDevMode?[{debugName:"brandLogo"}]:[]);brandLogoAlt=n("شعار الجهة",...ngDevMode?[{debugName:"brandLogoAlt"}]:[]);brandPlaceholder=n(!1,{...ngDevMode?{debugName:"brandPlaceholder"}:{},transform:I});brandHref=n("#",...ngDevMode?[{debugName:"brandHref"}]:[]);navLabel=n("التنقل الرئيسي",...ngDevMode?[{debugName:"navLabel"}]:[]);menuToggleLabel=n("فتح قائمة التنقل",...ngDevMode?[{debugName:"menuToggleLabel"}]:[]);menuCloseLabel=n("إغلاق قائمة التنقل",...ngDevMode?[{debugName:"menuCloseLabel"}]:[]);appearance=n("default",...ngDevMode?[{debugName:"appearance"}]:[]);mobileNav=n("sheet",...ngDevMode?[{debugName:"mobileNav"}]:[]);sticky=n(!0,{...ngDevMode?{debugName:"sticky"}:{},transform:I});items=n([],...ngDevMode?[{debugName:"items"}]:[]);actions=n([],...ngDevMode?[{debugName:"actions"}]:[]);search=n(null,...ngDevMode?[{debugName:"search"}]:[]);searchQuery=w("",...ngDevMode?[{debugName:"searchQuery"}]:[]);notifications=n(null,...ngDevMode?[{debugName:"notifications"}]:[]);login=n(null,...ngDevMode?[{debugName:"login"}]:[]);user=n(null,...ngDevMode?[{debugName:"user"}]:[]);authenticated=w(!1,...ngDevMode?[{debugName:"authenticated"}]:[]);loginSubmitting=w(!1,...ngDevMode?[{debugName:"loginSubmitting"}]:[]);loginError=w("",...ngDevMode?[{debugName:"loginError"}]:[]);actionClick=u();searchSubmit=u();searchSuggestionSelect=u();searchVoice=u();notificationAction=u();loginSubmit=u();logout=u();userLinkClick=u();navLinkClick=u();mobileOpen=l(!1,...ngDevMode?[{debugName:"mobileOpen"}]:[]);openDropdown=l(null,...ngDevMode?[{debugName:"openDropdown"}]:[]);searchOpen=l(!1,...ngDevMode?[{debugName:"searchOpen"}]:[]);notificationsOpen=l(!1,...ngDevMode?[{debugName:"notificationsOpen"}]:[]);loginOpen=l(!1,...ngDevMode?[{debugName:"loginOpen"}]:[]);userMenuOpen=l(!1,...ngDevMode?[{debugName:"userMenuOpen"}]:[]);voiceListening=l(!1,...ngDevMode?[{debugName:"voiceListening"}]:[]);expandedNotificationId=l(null,...ngDevMode?[{debugName:"expandedNotificationId"}]:[]);loginEmail=l("",...ngDevMode?[{debugName:"loginEmail"}]:[]);loginPassword=l("",...ngDevMode?[{debugName:"loginPassword"}]:[]);showLoginPassword=l(!1,...ngDevMode?[{debugName:"showLoginPassword"}]:[]);loginEmailError=l("",...ngDevMode?[{debugName:"loginEmailError"}]:[]);loginPasswordError=l("",...ngDevMode?[{debugName:"loginPasswordError"}]:[]);dropdownPanelStyle=l({},...ngDevMode?[{debugName:"dropdownPanelStyle"}]:[]);customLoginForm=M(m,...ngDevMode?[{debugName:"customLoginForm"}]:[]);customLoginFooter=M(p,...ngDevMode?[{debugName:"customLoginFooter"}]:[]);dismissedNotificationIds=l(new Set,...ngDevMode?[{debugName:"dismissedNotificationIds"}]:[]);readNotificationIds=l(new Set,...ngDevMode?[{debugName:"readNotificationIds"}]:[]);dropdownTrigger=null;dropdownActionId=null;injector=g(Y);doc=g(Q);destroyRef=g(W);searchInputRef=P("searchInput",...ngDevMode?[{debugName:"searchInputRef"}]:[]);utilLayerRef=P("utilLayer",...ngDevMode?[{debugName:"utilLayerRef"}]:[]);searchPanelId="dga-header-search-panel";notificationsPanelId="dga-header-notifications-panel";loginPanelId="dga-header-login-panel";userPanelId="dga-header-user-panel";isPortal=s(()=>this.appearance()==="portal",...ngDevMode?[{debugName:"isPortal"}]:[]);appHref(e){return O(e,this.baseHref)}searchConfig=s(()=>this.search(),...ngDevMode?[{debugName:"searchConfig"}]:[]);searchActionId=s(()=>this.search()?.actionId??"search",...ngDevMode?[{debugName:"searchActionId"}]:[]);notificationsConfig=s(()=>this.notifications(),...ngDevMode?[{debugName:"notificationsConfig"}]:[]);notificationsActionId=s(()=>this.notifications()?.actionId??"notifications",...ngDevMode?[{debugName:"notificationsActionId"}]:[]);loginConfig=s(()=>this.login(),...ngDevMode?[{debugName:"loginConfig"}]:[]);loginActionId=s(()=>this.login()?.actionId??"login",...ngDevMode?[{debugName:"loginActionId"}]:[]);userConfig=s(()=>this.user(),...ngDevMode?[{debugName:"userConfig"}]:[]);hasCustomLoginForm=s(()=>!!this.customLoginForm(),...ngDevMode?[{debugName:"hasCustomLoginForm"}]:[]);hasCustomLoginFooter=s(()=>!!this.customLoginFooter(),...ngDevMode?[{debugName:"hasCustomLoginFooter"}]:[]);utilityOverlayOpen=s(()=>this.notificationsOpen()||this.loginOpen()||this.userMenuOpen(),...ngDevMode?[{debugName:"utilityOverlayOpen"}]:[]);visibleNotifications=s(()=>{const e=this.notifications()?.items??[],t=this.dismissedNotificationIds(),o=this.readNotificationIds();return e.filter(a=>!t.has(a.id)).map(a=>({...a,read:!!a.read||o.has(a.id)}))},...ngDevMode?[{debugName:"visibleNotifications"}]:[]);unreadNotificationCount=s(()=>this.visibleNotifications().filter(e=>!e.read).length,...ngDevMode?[{debugName:"unreadNotificationCount"}]:[]);constructor(){this.destroyRef.onDestroy(()=>this.removePortaledUtilLayer()),L(()=>{this.mobileNav(),z(()=>{this.mobileOpen()&&this.closeAll()})}),L(()=>{if(!this.utilityOverlayOpen())return;this.utilLayerRef()?.nativeElement&&this.portalUtilLayer(),S(()=>this.portalUtilLayer(),{injector:this.injector})}),L(()=>{this.authenticated()&&this.loginOpen()&&z(()=>this.closeLogin())})}portalUtilLayer(){const e=this.utilLayerRef()?.nativeElement;!e||e.parentElement===this.doc.body||this.doc.body.appendChild(e)}removePortaledUtilLayer(){const e=this.utilLayerRef()?.nativeElement;e?.parentElement===this.doc.body&&e.remove()}activeWideDropdown=s(()=>{if(!this.hoverMenus()&&this.isMobileViewport())return null;const e=this.openDropdown();if(e===null)return null;const t=this.items()[e];if(!t?.dropdown)return null;const o=this.resolveVariant(t);return o==="menu"?null:{index:e,item:t,variant:o}},...ngDevMode?[{debugName:"activeWideDropdown"}]:[]);hostClasses=s(()=>c("relative z-header block overflow-visible border-b border-border-subtle bg-nav font-sans text-fg",this.sticky()&&"sticky top-0 shadow-md"),...ngDevMode?[{debugName:"hostClasses"}]:[]);innerClasses=s(()=>c("relative flex w-full gap-lg px-(--wrapper-padding)",this.appearance()==="default"&&"min-h-6xl items-center py-md",this.appearance()==="portal"&&"h-(--size-header-portal) items-stretch"),...ngDevMode?[{debugName:"innerClasses"}]:[]);desktopNavClasses=s(()=>c("min-w-0 flex-1",this.appearance()==="default"&&"flex flex-wrap items-center gap-lg self-center",this.appearance()==="portal"&&"hidden md:flex md:items-stretch"),...ngDevMode?[{debugName:"desktopNavClasses"}]:[]);actionsClasses=s(()=>c("ms-auto flex shrink-0 items-stretch empty:hidden",this.isPortal()&&this.items().length>0&&"max-md:hidden"),...ngDevMode?[{debugName:"actionsClasses"}]:[]);mobilePanelClass(){const e=this.mobileOpen(),t=this.mobileNav();return c("flex flex-col overflow-hidden bg-nav md:hidden",t==="sheet"&&"fixed top-0 bottom-0 end-0 z-20 w-[min(16rem,70vw)] max-w-[16rem] rounded-s-xl border-s border-border shadow-2xl",t==="fullscreen"&&"fixed inset-0 z-40 rounded-none border-0 shadow-none",t==="push"&&"absolute inset-x-0 top-full z-20 max-h-[min(70dvh,28rem)] border-b border-border shadow-lg",e?"dga-mobile-nav-open":"dga-mobile-nav-closed",e&&t==="sheet"&&"dga-mobile-sheet-open",e&&t==="fullscreen"&&"dga-mobile-fs-open",e&&t==="push"&&"dga-mobile-push-open")}hoverMenus(){return typeof matchMedia!="function"?!1:matchMedia("(hover: hover) and (pointer: fine)").matches}isMobileViewport(){return typeof matchMedia!="function"?!1:matchMedia("(max-width: 767px)").matches}resolveVariant(e){const t=e.dropdown;return t?t.variant?t.variant:t.featured?"featured":t.columns?.length||t.layout==="columns"||t.layout==="rows"?"mega":"menu":"menu"}resolveLayout(e){const t=e.dropdown;return t?t.layout?t.layout:t.columns?.length?"columns":"list":"list"}colCount(e){return e.dropdown?.columns?.length??0}flatLinks(e){const t=e.dropdown;return t?t.links?.length?t.links:t.columns?.flatMap(o=>o.links)??[]:[]}columnsGridClass(e){return c("grid w-full gap-2xl py-lg",e>1&&"sm:grid-cols-2",e>2&&"lg:grid-cols-3",e>3&&"xl:grid-cols-4")}featuredGridClass(e,t){return c("grid w-full gap-3xl",e==="featured"&&t&&"lg:grid-cols-[minmax(0,1fr)_minmax(14rem,18rem)]")}navItemClass(e,t=!1){return c(T,"justify-center",e&&"text-fg-primary",t&&"bg-neutral-light")}mobileItemClass(e,t=!1){return c(ae,e&&"bg-primary-faint",t&&"bg-neutral-light")}indicatorClass(e){return c(te,e?"bg-primary group-hover:bg-primary":"bg-transparent group-hover:bg-fg-disabled")}actionClass(e){return c(T,"relative justify-center")}badgeClass(){return c("dga-action-badge absolute top-lg end-md flex h-lg min-w-lg","items-center justify-center rounded-full bg-error px-xxs","text-body-2xs font-medium text-on-color")}isIconOnly(e){return e.iconOnly!==!1}isSearchAction(e){return!!this.search()&&e.id===this.searchActionId()}isNotificationsAction(e){return!!this.notifications()&&e.id===this.notificationsActionId()}isLoginAction(e){return!!this.login()&&e.id===this.loginActionId()}actionTooltip(e){return this.isLoginAction(e)&&this.authenticated()&&this.user()?.name||e.label}actionAriaLabel(e){return this.actionTooltip(e)}actionExpanded(e){return this.isSearchAction(e)?this.searchOpen():this.isNotificationsAction(e)?this.notificationsOpen():this.isLoginAction(e)?this.authenticated()?this.userMenuOpen():this.loginOpen():null}actionControls(e){return this.isSearchAction(e)?this.searchPanelId:this.isNotificationsAction(e)?this.notificationsPanelId:this.isLoginAction(e)?this.authenticated()?this.userPanelId:this.loginPanelId:null}actionIndicatorActive(e){return this.isSearchAction(e)?this.searchOpen():this.isNotificationsAction(e)?this.notificationsOpen():this.isLoginAction(e)?this.authenticated()?this.userMenuOpen():this.loginOpen():!1}clearCloseTimer(){this.closeTimer!==null&&(clearTimeout(this.closeTimer),this.closeTimer=null)}scheduleClose(){this.clearCloseTimer(),this.closeTimer=setTimeout(()=>{this.openDropdown.set(null),this.closeTimer=null},120)}setBodyScrollLocked(e){typeof document>"u"||document.documentElement.classList.toggle("dga-nav-locked",e)}unlockBodyIfIdle(){this.mobileOpen()||this.utilityOverlayOpen()||this.setBodyScrollLocked(!1)}onItemEnter(e){if(!this.isMobileViewport()){if(!this.items()[e]?.dropdown){this.hoverMenus()&&this.scheduleClose();return}this.clearCloseTimer(),this.hoverMenus()&&this.openDropdown.set(e)}}onPanelEnter(){this.clearCloseTimer()}onHostLeave(e){if(!this.hoverMenus()||this.isMobileViewport())return;const t=e.relatedTarget;t&&this.host.nativeElement.contains(t)||this.scheduleClose()}toggleMobile(){this.mobileOpen.update(e=>!e),this.openDropdown.set(null),this.setBodyScrollLocked(this.mobileOpen())}toggleDropdown(e,t){t.stopPropagation(),!(this.hoverMenus()&&!this.isMobileViewport()&&this.openDropdown()===e)&&(this.clearCloseTimer(),this.closeSearch(),this.closeNotifications(),this.closeLogin(),this.closeUserMenu(),this.openDropdown.update(o=>o===e?null:e))}closeAll(){this.clearCloseTimer(),this.openDropdown.set(null),this.mobileOpen.set(!1),this.closeSearch(!1),this.closeNotifications(),this.closeLogin(),this.closeUserMenu(),this.setBodyScrollLocked(!1)}onAction(e,t){const o=this.triggerFromEvent(t);if(this.isSearchAction(e)){this.closeNotifications(),this.closeLogin(),this.closeUserMenu(),this.toggleSearch(),this.actionClick.emit(e);return}if(this.isNotificationsAction(e)){this.closeSearch(),this.closeLogin(),this.closeUserMenu(),this.toggleNotifications(o),this.actionClick.emit(e);return}if(this.isLoginAction(e)){this.closeSearch(),this.closeNotifications(),this.authenticated()?(this.closeLogin(),this.toggleUserMenu(o)):(this.closeUserMenu(),this.toggleLogin(o)),this.actionClick.emit(e);return}this.closeSearch(),this.closeNotifications(),this.closeLogin(),this.closeUserMenu(),this.actionClick.emit(e)}onMobileAction(e,t){const o=this.triggerFromEvent(t);if(this.isSearchAction(e)){this.mobileOpen.set(!1),this.setBodyScrollLocked(!1),this.closeNotifications(),this.closeLogin(),this.closeUserMenu(),this.toggleSearch(),this.actionClick.emit(e);return}if(this.isNotificationsAction(e)){this.mobileOpen.set(!1),this.closeSearch(),this.closeLogin(),this.closeUserMenu(),this.toggleNotifications(o),this.isMobileViewport()&&this.setBodyScrollLocked(!0),this.actionClick.emit(e);return}if(this.isLoginAction(e)){this.mobileOpen.set(!1),this.closeSearch(),this.closeNotifications(),this.authenticated()?(this.closeLogin(),this.toggleUserMenu(o)):(this.closeUserMenu(),this.toggleLogin(o)),this.isMobileViewport()&&this.setBodyScrollLocked(!0),this.actionClick.emit(e);return}this.actionClick.emit(e),this.closeAll()}closeUtilityOverlays(){this.closeSearch(),this.closeNotifications(),this.closeLogin(),this.closeUserMenu()}closePortalChromeMenus(){typeof document>"u"||document.dispatchEvent(new CustomEvent("dga-close-portal-chrome-menus"))}onCloseHeaderOverlays(){this.closeUtilityOverlays()}toggleSearch(){if(this.searchOpen()){this.closeSearch();return}this.openDropdown.set(null),this.closeNotifications(),this.closeLogin(),this.closeUserMenu(),this.closePortalChromeMenus(),this.searchOpen.set(!0)}onSearchModalOpenChange(e){if(e){this.searchOpen.set(!0);return}this.closeSearch()}focusSearchInput(){S(()=>this.searchInputRef()?.nativeElement.focus(),{injector:this.injector})}closeSearch(e=!0){this.searchOpen.set(!1),e&&this.stopVoice()}toggleNotifications(e){if(this.notificationsOpen()){this.closeNotifications();return}this.openDropdown.set(null),this.closeSearch(),this.closeLogin(),this.closeUserMenu(),this.closePortalChromeMenus(),this.notificationsOpen.set(!0);const t=this.visibleNotifications()[0];this.expandedNotificationId.set(t?.id??null),this.scheduleDropdownSync(this.notificationsActionId(),e),this.isMobileViewport()&&this.setBodyScrollLocked(!0)}closeNotifications(){this.notificationsOpen.set(!1),this.expandedNotificationId.set(null),this.clearDropdownAnchor(),this.unlockBodyIfIdle()}toggleLogin(e){if(this.loginOpen()){this.closeLogin();return}this.openDropdown.set(null),this.closeSearch(),this.closeNotifications(),this.closeUserMenu(),this.closePortalChromeMenus(),this.loginOpen.set(!0),this.scheduleDropdownSync(this.loginActionId(),e),this.isMobileViewport()&&this.setBodyScrollLocked(!0)}closeLogin(){this.loginOpen.set(!1),this.loginSubmitting.set(!1),this.loginError.set(""),this.loginEmailError.set(""),this.loginPasswordError.set(""),this.loginEmail.set(""),this.loginPassword.set(""),this.showLoginPassword.set(!1),this.clearDropdownAnchor(),this.unlockBodyIfIdle()}toggleUserMenu(e){if(this.userMenuOpen()){this.closeUserMenu();return}this.openDropdown.set(null),this.closeSearch(),this.closeNotifications(),this.closeLogin(),this.closePortalChromeMenus(),this.userMenuOpen.set(!0),this.scheduleDropdownSync(this.loginActionId(),e),this.isMobileViewport()&&this.setBodyScrollLocked(!0)}closeUserMenu(){this.userMenuOpen.set(!1),this.clearDropdownAnchor(),this.unlockBodyIfIdle()}onLoginEmailInput(e){this.loginEmail.set(e),this.loginEmailError()&&this.loginEmailError.set("")}onLoginPasswordInput(e){this.loginPassword.set(e),this.loginPasswordError()&&this.loginPasswordError.set("")}showLoginRegisterRow(e){return!!(e.registerPrompt||e.registerLabel||e.registerHref)}loginPanelOuterStyle(){const e=this.dropdownPanelStyle();if(this.isMobileViewport())return e;const t=this.loginConfig()?.panelWidth??"24rem";return{...e,width:`min(${t}, calc(100vw - 2rem))`}}loginPanelInnerStyle(){return this.isMobileViewport()?{maxHeight:`min(90svh, ${this.loginConfig()?.maxHeight??"44rem"})`}:{}}onLoginSubmit(e){e.preventDefault();const t=this.loginConfig(),o=this.loginEmail().trim(),a=this.loginPassword();this.loginEmailError.set(""),this.loginPasswordError.set(""),this.loginError.set("");let r=!1;o?/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(o)||(this.loginEmailError.set(t?.emailInvalidMessage??"Enter a valid email address"),r=!0):(this.loginEmailError.set(t?.emailRequiredMessage??"Email is required"),r=!0),a||(this.loginPasswordError.set(t?.passwordRequiredMessage??"Password is required"),r=!0),!r&&(this.loginSubmitting.set(!0),this.loginSubmit.emit({email:o,password:a}))}onUserLink(e){if(this.userLinkClick.emit(e),e.id==="logout"||e.danger){this.authenticated.set(!1),this.logout.emit(),this.closeUserMenu();return}this.closeUserMenu()}toggleNotificationExpand(e){this.expandedNotificationId.update(t=>t===e.id?null:e.id),this.notificationAction.emit({item:e,action:"select"})}onNotificationAction(e,t){t==="read"&&this.readNotificationIds.update(o=>new Set([...o,e.id])),t==="dismiss"&&(this.dismissedNotificationIds.update(o=>new Set([...o,e.id])),this.expandedNotificationId.update(o=>o===e.id?null:o)),t==="view"&&e.href&&J(e.href,this.baseHref),this.notificationAction.emit({item:e,action:t})}markAllNotificationsRead(){const e=this.visibleNotifications().map(t=>t.id);this.readNotificationIds.update(t=>new Set([...t,...e]))}clearSearchQuery(){this.searchQuery.set(""),queueMicrotask(()=>this.searchInputRef()?.nativeElement.focus())}applySearchSuggestion(e){const t=e.value??e.label;this.searchQuery.set(t),this.searchSuggestionSelect.emit(e),queueMicrotask(()=>this.searchInputRef()?.nativeElement.focus())}onSearchFormSubmit(e){e.preventDefault();const t=this.searchQuery().trim();this.searchSubmit.emit(t);const o=this.search();if(o?.resultsHref){const a=o.queryParam??"q",r=new URL(o.resultsHref,typeof window<"u"?window.location.origin:"http://localhost");t?r.searchParams.set(a,t):r.searchParams.delete(a),typeof window<"u"&&window.location.assign(`${r.pathname}${r.search}${r.hash}`)}this.closeSearch()}onSearchVoice(){if(this.searchVoice.emit(),typeof window>"u")return;const e=window,t=e.SpeechRecognition||e.webkitSpeechRecognition;if(!t)return;this.stopVoice();const o=new t;o.lang=typeof document<"u"&&document.documentElement.lang?document.documentElement.lang:"ar-SA",o.interimResults=!1,o.maxAlternatives=1,this.voiceListening.set(!0),o.onresult=a=>{const r=a.results[0]?.[0]?.transcript?.trim();r&&this.searchQuery.set(r),this.voiceListening.set(!1)},o.onerror=()=>this.voiceListening.set(!1),o.onend=()=>this.voiceListening.set(!1),this.speechRecognition=o,o.start()}speechRecognition=null;stopVoice(){this.speechRecognition?.stop(),this.speechRecognition=null,this.voiceListening.set(!1)}triggerFromEvent(e){const t=e?.currentTarget;return t instanceof HTMLElement?t:null}scheduleDropdownSync(e,t){this.dropdownActionId=e,this.dropdownTrigger=t??null,S(()=>this.requestDropdownSync(t),{injector:this.injector})}requestDropdownSync(e){if(typeof requestAnimationFrame!="function"){this.syncDropdownPanel(e);return}this.dropdownSyncFrame===null&&(this.dropdownSyncFrame=requestAnimationFrame(()=>{this.dropdownSyncFrame=null,this.syncDropdownPanel(e)}))}clearDropdownAnchor(){this.notificationsOpen()||this.loginOpen()||this.userMenuOpen()||(this.dropdownTrigger=null,this.dropdownActionId=null,this.lastDropdownStyleKey="",this.dropdownPanelStyle.set({}))}findActionTrigger(e){const t=this.host.nativeElement.querySelectorAll(`[data-dga-action="${CSS.escape(e)}"]`);for(const o of Array.from(t)){const a=o;if(a.getClientRects().length>0)return a}return t[0]??null}activeUtilityPanelWidthPx(){if(typeof window>"u")return 448;const e=window.innerWidth-32;if(this.loginOpen()){const t=this.loginConfig()?.panelWidth??"24rem";return Math.min(ee(t,384),e)}return this.userMenuOpen()?Math.min(352,e):(this.notificationsOpen(),Math.min(448,e))}syncDropdownPanel(e){if(typeof window>"u")return;if(this.isMobileViewport()){const d={top:"auto",bottom:"max(0.75rem, env(safe-area-inset-bottom, 0px))",left:"0.75rem",right:"0.75rem",width:"auto",maxWidth:"none"},D=`sheet|${d.bottom}`;if(D===this.lastDropdownStyleKey)return;this.lastDropdownStyleKey=D,this.dropdownPanelStyle.set(d);return}const t=e??this.dropdownTrigger??(this.dropdownActionId?this.findActionTrigger(this.dropdownActionId):null);if(!t)return;this.dropdownTrigger=t;const o=t.getBoundingClientRect();if(o.width<1&&o.height<1)return;const a=getComputedStyle(this.host.nativeElement).direction,U=(typeof document<"u"?document.documentElement.getAttribute("dir"):null)==="rtl"||a==="rtl",_=8,N=this.activeUtilityPanelWidthPx(),f={top:`${Math.round(o.bottom+_)}px`};if(U){let d=Math.round(o.left);d=Math.max(16,Math.min(d,window.innerWidth-N-16)),f.left=`${d}px`,f.right="auto"}else{let d=Math.round(window.innerWidth-o.right);d=Math.max(16,Math.min(d,window.innerWidth-N-16)),f.right=`${d}px`,f.left="auto"}const C=`${f.top}|${f.left??""}|${f.right??""}`;C!==this.lastDropdownStyleKey&&(this.lastDropdownStyleKey=C,this.dropdownPanelStyle.set(f))}onKey(e){e.key==="Escape"&&this.closeAll()}onScroll(){(this.notificationsOpen()||this.loginOpen()||this.userMenuOpen())&&this.requestDropdownSync()}onResize(){typeof window>"u"||(window.matchMedia("(max-width: 767px)").matches||(this.mobileOpen.set(!1),this.setBodyScrollLocked(!1)),(this.notificationsOpen()||this.loginOpen()||this.userMenuOpen())&&(this.lastDropdownStyleKey="",this.requestDropdownSync()))}onNavLinkClick(e,t){this.navLinkClick.emit(e),e.href||t.preventDefault()}onDocClick(e){this.searchOpen()||this.notificationsOpen()||this.loginOpen()||this.userMenuOpen()||this.hoverMenus()&&!this.isMobileViewport()||this.mobileOpen()||this.host.nativeElement.contains(e.target)||this.openDropdown.set(null)}static ɵfac=i.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:i,type:v,deps:[],target:i.ɵɵFactoryTarget.Component});static ɵcmp=i.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"22.0.7",type:v,isStandalone:!0,selector:"dga-header",inputs:{brand:{classPropertyName:"brand",publicName:"brand",isSignal:!0,isRequired:!1,transformFunction:null},brandSlogan:{classPropertyName:"brandSlogan",publicName:"brandSlogan",isSignal:!0,isRequired:!1,transformFunction:null},brandLogo:{classPropertyName:"brandLogo",publicName:"brandLogo",isSignal:!0,isRequired:!1,transformFunction:null},brandLogoAlt:{classPropertyName:"brandLogoAlt",publicName:"brandLogoAlt",isSignal:!0,isRequired:!1,transformFunction:null},brandPlaceholder:{classPropertyName:"brandPlaceholder",publicName:"brandPlaceholder",isSignal:!0,isRequired:!1,transformFunction:null},brandHref:{classPropertyName:"brandHref",publicName:"brandHref",isSignal:!0,isRequired:!1,transformFunction:null},navLabel:{classPropertyName:"navLabel",publicName:"navLabel",isSignal:!0,isRequired:!1,transformFunction:null},menuToggleLabel:{classPropertyName:"menuToggleLabel",publicName:"menuToggleLabel",isSignal:!0,isRequired:!1,transformFunction:null},menuCloseLabel:{classPropertyName:"menuCloseLabel",publicName:"menuCloseLabel",isSignal:!0,isRequired:!1,transformFunction:null},appearance:{classPropertyName:"appearance",publicName:"appearance",isSignal:!0,isRequired:!1,transformFunction:null},mobileNav:{classPropertyName:"mobileNav",publicName:"mobileNav",isSignal:!0,isRequired:!1,transformFunction:null},sticky:{classPropertyName:"sticky",publicName:"sticky",isSignal:!0,isRequired:!1,transformFunction:null},items:{classPropertyName:"items",publicName:"items",isSignal:!0,isRequired:!1,transformFunction:null},actions:{classPropertyName:"actions",publicName:"actions",isSignal:!0,isRequired:!1,transformFunction:null},search:{classPropertyName:"search",publicName:"search",isSignal:!0,isRequired:!1,transformFunction:null},searchQuery:{classPropertyName:"searchQuery",publicName:"searchQuery",isSignal:!0,isRequired:!1,transformFunction:null},notifications:{classPropertyName:"notifications",publicName:"notifications",isSignal:!0,isRequired:!1,transformFunction:null},login:{classPropertyName:"login",publicName:"login",isSignal:!0,isRequired:!1,transformFunction:null},user:{classPropertyName:"user",publicName:"user",isSignal:!0,isRequired:!1,transformFunction:null},authenticated:{classPropertyName:"authenticated",publicName:"authenticated",isSignal:!0,isRequired:!1,transformFunction:null},loginSubmitting:{classPropertyName:"loginSubmitting",publicName:"loginSubmitting",isSignal:!0,isRequired:!1,transformFunction:null},loginError:{classPropertyName:"loginError",publicName:"loginError",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{searchQuery:"searchQueryChange",authenticated:"authenticatedChange",loginSubmitting:"loginSubmittingChange",loginError:"loginErrorChange",actionClick:"actionClick",searchSubmit:"searchSubmit",searchSuggestionSelect:"searchSuggestionSelect",searchVoice:"searchVoice",notificationAction:"notificationAction",loginSubmit:"loginSubmit",logout:"logout",userLinkClick:"userLinkClick",navLinkClick:"navLinkClick"},host:{attributes:{role:"banner"},listeners:{mouseleave:"onHostLeave($event)","document:dga-close-header-overlays":"onCloseHeaderOverlays()","document:keydown":"onKey($event)","window:scroll":"onScroll()","window:resize":"onResize()","document:click":"onDocClick($event)"},properties:{class:"hostClasses()","attr.data-appearance":"appearance()","attr.data-mobile-nav":"mobileNav()","attr.data-mobile-open":"mobileOpen() || null"}},queries:[{propertyName:"customLoginForm",first:!0,predicate:m,descendants:!0,isSignal:!0},{propertyName:"customLoginFooter",first:!0,predicate:p,descendants:!0,isSignal:!0}],viewQueries:[{propertyName:"searchInputRef",first:!0,predicate:["searchInput"],descendants:!0,isSignal:!0},{propertyName:"utilLayerRef",first:!0,predicate:["utilLayer"],descendants:!0,isSignal:!0}],ngImport:i,template:`
|
|
2
|
+
<div [class]="innerClasses()">
|
|
3
|
+
<div class="relative flex min-w-0 shrink-0 items-center self-center">
|
|
4
|
+
<ng-content select="[dgaHeaderBrand]" />
|
|
5
|
+
@if (brand() || brandLogo()) {
|
|
6
|
+
<a
|
|
7
|
+
class="inline-flex h-(--size-header-logo) cursor-pointer items-center gap-lg font-sans
|
|
8
|
+
focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2
|
|
9
|
+
focus-visible:outline-focus"
|
|
10
|
+
[href]="appHref(brandHref())"
|
|
11
|
+
>
|
|
12
|
+
@if (brandLogo()) {
|
|
13
|
+
<img
|
|
14
|
+
class="h-(--size-header-logo) w-auto max-w-[min(100%,14rem)] shrink-0 object-contain"
|
|
15
|
+
[src]="brandLogo()"
|
|
16
|
+
[alt]="brandLogoAlt()"
|
|
17
|
+
height="58"
|
|
18
|
+
/>
|
|
19
|
+
} @else if (appearance() === 'portal' && brandPlaceholder()) {
|
|
20
|
+
<span
|
|
21
|
+
class="inline-flex size-(--size-header-logo) shrink-0 items-center justify-center rounded-sm
|
|
22
|
+
bg-primary-faint text-fg-primary"
|
|
23
|
+
aria-hidden="true"
|
|
24
|
+
>
|
|
25
|
+
<dga-icon name="home" size="xl" tone="primary" />
|
|
26
|
+
</span>
|
|
27
|
+
}
|
|
28
|
+
@if (brand() && !brandLogo()) {
|
|
29
|
+
<span class="flex min-w-0 flex-col gap-xxs">
|
|
30
|
+
<span class="text-body-md font-bold text-display">{{ brand() }}</span>
|
|
31
|
+
@if (brandSlogan()) {
|
|
32
|
+
<span class="text-body-sm font-normal text-muted">{{ brandSlogan() }}</span>
|
|
33
|
+
}
|
|
34
|
+
</span>
|
|
35
|
+
}
|
|
36
|
+
</a>
|
|
37
|
+
}
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
@if (isPortal() && items().length) {
|
|
41
|
+
<button
|
|
42
|
+
type="button"
|
|
43
|
+
class="dga-burger relative z-30 ms-auto hidden h-full w-6xl shrink-0 cursor-pointer
|
|
44
|
+
items-center justify-center self-stretch rounded-md text-fg transition-colors
|
|
45
|
+
hover:bg-neutral-light max-md:inline-flex
|
|
46
|
+
focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2
|
|
47
|
+
focus-visible:outline-focus"
|
|
48
|
+
[class.dga-burger--open]="mobileOpen()"
|
|
49
|
+
[class.dga-burger--hidden]="mobileOpen() && mobileNav() !== 'push'"
|
|
50
|
+
[attr.aria-expanded]="mobileOpen()"
|
|
51
|
+
[attr.aria-controls]="collapseId"
|
|
52
|
+
[attr.aria-label]="mobileOpen() ? menuCloseLabel() : menuToggleLabel()"
|
|
53
|
+
(click)="toggleMobile()"
|
|
54
|
+
>
|
|
55
|
+
<span class="dga-burger__box" aria-hidden="true">
|
|
56
|
+
<span class="dga-burger__line"></span>
|
|
57
|
+
<span class="dga-burger__line"></span>
|
|
58
|
+
<span class="dga-burger__line"></span>
|
|
59
|
+
</span>
|
|
60
|
+
</button>
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
<!-- Desktop navigation -->
|
|
64
|
+
<nav
|
|
65
|
+
[class]="desktopNavClasses()"
|
|
66
|
+
[attr.aria-label]="navLabel()"
|
|
67
|
+
[attr.hidden]="null"
|
|
68
|
+
>
|
|
69
|
+
@if (items().length) {
|
|
70
|
+
<ul
|
|
71
|
+
class="m-0 flex list-none flex-row flex-nowrap items-stretch gap-none p-0"
|
|
72
|
+
[class.overflow-x-auto]="openDropdown() === null"
|
|
73
|
+
[class.overflow-visible]="openDropdown() !== null"
|
|
74
|
+
role="list"
|
|
75
|
+
>
|
|
76
|
+
@for (item of items(); track item.label; let i = $index) {
|
|
77
|
+
<li
|
|
78
|
+
class="relative"
|
|
79
|
+
[class.z-dropdown]="openDropdown() === i"
|
|
80
|
+
[attr.data-open]="openDropdown() === i || null"
|
|
81
|
+
[attr.data-variant]="item.dropdown ? resolveVariant(item) : null"
|
|
82
|
+
(mouseenter)="onItemEnter(i)"
|
|
83
|
+
(focusin)="onItemEnter(i)"
|
|
84
|
+
>
|
|
85
|
+
@if (item.dropdown) {
|
|
86
|
+
<button
|
|
87
|
+
type="button"
|
|
88
|
+
[class]="navItemClass(!!item.current, openDropdown() === i)"
|
|
89
|
+
[attr.aria-expanded]="openDropdown() === i"
|
|
90
|
+
[attr.aria-haspopup]="'true'"
|
|
91
|
+
(click)="toggleDropdown(i, $event)"
|
|
92
|
+
>
|
|
93
|
+
<span
|
|
94
|
+
aria-hidden="true"
|
|
95
|
+
[class]="indicatorClass(!!item.current || openDropdown() === i)"
|
|
96
|
+
></span>
|
|
97
|
+
<span class="whitespace-nowrap">{{ item.label }}</span>
|
|
98
|
+
<dga-icon
|
|
99
|
+
name="chevronDown"
|
|
100
|
+
size="md"
|
|
101
|
+
[class]="
|
|
102
|
+
openDropdown() === i
|
|
103
|
+
? 'rotate-180 transition-transform duration-200'
|
|
104
|
+
: 'transition-transform duration-200'
|
|
105
|
+
"
|
|
106
|
+
/>
|
|
107
|
+
</button>
|
|
108
|
+
|
|
109
|
+
@if (openDropdown() === i && resolveVariant(item) === 'menu') {
|
|
110
|
+
<div
|
|
111
|
+
class="absolute start-0 top-full z-dropdown min-w-[16rem]
|
|
112
|
+
max-w-[min(100vw-2rem,20rem)]"
|
|
113
|
+
role="menu"
|
|
114
|
+
[attr.aria-label]="item.label"
|
|
115
|
+
>
|
|
116
|
+
<div class="h-xs" aria-hidden="true"></div>
|
|
117
|
+
<div
|
|
118
|
+
class="dga-panel-enter rounded-md border border-border bg-card p-sm
|
|
119
|
+
shadow-lg"
|
|
120
|
+
>
|
|
121
|
+
@if (item.dropdown.columns?.length) {
|
|
122
|
+
<div class="flex flex-col gap-lg p-md">
|
|
123
|
+
@for (col of item.dropdown.columns!; track col.title ?? $index) {
|
|
124
|
+
<div class="flex flex-col gap-xs">
|
|
125
|
+
@if (col.title) {
|
|
126
|
+
<p class="px-xl text-body-sm font-medium text-fg-primary">
|
|
127
|
+
{{ col.title }}
|
|
128
|
+
</p>
|
|
129
|
+
}
|
|
130
|
+
<ul class="m-0 flex list-none flex-col gap-none p-0" role="list">
|
|
131
|
+
@for (link of col.links; track link.label) {
|
|
132
|
+
<li role="none">
|
|
133
|
+
<a
|
|
134
|
+
role="menuitem"
|
|
135
|
+
[class]="dropLink"
|
|
136
|
+
[href]="appHref(link.href || '#')"
|
|
137
|
+
(click)="onNavLinkClick(link, $event)"
|
|
138
|
+
>{{ link.label }}</a
|
|
139
|
+
>
|
|
140
|
+
</li>
|
|
141
|
+
}
|
|
142
|
+
</ul>
|
|
143
|
+
</div>
|
|
144
|
+
}
|
|
145
|
+
</div>
|
|
146
|
+
} @else {
|
|
147
|
+
<ul class="m-0 flex list-none flex-col gap-none p-0" role="list">
|
|
148
|
+
@for (link of item.dropdown.links || []; track link.label) {
|
|
149
|
+
<li role="none">
|
|
150
|
+
<a
|
|
151
|
+
role="menuitem"
|
|
152
|
+
[class]="dropLink"
|
|
153
|
+
[href]="appHref(link.href || '#')"
|
|
154
|
+
(click)="onNavLinkClick(link, $event)"
|
|
155
|
+
>{{ link.label }}</a
|
|
156
|
+
>
|
|
157
|
+
</li>
|
|
158
|
+
}
|
|
159
|
+
</ul>
|
|
160
|
+
}
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
}
|
|
164
|
+
} @else {
|
|
165
|
+
<a
|
|
166
|
+
[class]="navItemClass(!!item.current)"
|
|
167
|
+
[attr.aria-current]="item.current ? 'page' : null"
|
|
168
|
+
[href]="appHref(item.href || '#')"
|
|
169
|
+
(click)="onNavLinkClick(item, $event)"
|
|
170
|
+
>
|
|
171
|
+
<span aria-hidden="true" [class]="indicatorClass(!!item.current)"></span>
|
|
172
|
+
<span class="whitespace-nowrap">{{ item.label }}</span>
|
|
173
|
+
</a>
|
|
174
|
+
}
|
|
175
|
+
</li>
|
|
176
|
+
}
|
|
177
|
+
</ul>
|
|
178
|
+
}
|
|
179
|
+
<div class="contents">
|
|
180
|
+
<ng-content />
|
|
181
|
+
</div>
|
|
182
|
+
</nav>
|
|
183
|
+
|
|
184
|
+
<div [class]="actionsClasses()">
|
|
185
|
+
@for (action of actions(); track action.id) {
|
|
186
|
+
<dga-tooltip
|
|
187
|
+
class="relative flex h-full"
|
|
188
|
+
[text]="actionTooltip(action)"
|
|
189
|
+
placement="bottom"
|
|
190
|
+
[showIcon]="false"
|
|
191
|
+
[disabled]="!isIconOnly(action) && !(isLoginAction(action) && authenticated())"
|
|
192
|
+
>
|
|
193
|
+
@if (action.href) {
|
|
194
|
+
<a
|
|
195
|
+
[class]="actionClass(action)"
|
|
196
|
+
[href]="appHref(action.href)"
|
|
197
|
+
[attr.aria-label]="actionAriaLabel(action)"
|
|
198
|
+
[attr.data-dga-action]="action.id"
|
|
199
|
+
>
|
|
200
|
+
<span aria-hidden="true" [class]="indicatorClass(false)"></span>
|
|
201
|
+
@if (action.icon) {
|
|
202
|
+
<dga-icon [name]="action.icon" size="xl" />
|
|
203
|
+
}
|
|
204
|
+
@if (!isIconOnly(action)) {
|
|
205
|
+
<span>{{ action.label }}</span>
|
|
206
|
+
}
|
|
207
|
+
@if (action.badge) {
|
|
208
|
+
<span [class]="badgeClass()">{{ action.badge }}</span>
|
|
209
|
+
}
|
|
210
|
+
</a>
|
|
211
|
+
} @else {
|
|
212
|
+
<button
|
|
213
|
+
type="button"
|
|
214
|
+
[class]="actionClass(action)"
|
|
215
|
+
[attr.aria-label]="actionAriaLabel(action)"
|
|
216
|
+
[attr.aria-expanded]="actionExpanded(action)"
|
|
217
|
+
[attr.aria-controls]="actionControls(action)"
|
|
218
|
+
[attr.data-dga-action]="action.id"
|
|
219
|
+
(click)="onAction(action, $event)"
|
|
220
|
+
>
|
|
221
|
+
<span
|
|
222
|
+
aria-hidden="true"
|
|
223
|
+
[class]="indicatorClass(actionIndicatorActive(action))"
|
|
224
|
+
></span>
|
|
225
|
+
@if (isLoginAction(action) && authenticated() && userConfig(); as u) {
|
|
226
|
+
<dga-avatar [name]="u.name" [src]="u.avatarSrc" size="sm" />
|
|
227
|
+
<span class="hidden max-w-11xl truncate lg:inline">{{ u.name }}</span>
|
|
228
|
+
} @else {
|
|
229
|
+
@if (action.icon) {
|
|
230
|
+
<dga-icon [name]="action.icon" size="xl" />
|
|
231
|
+
}
|
|
232
|
+
@if (!isIconOnly(action)) {
|
|
233
|
+
<span>{{ action.label }}</span>
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
@if (action.badge) {
|
|
237
|
+
<span [class]="badgeClass()">{{ action.badge }}</span>
|
|
238
|
+
}
|
|
239
|
+
</button>
|
|
240
|
+
}
|
|
241
|
+
</dga-tooltip>
|
|
242
|
+
}
|
|
243
|
+
<ng-content select="[dgaHeaderEnd]" />
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
|
|
247
|
+
<!-- Desktop mega / featured -->
|
|
248
|
+
@if (activeWideDropdown(); as drop) {
|
|
249
|
+
<div
|
|
250
|
+
class="absolute start-0 end-0 top-full z-dropdown hidden w-full md:block"
|
|
251
|
+
role="region"
|
|
252
|
+
[attr.aria-label]="drop.item.label"
|
|
253
|
+
[attr.data-variant]="drop.variant"
|
|
254
|
+
(mouseenter)="onPanelEnter()"
|
|
255
|
+
>
|
|
256
|
+
<div
|
|
257
|
+
class="dga-panel-enter border-b border-border bg-card shadow-lg md:rounded-b-lg"
|
|
258
|
+
>
|
|
259
|
+
<div class="w-full px-(--wrapper-padding) py-2xl lg:py-3xl">
|
|
260
|
+
<div [class]="featuredGridClass(drop.variant, !!drop.item.dropdown!.featured)">
|
|
261
|
+
<div class="min-w-0">
|
|
262
|
+
@switch (resolveLayout(drop.item)) {
|
|
263
|
+
@case ('columns') {
|
|
264
|
+
<div [class]="columnsGridClass(colCount(drop.item))">
|
|
265
|
+
@for (
|
|
266
|
+
col of drop.item.dropdown!.columns!;
|
|
267
|
+
track col.title ?? $index
|
|
268
|
+
) {
|
|
269
|
+
<div class="flex min-w-0 flex-col gap-md">
|
|
270
|
+
@if (col.title) {
|
|
271
|
+
<p
|
|
272
|
+
class="border-b border-border-subtle pb-sm text-body-lg
|
|
273
|
+
font-medium text-fg-primary"
|
|
274
|
+
>
|
|
275
|
+
{{ col.title }}
|
|
276
|
+
</p>
|
|
277
|
+
}
|
|
278
|
+
<ul class="m-0 flex list-none flex-col gap-none p-0" role="list">
|
|
279
|
+
@for (link of col.links; track link.label) {
|
|
280
|
+
<li>
|
|
281
|
+
<a
|
|
282
|
+
[class]="dropLink"
|
|
283
|
+
[href]="appHref(link.href || '#')"
|
|
284
|
+
(click)="onNavLinkClick(link, $event)"
|
|
285
|
+
>
|
|
286
|
+
<span>{{ link.label }}</span>
|
|
287
|
+
@if (link.description) {
|
|
288
|
+
<span class="text-body-sm text-muted">{{
|
|
289
|
+
link.description
|
|
290
|
+
}}</span>
|
|
291
|
+
}
|
|
292
|
+
</a>
|
|
293
|
+
</li>
|
|
294
|
+
}
|
|
295
|
+
</ul>
|
|
296
|
+
</div>
|
|
297
|
+
}
|
|
298
|
+
</div>
|
|
299
|
+
}
|
|
300
|
+
@case ('rows') {
|
|
301
|
+
<ul
|
|
302
|
+
class="m-0 grid w-full list-none grid-cols-1 gap-md p-0
|
|
303
|
+
sm:grid-cols-2 lg:grid-cols-4"
|
|
304
|
+
role="list"
|
|
305
|
+
>
|
|
306
|
+
@for (link of drop.item.dropdown!.links || []; track link.label) {
|
|
307
|
+
<li class="min-w-0">
|
|
308
|
+
<a
|
|
309
|
+
[class]="dropTile"
|
|
310
|
+
[href]="appHref(link.href || '#')"
|
|
311
|
+
(click)="onNavLinkClick(link, $event)"
|
|
312
|
+
>
|
|
313
|
+
<span class="text-body-md font-medium text-fg">{{
|
|
314
|
+
link.label
|
|
315
|
+
}}</span>
|
|
316
|
+
@if (link.description) {
|
|
317
|
+
<span class="text-body-sm text-muted">{{
|
|
318
|
+
link.description
|
|
319
|
+
}}</span>
|
|
320
|
+
}
|
|
321
|
+
</a>
|
|
322
|
+
</li>
|
|
323
|
+
}
|
|
324
|
+
</ul>
|
|
325
|
+
}
|
|
326
|
+
@default {
|
|
327
|
+
<ul
|
|
328
|
+
class="m-0 grid w-full max-w-(--container-5xl) list-none grid-cols-1 gap-xs
|
|
329
|
+
p-0 sm:grid-cols-2 lg:grid-cols-3"
|
|
330
|
+
role="list"
|
|
331
|
+
>
|
|
332
|
+
@for (link of flatLinks(drop.item); track link.label) {
|
|
333
|
+
<li class="min-w-0">
|
|
334
|
+
<a
|
|
335
|
+
[class]="dropLink"
|
|
336
|
+
[href]="appHref(link.href || '#')"
|
|
337
|
+
(click)="onNavLinkClick(link, $event)"
|
|
338
|
+
>
|
|
339
|
+
<span>{{ link.label }}</span>
|
|
340
|
+
@if (link.description) {
|
|
341
|
+
<span class="text-body-sm text-muted">{{
|
|
342
|
+
link.description
|
|
343
|
+
}}</span>
|
|
344
|
+
}
|
|
345
|
+
</a>
|
|
346
|
+
</li>
|
|
347
|
+
}
|
|
348
|
+
</ul>
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
</div>
|
|
352
|
+
|
|
353
|
+
@if (drop.variant === 'featured' && drop.item.dropdown!.featured; as feat) {
|
|
354
|
+
<aside
|
|
355
|
+
class="flex min-w-0 flex-col gap-lg overflow-hidden rounded-md
|
|
356
|
+
border border-border bg-primary-faint p-2xl lg:self-start"
|
|
357
|
+
>
|
|
358
|
+
@if (feat.imageUrl) {
|
|
359
|
+
<img
|
|
360
|
+
class="aspect-[16/10] h-auto w-full rounded-sm object-cover"
|
|
361
|
+
[src]="feat.imageUrl"
|
|
362
|
+
alt=""
|
|
363
|
+
/>
|
|
364
|
+
}
|
|
365
|
+
<div class="flex min-w-0 flex-col gap-md">
|
|
366
|
+
<p class="text-body-lg font-semibold text-display">{{ feat.title }}</p>
|
|
367
|
+
@if (feat.description) {
|
|
368
|
+
<p class="text-body-sm leading-relaxed text-paragraph">
|
|
369
|
+
{{ feat.description }}
|
|
370
|
+
</p>
|
|
371
|
+
}
|
|
372
|
+
@if (feat.cta) {
|
|
373
|
+
<a
|
|
374
|
+
class="mt-xs inline-flex h-5xl cursor-pointer items-center justify-center gap-sm
|
|
375
|
+
rounded-sm bg-primary px-xl text-body-md font-medium text-on-color
|
|
376
|
+
transition-opacity hover:opacity-90
|
|
377
|
+
focus-visible:outline focus-visible:outline-2
|
|
378
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
379
|
+
[href]="appHref(feat.href || '#')"
|
|
380
|
+
>
|
|
381
|
+
<span>{{ feat.cta }}</span>
|
|
382
|
+
<dga-icon name="chevronLeft" size="sm" />
|
|
383
|
+
</a>
|
|
384
|
+
}
|
|
385
|
+
</div>
|
|
386
|
+
</aside>
|
|
387
|
+
}
|
|
388
|
+
</div>
|
|
389
|
+
</div>
|
|
390
|
+
</div>
|
|
391
|
+
</div>
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
<!-- Header search popup (dga-modal) -->
|
|
395
|
+
@if (searchConfig(); as cfg) {
|
|
396
|
+
<dga-modal
|
|
397
|
+
class="dga-header-search-modal"
|
|
398
|
+
[id]="searchPanelId"
|
|
399
|
+
[open]="searchOpen()"
|
|
400
|
+
(openChange)="onSearchModalOpenChange($event)"
|
|
401
|
+
[title]="cfg.title || cfg.submitLabel || 'Search'"
|
|
402
|
+
[description]="cfg.description || ''"
|
|
403
|
+
[closeLabel]="cfg.closeLabel || 'Close'"
|
|
404
|
+
size="lg"
|
|
405
|
+
animation="scale"
|
|
406
|
+
[scrollable]="false"
|
|
407
|
+
(opened)="focusSearchInput()"
|
|
408
|
+
>
|
|
409
|
+
<form
|
|
410
|
+
class="flex flex-col gap-xl"
|
|
411
|
+
role="search"
|
|
412
|
+
[attr.aria-label]="cfg.submitLabel || 'Search'"
|
|
413
|
+
(submit)="onSearchFormSubmit($event)"
|
|
414
|
+
>
|
|
415
|
+
<div class="flex w-full flex-col gap-md sm:flex-row sm:items-stretch sm:gap-lg">
|
|
416
|
+
<div class="min-w-0 flex-1">
|
|
417
|
+
<dga-form-control size="lg" startIcon="search" [filled]="!!searchQuery()">
|
|
418
|
+
<input
|
|
419
|
+
#searchInput
|
|
420
|
+
type="search"
|
|
421
|
+
name="q"
|
|
422
|
+
class="dga-search-input placeholder:text-muted"
|
|
423
|
+
[placeholder]="cfg.placeholder || 'Search...'"
|
|
424
|
+
[attr.aria-label]="cfg.placeholder || 'Search...'"
|
|
425
|
+
[value]="searchQuery()"
|
|
426
|
+
(input)="searchQuery.set($any($event.target).value)"
|
|
427
|
+
/>
|
|
428
|
+
@if (searchQuery()) {
|
|
429
|
+
<button
|
|
430
|
+
type="button"
|
|
431
|
+
dgaEnd
|
|
432
|
+
[attr.aria-label]="cfg.clearLabel || 'Clear search'"
|
|
433
|
+
(click)="clearSearchQuery()"
|
|
434
|
+
>
|
|
435
|
+
<dga-icon name="close" size="sm" />
|
|
436
|
+
</button>
|
|
437
|
+
}
|
|
438
|
+
@if (cfg.voice !== false) {
|
|
439
|
+
<button
|
|
440
|
+
type="button"
|
|
441
|
+
dgaEnd
|
|
442
|
+
class="dga-search-voice"
|
|
443
|
+
[class.dga-search-voice--active]="voiceListening()"
|
|
444
|
+
[attr.aria-label]="cfg.voiceLabel || 'Voice input'"
|
|
445
|
+
[attr.aria-pressed]="voiceListening()"
|
|
446
|
+
(click)="onSearchVoice()"
|
|
447
|
+
>
|
|
448
|
+
<dga-icon
|
|
449
|
+
name="mic"
|
|
450
|
+
size="sm"
|
|
451
|
+
[tone]="voiceListening() ? 'current' : 'muted'"
|
|
452
|
+
/>
|
|
453
|
+
</button>
|
|
454
|
+
}
|
|
455
|
+
</dga-form-control>
|
|
456
|
+
</div>
|
|
457
|
+
<button
|
|
458
|
+
type="submit"
|
|
459
|
+
class="inline-flex min-h-6xl shrink-0 cursor-pointer items-center justify-center gap-sm
|
|
460
|
+
rounded-md bg-primary px-xl text-body-md font-medium text-on-color shadow-sm
|
|
461
|
+
transition-opacity hover:opacity-90
|
|
462
|
+
focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2
|
|
463
|
+
focus-visible:outline-focus sm:px-2xl"
|
|
464
|
+
>
|
|
465
|
+
<dga-icon name="search" size="md" />
|
|
466
|
+
<span>{{ cfg.submitLabel || 'Search' }}</span>
|
|
467
|
+
</button>
|
|
468
|
+
</div>
|
|
469
|
+
|
|
470
|
+
@if (cfg.suggestions?.length) {
|
|
471
|
+
<div class="flex flex-col gap-md">
|
|
472
|
+
<span class="text-body-sm font-semibold text-display">
|
|
473
|
+
{{ cfg.suggestionsLabel || 'Suggestions:' }}
|
|
474
|
+
</span>
|
|
475
|
+
<div class="flex flex-wrap gap-sm">
|
|
476
|
+
@for (item of cfg.suggestions!; track item.value ?? item.label; let i = $index) {
|
|
477
|
+
<button
|
|
478
|
+
type="button"
|
|
479
|
+
class="dga-search-chip inline-flex h-4xl cursor-pointer items-center gap-xs
|
|
480
|
+
rounded-full border border-border bg-neutral-light px-lg text-body-sm
|
|
481
|
+
text-paragraph transition-[background-color,transform,border-color]
|
|
482
|
+
duration-150 ease-out hover:-translate-y-px hover:border-primary
|
|
483
|
+
hover:bg-sunken
|
|
484
|
+
focus-visible:outline focus-visible:outline-2
|
|
485
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
486
|
+
[style.animation-delay]="i * 40 + 'ms'"
|
|
487
|
+
(click)="applySearchSuggestion(item)"
|
|
488
|
+
>
|
|
489
|
+
<dga-icon [name]="item.icon || 'plus'" size="xs" />
|
|
490
|
+
<span>{{ item.label }}</span>
|
|
491
|
+
</button>
|
|
492
|
+
}
|
|
493
|
+
</div>
|
|
494
|
+
</div>
|
|
495
|
+
}
|
|
496
|
+
</form>
|
|
497
|
+
</dga-modal>
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
<!--
|
|
501
|
+
Utility overlays (notifications / login / user): portaled to body at z-urgent
|
|
502
|
+
so sticky announcement + chatbot/a11y FABs stay underneath.
|
|
503
|
+
-->
|
|
504
|
+
@if (utilityOverlayOpen()) {
|
|
505
|
+
<div #utilLayer class="dga-header-util-layer">
|
|
506
|
+
<button
|
|
507
|
+
type="button"
|
|
508
|
+
class="dga-util-backdrop absolute inset-0 cursor-default bg-overlay/50"
|
|
509
|
+
tabindex="-1"
|
|
510
|
+
aria-label="Close"
|
|
511
|
+
(click)="closeUtilityOverlays()"
|
|
512
|
+
></button>
|
|
513
|
+
|
|
514
|
+
<!-- Header notifications panel -->
|
|
515
|
+
@if (notificationsOpen() && notificationsConfig(); as ncfg) {
|
|
516
|
+
<div
|
|
517
|
+
[id]="notificationsPanelId"
|
|
518
|
+
class="dga-header-util-panel fixed w-[min(28rem,calc(100vw-2rem))] max-md:inset-x-3
|
|
519
|
+
max-md:bottom-3 max-md:top-auto max-md:w-auto"
|
|
520
|
+
role="region"
|
|
521
|
+
[attr.aria-label]="ncfg.title || ncfg.viewAllLabel || 'Notifications'"
|
|
522
|
+
[style]="dropdownPanelStyle()"
|
|
523
|
+
>
|
|
524
|
+
<div
|
|
525
|
+
class="dga-panel-enter dga-panel-enter--anchor-end flex max-h-[min(85svh,40rem)]
|
|
526
|
+
flex-col overflow-hidden rounded-2xl border border-border bg-card shadow-xl
|
|
527
|
+
md:max-h-[none] md:rounded-md"
|
|
528
|
+
>
|
|
529
|
+
<div
|
|
530
|
+
class="flex shrink-0 flex-col gap-sm border-b border-border-subtle px-xl py-md
|
|
531
|
+
md:flex-row md:items-center md:justify-between md:gap-md"
|
|
532
|
+
>
|
|
533
|
+
<div class="flex min-w-0 items-center justify-between gap-sm md:justify-start">
|
|
534
|
+
<div class="flex min-w-0 items-center gap-sm">
|
|
535
|
+
<h2 class="m-0 truncate text-body-lg font-semibold text-display md:text-body-md">
|
|
536
|
+
{{ ncfg.title || 'Notifications' }}
|
|
537
|
+
</h2>
|
|
538
|
+
@if (unreadNotificationCount() > 0) {
|
|
539
|
+
<span
|
|
540
|
+
class="inline-flex min-w-4xl items-center justify-center rounded-full
|
|
541
|
+
bg-error px-sm py-xxs text-body-2xs font-semibold text-on-color"
|
|
542
|
+
>
|
|
543
|
+
{{ unreadNotificationCount() }}
|
|
544
|
+
</span>
|
|
545
|
+
}
|
|
546
|
+
</div>
|
|
547
|
+
<button
|
|
548
|
+
type="button"
|
|
549
|
+
class="inline-flex size-5xl shrink-0 cursor-pointer items-center justify-center
|
|
550
|
+
rounded-sm text-muted transition-colors hover:bg-neutral-light hover:text-fg
|
|
551
|
+
focus-visible:outline focus-visible:outline-2
|
|
552
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus md:hidden"
|
|
553
|
+
[attr.aria-label]="ncfg.closeLabel || 'Close'"
|
|
554
|
+
(click)="closeNotifications()"
|
|
555
|
+
>
|
|
556
|
+
<dga-icon name="close" size="md" />
|
|
557
|
+
</button>
|
|
558
|
+
</div>
|
|
559
|
+
<div class="flex shrink-0 items-center gap-xxs max-md:justify-stretch">
|
|
560
|
+
@if (unreadNotificationCount() > 0) {
|
|
561
|
+
<button
|
|
562
|
+
type="button"
|
|
563
|
+
class="inline-flex h-4xl flex-1 cursor-pointer items-center justify-center
|
|
564
|
+
rounded-sm px-md text-body-sm font-medium text-fg-primary
|
|
565
|
+
transition-colors hover:bg-primary-faint
|
|
566
|
+
focus-visible:outline focus-visible:outline-2
|
|
567
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus
|
|
568
|
+
md:flex-none"
|
|
569
|
+
(click)="markAllNotificationsRead()"
|
|
570
|
+
>
|
|
571
|
+
{{ ncfg.markAllReadLabel || 'Mark all as read' }}
|
|
572
|
+
</button>
|
|
573
|
+
}
|
|
574
|
+
<button
|
|
575
|
+
type="button"
|
|
576
|
+
class="hidden size-5xl cursor-pointer items-center justify-center rounded-sm
|
|
577
|
+
text-muted transition-colors hover:bg-neutral-light hover:text-fg
|
|
578
|
+
focus-visible:outline focus-visible:outline-2
|
|
579
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus md:inline-flex"
|
|
580
|
+
[attr.aria-label]="ncfg.closeLabel || 'Close'"
|
|
581
|
+
(click)="closeNotifications()"
|
|
582
|
+
>
|
|
583
|
+
<dga-icon name="close" size="md" />
|
|
584
|
+
</button>
|
|
585
|
+
</div>
|
|
586
|
+
</div>
|
|
587
|
+
|
|
588
|
+
<div class="min-h-0 flex-1 overflow-y-auto overscroll-contain md:max-h-[min(48svh,28rem)]">
|
|
589
|
+
@if (visibleNotifications().length === 0) {
|
|
590
|
+
<div class="flex flex-col items-center gap-md px-xl py-3xl text-center">
|
|
591
|
+
<span
|
|
592
|
+
class="inline-flex size-6xl items-center justify-center rounded-full
|
|
593
|
+
bg-neutral-light text-muted"
|
|
594
|
+
aria-hidden="true"
|
|
595
|
+
>
|
|
596
|
+
<dga-icon name="bell" size="xl" tone="muted" />
|
|
597
|
+
</span>
|
|
598
|
+
<p class="m-0 text-body-sm text-muted">
|
|
599
|
+
{{ ncfg.emptyLabel || 'No notifications' }}
|
|
600
|
+
</p>
|
|
601
|
+
</div>
|
|
602
|
+
} @else {
|
|
603
|
+
<ul class="m-0 flex list-none flex-col p-0" role="list">
|
|
604
|
+
@for (item of visibleNotifications(); track item.id) {
|
|
605
|
+
<li
|
|
606
|
+
class="border-b border-border-subtle last:border-b-0"
|
|
607
|
+
[class]="item.read ? 'bg-surface' : 'bg-card'"
|
|
608
|
+
>
|
|
609
|
+
<button
|
|
610
|
+
type="button"
|
|
611
|
+
class="flex w-full cursor-pointer items-start gap-lg px-xl py-lg text-start
|
|
612
|
+
transition-colors hover:bg-neutral-light
|
|
613
|
+
focus-visible:outline focus-visible:outline-2
|
|
614
|
+
focus-visible:outline-offset-[-2px] focus-visible:outline-focus"
|
|
615
|
+
[attr.aria-expanded]="expandedNotificationId() === item.id"
|
|
616
|
+
(click)="toggleNotificationExpand(item)"
|
|
617
|
+
>
|
|
618
|
+
<span class="relative mt-xxs shrink-0">
|
|
619
|
+
<dga-icon-badge size="sm">
|
|
620
|
+
<dga-icon [name]="item.icon || 'bell'" size="sm" />
|
|
621
|
+
</dga-icon-badge>
|
|
622
|
+
@if (!item.read) {
|
|
623
|
+
<span
|
|
624
|
+
class="absolute -end-xxs -top-xxs size-[0.5rem] rounded-full bg-primary
|
|
625
|
+
ring-2 ring-white"
|
|
626
|
+
aria-hidden="true"
|
|
627
|
+
></span>
|
|
628
|
+
}
|
|
629
|
+
</span>
|
|
630
|
+
<span class="min-w-0 flex-1">
|
|
631
|
+
<span class="mb-xs flex flex-wrap items-center gap-sm">
|
|
632
|
+
@if (item.statusLabel) {
|
|
633
|
+
<dga-badge [variant]="item.tone || 'neutral'" size="sm">
|
|
634
|
+
{{ item.statusLabel }}
|
|
635
|
+
</dga-badge>
|
|
636
|
+
}
|
|
637
|
+
<span
|
|
638
|
+
class="min-w-0 truncate text-body-md text-display"
|
|
639
|
+
[class.font-semibold]="!item.read"
|
|
640
|
+
[class.font-medium]="item.read"
|
|
641
|
+
[class.text-muted]="item.read"
|
|
642
|
+
>
|
|
643
|
+
{{ item.title }}
|
|
644
|
+
</span>
|
|
645
|
+
</span>
|
|
646
|
+
<span
|
|
647
|
+
class="text-body-sm text-paragraph"
|
|
648
|
+
[class.line-clamp-2]="expandedNotificationId() !== item.id"
|
|
649
|
+
>
|
|
650
|
+
{{ item.message }}
|
|
651
|
+
</span>
|
|
652
|
+
</span>
|
|
653
|
+
<dga-icon
|
|
654
|
+
class="mt-xs shrink-0 text-muted transition-transform duration-200"
|
|
655
|
+
[class.rotate-180]="expandedNotificationId() === item.id"
|
|
656
|
+
name="chevronDown"
|
|
657
|
+
size="sm"
|
|
658
|
+
/>
|
|
659
|
+
</button>
|
|
660
|
+
|
|
661
|
+
@if (expandedNotificationId() === item.id) {
|
|
662
|
+
<div
|
|
663
|
+
class="dga-notif-actions flex flex-wrap gap-sm border-t border-border-subtle
|
|
664
|
+
bg-surface px-xl py-md"
|
|
665
|
+
>
|
|
666
|
+
@if (!item.read) {
|
|
667
|
+
<button
|
|
668
|
+
type="button"
|
|
669
|
+
class="inline-flex h-4xl cursor-pointer items-center gap-xs rounded-sm
|
|
670
|
+
px-md text-body-sm text-fg transition-colors hover:bg-neutral-light
|
|
671
|
+
focus-visible:outline focus-visible:outline-2
|
|
672
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
673
|
+
(click)="onNotificationAction(item, 'read'); $event.stopPropagation()"
|
|
674
|
+
>
|
|
675
|
+
<dga-icon name="success" size="sm" />
|
|
676
|
+
<span>{{ ncfg.markReadLabel || 'Mark as read' }}</span>
|
|
677
|
+
</button>
|
|
678
|
+
}
|
|
679
|
+
<button
|
|
680
|
+
type="button"
|
|
681
|
+
class="inline-flex h-4xl cursor-pointer items-center gap-xs rounded-sm
|
|
682
|
+
px-md text-body-sm text-fg transition-colors hover:bg-neutral-light
|
|
683
|
+
focus-visible:outline focus-visible:outline-2
|
|
684
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
685
|
+
(click)="onNotificationAction(item, 'view'); $event.stopPropagation()"
|
|
686
|
+
>
|
|
687
|
+
<dga-icon name="eye" size="sm" />
|
|
688
|
+
<span>{{ ncfg.viewLabel || 'View' }}</span>
|
|
689
|
+
</button>
|
|
690
|
+
<button
|
|
691
|
+
type="button"
|
|
692
|
+
class="inline-flex h-4xl cursor-pointer items-center gap-xs rounded-sm
|
|
693
|
+
px-md text-body-sm text-fg-error transition-colors hover:bg-error-light
|
|
694
|
+
focus-visible:outline focus-visible:outline-2
|
|
695
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
696
|
+
(click)="onNotificationAction(item, 'dismiss'); $event.stopPropagation()"
|
|
697
|
+
>
|
|
698
|
+
<dga-icon name="close" size="sm" />
|
|
699
|
+
<span>{{ ncfg.dismissLabel || 'Dismiss' }}</span>
|
|
700
|
+
</button>
|
|
701
|
+
</div>
|
|
702
|
+
}
|
|
703
|
+
</li>
|
|
704
|
+
}
|
|
705
|
+
</ul>
|
|
706
|
+
}
|
|
707
|
+
</div>
|
|
708
|
+
|
|
709
|
+
@if (ncfg.viewAllHref || ncfg.viewAllLabel) {
|
|
710
|
+
<div
|
|
711
|
+
class="shrink-0 border-t border-border
|
|
712
|
+
pb-[max(0px,env(safe-area-inset-bottom))] md:pb-0"
|
|
713
|
+
>
|
|
714
|
+
<a
|
|
715
|
+
class="inline-flex w-full cursor-pointer items-center justify-center gap-sm
|
|
716
|
+
px-xl py-lg text-body-sm font-medium text-fg-primary
|
|
717
|
+
transition-colors hover:bg-neutral-light
|
|
718
|
+
focus-visible:outline focus-visible:outline-2
|
|
719
|
+
focus-visible:outline-offset-[-2px] focus-visible:outline-focus"
|
|
720
|
+
[href]="appHref(ncfg.viewAllHref || '#')"
|
|
721
|
+
(click)="closeNotifications()"
|
|
722
|
+
>
|
|
723
|
+
<span>{{ ncfg.viewAllLabel || 'View all notifications' }}</span>
|
|
724
|
+
<dga-icon name="chevronLeft" size="sm" />
|
|
725
|
+
</a>
|
|
726
|
+
</div>
|
|
727
|
+
}
|
|
728
|
+
</div>
|
|
729
|
+
</div>
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
<!-- Header login panel (guest) -->
|
|
733
|
+
@if (loginOpen() && loginConfig(); as lcfg) {
|
|
734
|
+
<div
|
|
735
|
+
[id]="loginPanelId"
|
|
736
|
+
class="dga-header-util-panel fixed max-md:inset-x-3 max-md:bottom-3 max-md:top-auto
|
|
737
|
+
max-md:w-auto"
|
|
738
|
+
role="dialog"
|
|
739
|
+
[attr.aria-label]="lcfg.title || 'Login'"
|
|
740
|
+
[style]="loginPanelOuterStyle()"
|
|
741
|
+
>
|
|
742
|
+
<div
|
|
743
|
+
class="dga-panel-enter dga-panel-enter--anchor-end overflow-y-auto overscroll-contain
|
|
744
|
+
rounded-2xl border border-border bg-card shadow-xl md:overflow-visible
|
|
745
|
+
md:rounded-md"
|
|
746
|
+
[style]="loginPanelInnerStyle()"
|
|
747
|
+
>
|
|
748
|
+
<div class="flex items-start justify-between gap-md px-2xl pt-2xl max-md:pt-xl">
|
|
749
|
+
<div class="flex min-w-0 flex-col gap-xs">
|
|
750
|
+
<h2 class="m-0 text-body-lg font-semibold text-display">
|
|
751
|
+
{{ lcfg.title || 'Login' }}
|
|
752
|
+
</h2>
|
|
753
|
+
<p class="m-0 text-body-sm text-paragraph">
|
|
754
|
+
{{ lcfg.description || 'Sign in to access your account' }}
|
|
755
|
+
</p>
|
|
756
|
+
</div>
|
|
757
|
+
<button
|
|
758
|
+
type="button"
|
|
759
|
+
class="inline-flex size-5xl shrink-0 cursor-pointer items-center justify-center
|
|
760
|
+
rounded-sm text-muted transition-colors hover:bg-neutral-light hover:text-fg
|
|
761
|
+
focus-visible:outline focus-visible:outline-2
|
|
762
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
763
|
+
[attr.aria-label]="lcfg.closeLabel || lcfg.cancelLabel || 'Close'"
|
|
764
|
+
(click)="closeLogin()"
|
|
765
|
+
>
|
|
766
|
+
<dga-icon name="close" size="md" />
|
|
767
|
+
</button>
|
|
768
|
+
</div>
|
|
769
|
+
|
|
770
|
+
<ng-content select="[dgaHeaderLoginBeforeForm]" />
|
|
771
|
+
|
|
772
|
+
@if (hasCustomLoginForm()) {
|
|
773
|
+
<div
|
|
774
|
+
class="px-2xl pb-[max(1.5rem,env(safe-area-inset-bottom))] pt-xl md:pb-2xl"
|
|
775
|
+
>
|
|
776
|
+
<ng-content select="[dgaHeaderLoginForm]" />
|
|
777
|
+
</div>
|
|
778
|
+
} @else {
|
|
779
|
+
<form
|
|
780
|
+
class="flex flex-col gap-xl px-2xl pb-[max(1.5rem,env(safe-area-inset-bottom))]
|
|
781
|
+
pt-xl md:pb-2xl"
|
|
782
|
+
(submit)="onLoginSubmit($event)"
|
|
783
|
+
>
|
|
784
|
+
<dga-field
|
|
785
|
+
[label]="lcfg.emailLabel || 'Email'"
|
|
786
|
+
controlId="dga-header-login-email"
|
|
787
|
+
[hint]="loginEmailError() ? '' : lcfg.emailHint || ''"
|
|
788
|
+
[error]="loginEmailError()"
|
|
789
|
+
required
|
|
790
|
+
>
|
|
791
|
+
<dga-form-control startIcon="mail" [filled]="!!loginEmail()">
|
|
792
|
+
<input
|
|
793
|
+
id="dga-header-login-email"
|
|
794
|
+
type="email"
|
|
795
|
+
name="email"
|
|
796
|
+
autocomplete="username"
|
|
797
|
+
required
|
|
798
|
+
class="placeholder:text-muted"
|
|
799
|
+
[placeholder]="lcfg.emailPlaceholder || 'name@example.gov.sa'"
|
|
800
|
+
[value]="loginEmail()"
|
|
801
|
+
(input)="onLoginEmailInput($any($event.target).value)"
|
|
802
|
+
/>
|
|
803
|
+
</dga-form-control>
|
|
804
|
+
</dga-field>
|
|
805
|
+
|
|
806
|
+
<dga-field
|
|
807
|
+
[label]="lcfg.passwordLabel || 'Password'"
|
|
808
|
+
controlId="dga-header-login-password"
|
|
809
|
+
[hint]="loginPasswordError() ? '' : lcfg.passwordHint || ''"
|
|
810
|
+
[error]="loginPasswordError()"
|
|
811
|
+
required
|
|
812
|
+
>
|
|
813
|
+
<dga-form-control [filled]="!!loginPassword()">
|
|
814
|
+
<input
|
|
815
|
+
id="dga-header-login-password"
|
|
816
|
+
[type]="showLoginPassword() ? 'text' : 'password'"
|
|
817
|
+
name="password"
|
|
818
|
+
autocomplete="current-password"
|
|
819
|
+
required
|
|
820
|
+
class="placeholder:text-muted"
|
|
821
|
+
[placeholder]="lcfg.passwordPlaceholder || 'Enter your password'"
|
|
822
|
+
[value]="loginPassword()"
|
|
823
|
+
(input)="onLoginPasswordInput($any($event.target).value)"
|
|
824
|
+
/>
|
|
825
|
+
<button
|
|
826
|
+
type="button"
|
|
827
|
+
dgaEnd
|
|
828
|
+
[attr.aria-label]="
|
|
829
|
+
showLoginPassword()
|
|
830
|
+
? lcfg.hidePasswordLabel || 'Hide password'
|
|
831
|
+
: lcfg.showPasswordLabel || 'Show password'
|
|
832
|
+
"
|
|
833
|
+
(click)="showLoginPassword.set(!showLoginPassword())"
|
|
834
|
+
>
|
|
835
|
+
<dga-icon [name]="showLoginPassword() ? 'eyeOff' : 'eye'" size="sm" />
|
|
836
|
+
</button>
|
|
837
|
+
</dga-form-control>
|
|
838
|
+
</dga-field>
|
|
839
|
+
|
|
840
|
+
@if (lcfg.forgotPasswordHref || lcfg.forgotPasswordLabel) {
|
|
841
|
+
<a
|
|
842
|
+
class="self-start text-body-sm font-medium text-fg-primary transition-opacity
|
|
843
|
+
hover:opacity-80
|
|
844
|
+
focus-visible:outline focus-visible:outline-2
|
|
845
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
846
|
+
[href]="appHref(lcfg.forgotPasswordHref || '#')"
|
|
847
|
+
>
|
|
848
|
+
{{ lcfg.forgotPasswordLabel || 'Forgot password?' }}
|
|
849
|
+
</a>
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
<ng-content select="[dgaHeaderLoginAfterFields]" />
|
|
853
|
+
|
|
854
|
+
@if (loginError() || lcfg.errorMessage) {
|
|
855
|
+
<p class="m-0 text-body-sm text-fg-error" role="alert">
|
|
856
|
+
{{ loginError() || lcfg.errorMessage }}
|
|
857
|
+
</p>
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
<div class="flex flex-col gap-md pt-xs">
|
|
861
|
+
<button
|
|
862
|
+
type="submit"
|
|
863
|
+
class="inline-flex h-5xl w-full cursor-pointer items-center justify-center gap-sm
|
|
864
|
+
rounded-sm bg-primary px-xl text-body-md font-medium text-on-color shadow-sm
|
|
865
|
+
transition-opacity hover:opacity-90 disabled:cursor-wait disabled:opacity-60
|
|
866
|
+
focus-visible:outline focus-visible:outline-2
|
|
867
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
868
|
+
[disabled]="loginSubmitting()"
|
|
869
|
+
>
|
|
870
|
+
@if (loginSubmitting()) {
|
|
871
|
+
<span
|
|
872
|
+
class="dga-login-spinner size-md rounded-full border-2 border-on-color/30
|
|
873
|
+
border-t-on-color"
|
|
874
|
+
aria-hidden="true"
|
|
875
|
+
></span>
|
|
876
|
+
}
|
|
877
|
+
<span>
|
|
878
|
+
{{
|
|
879
|
+
loginSubmitting()
|
|
880
|
+
? lcfg.submittingLabel || '…'
|
|
881
|
+
: lcfg.submitLabel || 'Login'
|
|
882
|
+
}}
|
|
883
|
+
</span>
|
|
884
|
+
</button>
|
|
885
|
+
@if (lcfg.showCancel !== false) {
|
|
886
|
+
<button
|
|
887
|
+
type="button"
|
|
888
|
+
class="inline-flex h-5xl w-full cursor-pointer items-center justify-center
|
|
889
|
+
rounded-sm px-xl text-body-md font-medium text-fg transition-colors
|
|
890
|
+
hover:bg-neutral-light
|
|
891
|
+
focus-visible:outline focus-visible:outline-2
|
|
892
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
893
|
+
(click)="closeLogin()"
|
|
894
|
+
>
|
|
895
|
+
{{ lcfg.cancelLabel || 'Cancel' }}
|
|
896
|
+
</button>
|
|
897
|
+
}
|
|
898
|
+
</div>
|
|
899
|
+
</form>
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
@if (hasCustomLoginFooter()) {
|
|
903
|
+
<div
|
|
904
|
+
class="border-t border-border-subtle px-2xl py-xl pb-[max(1.5rem,env(safe-area-inset-bottom))]"
|
|
905
|
+
>
|
|
906
|
+
<ng-content select="[dgaHeaderLoginFooter]" />
|
|
907
|
+
</div>
|
|
908
|
+
} @else if (showLoginRegisterRow(lcfg) || (lcfg.footerLinks?.length ?? 0) > 0) {
|
|
909
|
+
<div
|
|
910
|
+
class="flex flex-col gap-md border-t border-border-subtle px-2xl py-xl
|
|
911
|
+
pb-[max(1.5rem,env(safe-area-inset-bottom))]"
|
|
912
|
+
>
|
|
913
|
+
@if (showLoginRegisterRow(lcfg)) {
|
|
914
|
+
<p class="m-0 text-center text-body-sm text-muted">
|
|
915
|
+
{{ lcfg.registerPrompt || "Don't have an account?" }}
|
|
916
|
+
@if (lcfg.registerLabel || lcfg.registerHref) {
|
|
917
|
+
<a
|
|
918
|
+
class="ms-xs font-medium text-fg-primary transition-opacity hover:opacity-80
|
|
919
|
+
focus-visible:outline focus-visible:outline-2
|
|
920
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
921
|
+
[href]="appHref(lcfg.registerHref || '#')"
|
|
922
|
+
>
|
|
923
|
+
{{ lcfg.registerLabel || 'Sign up' }}
|
|
924
|
+
</a>
|
|
925
|
+
}
|
|
926
|
+
</p>
|
|
927
|
+
}
|
|
928
|
+
@if (lcfg.footerLinks?.length) {
|
|
929
|
+
<div class="flex flex-col gap-xs">
|
|
930
|
+
@for (link of lcfg.footerLinks; track link.id ?? link.label) {
|
|
931
|
+
<a
|
|
932
|
+
class="text-center text-body-sm font-medium text-fg-primary transition-opacity
|
|
933
|
+
hover:opacity-80
|
|
934
|
+
focus-visible:outline focus-visible:outline-2
|
|
935
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
936
|
+
[href]="appHref(link.href || '#')"
|
|
937
|
+
>
|
|
938
|
+
{{ link.label }}
|
|
939
|
+
</a>
|
|
940
|
+
}
|
|
941
|
+
</div>
|
|
942
|
+
}
|
|
943
|
+
</div>
|
|
944
|
+
}
|
|
945
|
+
</div>
|
|
946
|
+
</div>
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
<!-- Header user menu (authenticated) -->
|
|
950
|
+
@if (userMenuOpen() && userConfig(); as ucfg) {
|
|
951
|
+
<div
|
|
952
|
+
[id]="userPanelId"
|
|
953
|
+
class="dga-header-util-panel fixed w-[min(22rem,calc(100vw-2rem))] max-md:inset-x-3
|
|
954
|
+
max-md:bottom-3 max-md:top-auto max-md:w-auto"
|
|
955
|
+
role="menu"
|
|
956
|
+
[attr.aria-label]="ucfg.name"
|
|
957
|
+
[style]="dropdownPanelStyle()"
|
|
958
|
+
>
|
|
959
|
+
<div
|
|
960
|
+
class="dga-panel-enter dga-panel-enter--anchor-end max-h-[min(85svh,36rem)]
|
|
961
|
+
overflow-y-auto overscroll-contain rounded-2xl border border-border bg-card
|
|
962
|
+
shadow-xl md:max-h-[none] md:overflow-visible md:rounded-md"
|
|
963
|
+
>
|
|
964
|
+
<div class="flex items-center gap-lg border-b border-border-subtle px-xl py-lg">
|
|
965
|
+
<dga-avatar [name]="ucfg.name" [src]="ucfg.avatarSrc" size="md" />
|
|
966
|
+
<div class="flex min-w-0 flex-1 flex-col gap-xxs">
|
|
967
|
+
<span class="truncate text-body-md font-semibold text-display">{{ ucfg.name }}</span>
|
|
968
|
+
@if (ucfg.role) {
|
|
969
|
+
<span class="truncate text-body-sm text-muted">{{ ucfg.role }}</span>
|
|
970
|
+
}
|
|
971
|
+
@if (ucfg.email) {
|
|
972
|
+
<span class="truncate text-body-sm text-paragraph">{{ ucfg.email }}</span>
|
|
973
|
+
}
|
|
974
|
+
</div>
|
|
975
|
+
<button
|
|
976
|
+
type="button"
|
|
977
|
+
class="inline-flex size-5xl shrink-0 cursor-pointer items-center justify-center
|
|
978
|
+
rounded-sm text-muted transition-colors hover:bg-neutral-light hover:text-fg
|
|
979
|
+
focus-visible:outline focus-visible:outline-2
|
|
980
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
981
|
+
aria-label="Close"
|
|
982
|
+
(click)="closeUserMenu()"
|
|
983
|
+
>
|
|
984
|
+
<dga-icon name="close" size="md" />
|
|
985
|
+
</button>
|
|
986
|
+
</div>
|
|
987
|
+
<div class="flex flex-col gap-xxs p-sm">
|
|
988
|
+
@for (link of ucfg.links || []; track link.id) {
|
|
989
|
+
@if (link.id === 'logout') {
|
|
990
|
+
<div class="my-xs border-t border-border-subtle" role="separator"></div>
|
|
991
|
+
<button
|
|
992
|
+
type="button"
|
|
993
|
+
role="menuitem"
|
|
994
|
+
class="flex w-full cursor-pointer items-center gap-md rounded-sm px-lg py-sm
|
|
995
|
+
text-start text-body-md text-fg-error transition-colors hover:bg-error-light
|
|
996
|
+
focus-visible:outline focus-visible:outline-2
|
|
997
|
+
focus-visible:outline-offset-[-2px] focus-visible:outline-focus"
|
|
998
|
+
(click)="onUserLink(link)"
|
|
999
|
+
>
|
|
1000
|
+
@if (link.icon) {
|
|
1001
|
+
<dga-icon [name]="link.icon" size="md" />
|
|
1002
|
+
}
|
|
1003
|
+
<span>{{ link.label }}</span>
|
|
1004
|
+
</button>
|
|
1005
|
+
} @else if (link.href) {
|
|
1006
|
+
<a
|
|
1007
|
+
role="menuitem"
|
|
1008
|
+
class="flex w-full cursor-pointer items-center gap-md rounded-sm px-lg py-sm
|
|
1009
|
+
text-start text-body-md text-fg transition-colors hover:bg-neutral-light
|
|
1010
|
+
focus-visible:outline focus-visible:outline-2
|
|
1011
|
+
focus-visible:outline-offset-[-2px] focus-visible:outline-focus"
|
|
1012
|
+
[href]="appHref(link.href)"
|
|
1013
|
+
(click)="onUserLink(link)"
|
|
1014
|
+
>
|
|
1015
|
+
@if (link.icon) {
|
|
1016
|
+
<dga-icon [name]="link.icon" size="md" />
|
|
1017
|
+
}
|
|
1018
|
+
<span>{{ link.label }}</span>
|
|
1019
|
+
</a>
|
|
1020
|
+
} @else {
|
|
1021
|
+
<button
|
|
1022
|
+
type="button"
|
|
1023
|
+
role="menuitem"
|
|
1024
|
+
class="flex w-full cursor-pointer items-center gap-md rounded-sm px-lg py-sm
|
|
1025
|
+
text-start text-body-md text-fg transition-colors hover:bg-neutral-light
|
|
1026
|
+
focus-visible:outline focus-visible:outline-2
|
|
1027
|
+
focus-visible:outline-offset-[-2px] focus-visible:outline-focus"
|
|
1028
|
+
(click)="onUserLink(link)"
|
|
1029
|
+
>
|
|
1030
|
+
@if (link.icon) {
|
|
1031
|
+
<dga-icon [name]="link.icon" size="md" />
|
|
1032
|
+
}
|
|
1033
|
+
<span>{{ link.label }}</span>
|
|
1034
|
+
</button>
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
</div>
|
|
1038
|
+
</div>
|
|
1039
|
+
</div>
|
|
1040
|
+
}
|
|
1041
|
+
</div>
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
<!-- Mobile navigation: sheet | fullscreen | push -->
|
|
1045
|
+
@if (isPortal() && items().length) {
|
|
1046
|
+
@if (mobileOpen() && mobileNav() !== 'push') {
|
|
1047
|
+
<button
|
|
1048
|
+
type="button"
|
|
1049
|
+
class="fixed inset-0 cursor-default md:hidden"
|
|
1050
|
+
[class]="
|
|
1051
|
+
mobileNav() === 'fullscreen'
|
|
1052
|
+
? 'z-[35] bg-overlay/60 backdrop-blur-[3px]'
|
|
1053
|
+
: 'z-10 bg-overlay/40 backdrop-blur-[1px]'
|
|
1054
|
+
"
|
|
1055
|
+
tabindex="-1"
|
|
1056
|
+
[attr.aria-label]="menuCloseLabel()"
|
|
1057
|
+
(click)="closeAll()"
|
|
1058
|
+
></button>
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
<div
|
|
1062
|
+
[id]="collapseId"
|
|
1063
|
+
[class]="mobilePanelClass()"
|
|
1064
|
+
[attr.data-mobile-nav]="mobileNav()"
|
|
1065
|
+
[attr.aria-hidden]="!mobileOpen()"
|
|
1066
|
+
[attr.inert]="mobileOpen() ? null : ''"
|
|
1067
|
+
>
|
|
1068
|
+
@if (mobileNav() === 'fullscreen') {
|
|
1069
|
+
<div
|
|
1070
|
+
class="flex h-(--size-header-portal) shrink-0 items-center justify-between
|
|
1071
|
+
gap-lg border-b border-border px-xl"
|
|
1072
|
+
>
|
|
1073
|
+
<div class="flex min-w-0 items-center gap-lg">
|
|
1074
|
+
@if (brandLogo()) {
|
|
1075
|
+
<img
|
|
1076
|
+
class="h-5xl w-auto max-w-[10rem] shrink-0 object-contain"
|
|
1077
|
+
[src]="brandLogo()"
|
|
1078
|
+
[alt]="brandLogoAlt()"
|
|
1079
|
+
/>
|
|
1080
|
+
} @else {
|
|
1081
|
+
<span class="truncate text-body-md font-semibold text-display">{{
|
|
1082
|
+
brand() || brandLogoAlt() || navLabel()
|
|
1083
|
+
}}</span>
|
|
1084
|
+
}
|
|
1085
|
+
</div>
|
|
1086
|
+
<button
|
|
1087
|
+
type="button"
|
|
1088
|
+
class="inline-flex size-6xl shrink-0 cursor-pointer items-center justify-center
|
|
1089
|
+
rounded-md text-fg transition-colors hover:bg-neutral-light
|
|
1090
|
+
focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2
|
|
1091
|
+
focus-visible:outline-focus"
|
|
1092
|
+
[attr.aria-label]="menuCloseLabel()"
|
|
1093
|
+
(click)="closeAll()"
|
|
1094
|
+
>
|
|
1095
|
+
<dga-icon name="close" size="xl" />
|
|
1096
|
+
</button>
|
|
1097
|
+
</div>
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
@if (mobileNav() === 'sheet') {
|
|
1101
|
+
<div
|
|
1102
|
+
class="flex min-h-(--size-header-portal) shrink-0 items-center justify-end
|
|
1103
|
+
border-b border-border-subtle px-md
|
|
1104
|
+
pt-[env(safe-area-inset-top,0px)]"
|
|
1105
|
+
>
|
|
1106
|
+
<button
|
|
1107
|
+
type="button"
|
|
1108
|
+
class="inline-flex size-6xl shrink-0 cursor-pointer items-center justify-center
|
|
1109
|
+
rounded-md text-fg transition-colors hover:bg-neutral-light
|
|
1110
|
+
focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2
|
|
1111
|
+
focus-visible:outline-focus"
|
|
1112
|
+
[attr.aria-label]="menuCloseLabel()"
|
|
1113
|
+
(click)="closeAll()"
|
|
1114
|
+
>
|
|
1115
|
+
<dga-icon name="close" size="xl" />
|
|
1116
|
+
</button>
|
|
1117
|
+
</div>
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
@if (mobileNav() === 'push') {
|
|
1121
|
+
<div class="border-b border-border-subtle px-xl py-md">
|
|
1122
|
+
<p class="m-0 text-body-sm font-medium text-muted">{{ navLabel() }}</p>
|
|
1123
|
+
</div>
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
<div
|
|
1127
|
+
class="min-h-0 flex-1 overflow-y-auto overscroll-contain px-xl py-lg
|
|
1128
|
+
pb-[max(1rem,env(safe-area-inset-bottom))]"
|
|
1129
|
+
>
|
|
1130
|
+
<ul class="m-0 flex list-none flex-col gap-none p-0" role="list">
|
|
1131
|
+
@for (item of items(); track item.label; let i = $index) {
|
|
1132
|
+
<li class="border-b border-border-subtle last:border-b-0">
|
|
1133
|
+
@if (item.dropdown) {
|
|
1134
|
+
<button
|
|
1135
|
+
type="button"
|
|
1136
|
+
[class]="mobileItemClass(!!item.current, openDropdown() === i)"
|
|
1137
|
+
[attr.aria-expanded]="openDropdown() === i"
|
|
1138
|
+
(click)="toggleDropdown(i, $event)"
|
|
1139
|
+
>
|
|
1140
|
+
<span class="min-w-0 flex-1" [class]="item.current ? 'text-fg-primary' : ''">{{
|
|
1141
|
+
item.label
|
|
1142
|
+
}}</span>
|
|
1143
|
+
<dga-icon
|
|
1144
|
+
name="chevronDown"
|
|
1145
|
+
size="md"
|
|
1146
|
+
class="shrink-0"
|
|
1147
|
+
[class]="
|
|
1148
|
+
openDropdown() === i
|
|
1149
|
+
? 'rotate-180 text-fg-primary transition-transform duration-200'
|
|
1150
|
+
: 'text-muted transition-transform duration-200'
|
|
1151
|
+
"
|
|
1152
|
+
/>
|
|
1153
|
+
</button>
|
|
1154
|
+
|
|
1155
|
+
@if (openDropdown() === i) {
|
|
1156
|
+
<div
|
|
1157
|
+
class="dga-panel-enter space-y-md border-s-2 border-primary/30 pb-lg ps-lg
|
|
1158
|
+
ms-sm"
|
|
1159
|
+
>
|
|
1160
|
+
@if (item.dropdown.featured; as feat) {
|
|
1161
|
+
<a
|
|
1162
|
+
class="flex flex-col gap-sm rounded-md border border-border
|
|
1163
|
+
bg-primary-faint p-xl text-start no-underline"
|
|
1164
|
+
[href]="appHref(feat.href || '#')"
|
|
1165
|
+
(click)="closeAll()"
|
|
1166
|
+
>
|
|
1167
|
+
<span class="text-body-md font-semibold text-display">{{
|
|
1168
|
+
feat.title
|
|
1169
|
+
}}</span>
|
|
1170
|
+
@if (feat.description) {
|
|
1171
|
+
<span class="text-body-sm text-paragraph">{{
|
|
1172
|
+
feat.description
|
|
1173
|
+
}}</span>
|
|
1174
|
+
}
|
|
1175
|
+
@if (feat.cta) {
|
|
1176
|
+
<span class="text-body-sm font-medium text-fg-primary">{{
|
|
1177
|
+
feat.cta
|
|
1178
|
+
}}</span>
|
|
1179
|
+
}
|
|
1180
|
+
</a>
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
@if (item.dropdown.columns?.length) {
|
|
1184
|
+
@for (col of item.dropdown.columns!; track col.title ?? $index) {
|
|
1185
|
+
<div class="flex flex-col gap-xs">
|
|
1186
|
+
@if (col.title) {
|
|
1187
|
+
<p class="px-xl text-body-sm font-medium text-fg-primary">
|
|
1188
|
+
{{ col.title }}
|
|
1189
|
+
</p>
|
|
1190
|
+
}
|
|
1191
|
+
<ul class="m-0 flex list-none flex-col gap-none p-0">
|
|
1192
|
+
@for (link of col.links; track link.label) {
|
|
1193
|
+
<li>
|
|
1194
|
+
<a
|
|
1195
|
+
[class]="mobileLink"
|
|
1196
|
+
[href]="appHref(link.href || '#')"
|
|
1197
|
+
(click)="onNavLinkClick(link, $event); closeAll()"
|
|
1198
|
+
>
|
|
1199
|
+
<span>{{ link.label }}</span>
|
|
1200
|
+
@if (link.description) {
|
|
1201
|
+
<span class="text-body-sm text-muted">{{
|
|
1202
|
+
link.description
|
|
1203
|
+
}}</span>
|
|
1204
|
+
}
|
|
1205
|
+
</a>
|
|
1206
|
+
</li>
|
|
1207
|
+
}
|
|
1208
|
+
</ul>
|
|
1209
|
+
</div>
|
|
1210
|
+
}
|
|
1211
|
+
} @else {
|
|
1212
|
+
<ul class="m-0 flex list-none flex-col gap-none p-0">
|
|
1213
|
+
@for (link of flatLinks(item); track link.label) {
|
|
1214
|
+
<li>
|
|
1215
|
+
<a
|
|
1216
|
+
[class]="mobileLink"
|
|
1217
|
+
[href]="appHref(link.href || '#')"
|
|
1218
|
+
(click)="onNavLinkClick(link, $event); closeAll()"
|
|
1219
|
+
>
|
|
1220
|
+
<span>{{ link.label }}</span>
|
|
1221
|
+
@if (link.description) {
|
|
1222
|
+
<span class="text-body-sm text-muted">{{
|
|
1223
|
+
link.description
|
|
1224
|
+
}}</span>
|
|
1225
|
+
}
|
|
1226
|
+
</a>
|
|
1227
|
+
</li>
|
|
1228
|
+
}
|
|
1229
|
+
</ul>
|
|
1230
|
+
}
|
|
1231
|
+
</div>
|
|
1232
|
+
}
|
|
1233
|
+
} @else {
|
|
1234
|
+
<a
|
|
1235
|
+
[class]="mobileItemClass(!!item.current)"
|
|
1236
|
+
[attr.aria-current]="item.current ? 'page' : null"
|
|
1237
|
+
[href]="appHref(item.href || '#')"
|
|
1238
|
+
(click)="onNavLinkClick(item, $event); closeAll()"
|
|
1239
|
+
>
|
|
1240
|
+
@if (item.current) {
|
|
1241
|
+
<span
|
|
1242
|
+
class="absolute inset-y-md start-0 w-1 rounded-e-sm bg-primary"
|
|
1243
|
+
aria-hidden="true"
|
|
1244
|
+
></span>
|
|
1245
|
+
}
|
|
1246
|
+
<span class="min-w-0 flex-1" [class]="item.current ? 'text-fg-primary' : ''">{{
|
|
1247
|
+
item.label
|
|
1248
|
+
}}</span>
|
|
1249
|
+
</a>
|
|
1250
|
+
}
|
|
1251
|
+
</li>
|
|
1252
|
+
}
|
|
1253
|
+
</ul>
|
|
1254
|
+
</div>
|
|
1255
|
+
|
|
1256
|
+
@if (actions().length) {
|
|
1257
|
+
<div
|
|
1258
|
+
class="flex shrink-0 items-center justify-around gap-sm border-t border-border
|
|
1259
|
+
bg-nav px-xl py-md pb-[max(0.75rem,env(safe-area-inset-bottom))]"
|
|
1260
|
+
>
|
|
1261
|
+
@for (action of actions(); track action.id) {
|
|
1262
|
+
@if (action.href) {
|
|
1263
|
+
<a
|
|
1264
|
+
class="relative inline-flex min-h-6xl min-w-6xl cursor-pointer flex-col
|
|
1265
|
+
items-center justify-center gap-xxs rounded-md px-md text-fg
|
|
1266
|
+
hover:bg-neutral-light
|
|
1267
|
+
focus-visible:outline focus-visible:outline-2
|
|
1268
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
1269
|
+
[href]="appHref(action.href)"
|
|
1270
|
+
[attr.aria-label]="action.label"
|
|
1271
|
+
[attr.data-dga-action]="action.id"
|
|
1272
|
+
(click)="closeAll()"
|
|
1273
|
+
>
|
|
1274
|
+
@if (action.icon) {
|
|
1275
|
+
<dga-icon [name]="action.icon" size="xl" />
|
|
1276
|
+
}
|
|
1277
|
+
<span class="max-w-11xl truncate text-body-2xs">{{ action.label }}</span>
|
|
1278
|
+
@if (action.badge) {
|
|
1279
|
+
<span [class]="badgeClass()">{{ action.badge }}</span>
|
|
1280
|
+
}
|
|
1281
|
+
</a>
|
|
1282
|
+
} @else {
|
|
1283
|
+
<button
|
|
1284
|
+
type="button"
|
|
1285
|
+
class="relative inline-flex min-h-6xl min-w-6xl cursor-pointer flex-col
|
|
1286
|
+
items-center justify-center gap-xxs rounded-md px-md text-fg
|
|
1287
|
+
hover:bg-neutral-light
|
|
1288
|
+
focus-visible:outline focus-visible:outline-2
|
|
1289
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
1290
|
+
[attr.aria-label]="action.label"
|
|
1291
|
+
[attr.data-dga-action]="action.id"
|
|
1292
|
+
(click)="onMobileAction(action, $event)"
|
|
1293
|
+
>
|
|
1294
|
+
@if (action.icon) {
|
|
1295
|
+
<dga-icon [name]="action.icon" size="xl" />
|
|
1296
|
+
}
|
|
1297
|
+
<span class="max-w-11xl truncate text-body-2xs">{{ action.label }}</span>
|
|
1298
|
+
@if (action.badge) {
|
|
1299
|
+
<span [class]="badgeClass()">{{ action.badge }}</span>
|
|
1300
|
+
}
|
|
1301
|
+
</button>
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
</div>
|
|
1305
|
+
}
|
|
1306
|
+
</div>
|
|
1307
|
+
}
|
|
1308
|
+
`,isInline:!0,styles:["@keyframes dga-fade-in{0%{opacity:0}to{opacity:1}}@keyframes dga-panel-in{0%{opacity:0;transform:translateY(-.625rem) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes dga-chip-in{0%{opacity:0;transform:translateY(.25rem)}to{opacity:1;transform:translateY(0)}}@keyframes dga-notif-row-in{0%{opacity:0;transform:translateY(.35rem)}to{opacity:1;transform:translateY(0)}}@keyframes dga-expand-fade{0%{opacity:0;transform:translateY(-.25rem)}to{opacity:1;transform:translateY(0)}}@keyframes dga-spin{to{transform:rotate(360deg)}}@keyframes dga-badge-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.12)}}@keyframes dga-push-in{0%{opacity:0;transform:translateY(-.75rem)}to{opacity:1;transform:translateY(0)}}@keyframes dga-sheet-in-ltr{0%{opacity:.85;transform:translate3d(-100%,0,0)}to{opacity:1;transform:translateZ(0)}}@keyframes dga-sheet-in-rtl{0%{opacity:.85;transform:translate3d(100%,0,0)}to{opacity:1;transform:translateZ(0)}}@keyframes dga-fs-in{0%{opacity:0;transform:translateY(.5rem)}to{opacity:1;transform:translateY(0)}}@keyframes dga-sheet-in{0%{opacity:0;transform:translateY(1.25rem)}to{opacity:1;transform:translateY(0)}}:host .dga-util-backdrop,.dga-header-util-layer .dga-util-backdrop{animation:dga-fade-in .22s ease both}.dga-header-util-layer{position:fixed;inset:0;z-index:var(--z-index-urgent, 400);pointer-events:none}.dga-header-util-layer>.dga-util-backdrop,.dga-header-util-layer>.dga-header-util-panel{pointer-events:auto}:host .dga-panel-enter,.dga-header-util-layer .dga-panel-enter{animation:dga-panel-in .28s cubic-bezier(.16,1,.3,1) both;transform-origin:top center;will-change:transform,opacity}:host .dga-panel-enter--anchor-end,.dga-header-util-layer .dga-panel-enter--anchor-end{transform-origin:top right}:host-context([dir=\"rtl\"]) .dga-panel-enter--anchor-end,:host([dir=\"rtl\"]) .dga-panel-enter--anchor-end,:host-context([dir=\"rtl\"]) .dga-header-util-layer .dga-panel-enter--anchor-end,[dir=rtl] .dga-header-util-layer .dga-panel-enter--anchor-end{transform-origin:top left}@media(max-width:767px){:host .dga-panel-enter--anchor-end,.dga-header-util-layer .dga-panel-enter--anchor-end{animation-name:dga-sheet-in;transform-origin:bottom center}}:host .dga-search-chip{animation:dga-chip-in .28s cubic-bezier(.16,1,.3,1) both}:host .dga-search-input{-webkit-appearance:none;appearance:none}:host .dga-search-input::-webkit-search-decoration,:host .dga-search-input::-webkit-search-cancel-button,:host .dga-search-input::-webkit-search-results-button,:host .dga-search-input::-webkit-search-results-decoration{-webkit-appearance:none;appearance:none;display:none}:host .dga-search-voice.dga-search-voice--active{color:var(--dga-text-primary, #1b8354)!important;background:var(--dga-bg-primary-faint, #f3faf6)!important}:host .dga-notif-item,.dga-header-util-layer .dga-notif-item{animation:dga-notif-row-in .26s cubic-bezier(.16,1,.3,1) both}:host .dga-notif-actions,.dga-header-util-layer .dga-notif-actions{animation:dga-expand-fade .2s ease both}:host .dga-login-spinner,.dga-header-util-layer .dga-login-spinner{animation:dga-spin .7s linear infinite}:host .dga-action-badge{animation:dga-badge-pulse 1.8s ease-in-out infinite;transform-origin:center}@media(prefers-reduced-motion:reduce){:host .dga-util-backdrop,:host .dga-panel-enter,:host .dga-search-chip,:host .dga-notif-item,:host .dga-notif-actions,.dga-header-util-layer .dga-util-backdrop,.dga-header-util-layer .dga-panel-enter{animation-duration:.01ms!important;animation-delay:0ms!important}}:host .dga-burger__box{position:relative;display:block;width:1.375rem;height:1rem}:host .dga-burger__line{position:absolute;inset-inline:0;height:2px;border-radius:1px;background:currentColor;transition:transform .22s cubic-bezier(.4,0,.2,1),opacity .16s ease,top .22s cubic-bezier(.4,0,.2,1)}:host .dga-burger__line:nth-child(1){top:0}:host .dga-burger__line:nth-child(2){top:calc(50% - 1px)}:host .dga-burger__line:nth-child(3){top:calc(100% - 2px)}:host .dga-burger--open{background:var(--color-neutral-light, #f3f4f6)}:host .dga-burger--hidden{visibility:hidden;pointer-events:none}:host .dga-burger--open .dga-burger__line:nth-child(1){top:calc(50% - 1px);transform:rotate(45deg)}:host .dga-burger--open .dga-burger__line:nth-child(2){opacity:0;transform:scaleX(.4)}:host .dga-burger--open .dga-burger__line:nth-child(3){top:calc(50% - 1px);transform:rotate(-45deg)}:host .dga-mobile-nav-closed{display:none}:host .dga-mobile-nav-open{display:flex}:host .dga-mobile-push-open{animation:dga-push-in .24s cubic-bezier(.4,0,.2,1) forwards}:host .dga-mobile-sheet-open{animation:dga-sheet-in-rtl .28s cubic-bezier(.4,0,.2,1) forwards}:host-context([dir=\"rtl\"]) .dga-mobile-sheet-open{animation:dga-sheet-in-ltr .28s cubic-bezier(.4,0,.2,1) forwards}:host .dga-mobile-fs-open{animation:dga-fs-in .24s cubic-bezier(.4,0,.2,1) forwards}@media(prefers-reduced-motion:reduce){:host .dga-action-badge,:host .dga-mobile-push-open,:host .dga-mobile-sheet-open,:host .dga-mobile-fs-open,:host-context([dir=\"rtl\"]) .dga-mobile-sheet-open,:host .dga-burger__line{animation:none;transition:none}}\n"],dependencies:[{kind:"component",type:A,selector:"dga-avatar",inputs:["src","name","size","alt"]},{kind:"component",type:E,selector:"dga-badge",inputs:["variant","size"]},{kind:"component",type:H,selector:"dga-field",inputs:["label","labelHint","hint","error","status","statusMessage","controlId","required"]},{kind:"component",type:F,selector:"dga-form-control",inputs:["size","status","disabled","filled","startIcon","endIcon"]},{kind:"directive",type:$,selector:"[dgaEnd]"},{kind:"component",type:R,selector:"dga-icon",inputs:["name","glyph","size","tone","label"]},{kind:"component",type:j,selector:"dga-icon-badge",inputs:["size","appearance"]},{kind:"component",type:q,selector:"dga-modal",inputs:["open","title","description","size","animation","closeLabel","closeOnBackdrop","closeOnEscape","showClose","scrollable","centered"],outputs:["openChange","closed","opened"]},{kind:"component",type:V,selector:"dga-tooltip",inputs:["text","title","placement","variant","showIcon","disabled","showDelay","hideDelay","dismissMs"]}],changeDetection:i.ChangeDetectionStrategy.OnPush})}i.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:i,type:v,decorators:[{type:G,args:[{selector:"dga-header",standalone:!0,changeDetection:K.OnPush,imports:[A,E,H,F,$,R,j,q,V],template:`
|
|
1309
|
+
<div [class]="innerClasses()">
|
|
1310
|
+
<div class="relative flex min-w-0 shrink-0 items-center self-center">
|
|
1311
|
+
<ng-content select="[dgaHeaderBrand]" />
|
|
1312
|
+
@if (brand() || brandLogo()) {
|
|
1313
|
+
<a
|
|
1314
|
+
class="inline-flex h-(--size-header-logo) cursor-pointer items-center gap-lg font-sans
|
|
1315
|
+
focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2
|
|
1316
|
+
focus-visible:outline-focus"
|
|
1317
|
+
[href]="appHref(brandHref())"
|
|
1318
|
+
>
|
|
1319
|
+
@if (brandLogo()) {
|
|
1320
|
+
<img
|
|
1321
|
+
class="h-(--size-header-logo) w-auto max-w-[min(100%,14rem)] shrink-0 object-contain"
|
|
1322
|
+
[src]="brandLogo()"
|
|
1323
|
+
[alt]="brandLogoAlt()"
|
|
1324
|
+
height="58"
|
|
1325
|
+
/>
|
|
1326
|
+
} @else if (appearance() === 'portal' && brandPlaceholder()) {
|
|
1327
|
+
<span
|
|
1328
|
+
class="inline-flex size-(--size-header-logo) shrink-0 items-center justify-center rounded-sm
|
|
1329
|
+
bg-primary-faint text-fg-primary"
|
|
1330
|
+
aria-hidden="true"
|
|
1331
|
+
>
|
|
1332
|
+
<dga-icon name="home" size="xl" tone="primary" />
|
|
1333
|
+
</span>
|
|
1334
|
+
}
|
|
1335
|
+
@if (brand() && !brandLogo()) {
|
|
1336
|
+
<span class="flex min-w-0 flex-col gap-xxs">
|
|
1337
|
+
<span class="text-body-md font-bold text-display">{{ brand() }}</span>
|
|
1338
|
+
@if (brandSlogan()) {
|
|
1339
|
+
<span class="text-body-sm font-normal text-muted">{{ brandSlogan() }}</span>
|
|
1340
|
+
}
|
|
1341
|
+
</span>
|
|
1342
|
+
}
|
|
1343
|
+
</a>
|
|
1344
|
+
}
|
|
1345
|
+
</div>
|
|
1346
|
+
|
|
1347
|
+
@if (isPortal() && items().length) {
|
|
1348
|
+
<button
|
|
1349
|
+
type="button"
|
|
1350
|
+
class="dga-burger relative z-30 ms-auto hidden h-full w-6xl shrink-0 cursor-pointer
|
|
1351
|
+
items-center justify-center self-stretch rounded-md text-fg transition-colors
|
|
1352
|
+
hover:bg-neutral-light max-md:inline-flex
|
|
1353
|
+
focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2
|
|
1354
|
+
focus-visible:outline-focus"
|
|
1355
|
+
[class.dga-burger--open]="mobileOpen()"
|
|
1356
|
+
[class.dga-burger--hidden]="mobileOpen() && mobileNav() !== 'push'"
|
|
1357
|
+
[attr.aria-expanded]="mobileOpen()"
|
|
1358
|
+
[attr.aria-controls]="collapseId"
|
|
1359
|
+
[attr.aria-label]="mobileOpen() ? menuCloseLabel() : menuToggleLabel()"
|
|
1360
|
+
(click)="toggleMobile()"
|
|
1361
|
+
>
|
|
1362
|
+
<span class="dga-burger__box" aria-hidden="true">
|
|
1363
|
+
<span class="dga-burger__line"></span>
|
|
1364
|
+
<span class="dga-burger__line"></span>
|
|
1365
|
+
<span class="dga-burger__line"></span>
|
|
1366
|
+
</span>
|
|
1367
|
+
</button>
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
<!-- Desktop navigation -->
|
|
1371
|
+
<nav
|
|
1372
|
+
[class]="desktopNavClasses()"
|
|
1373
|
+
[attr.aria-label]="navLabel()"
|
|
1374
|
+
[attr.hidden]="null"
|
|
1375
|
+
>
|
|
1376
|
+
@if (items().length) {
|
|
1377
|
+
<ul
|
|
1378
|
+
class="m-0 flex list-none flex-row flex-nowrap items-stretch gap-none p-0"
|
|
1379
|
+
[class.overflow-x-auto]="openDropdown() === null"
|
|
1380
|
+
[class.overflow-visible]="openDropdown() !== null"
|
|
1381
|
+
role="list"
|
|
1382
|
+
>
|
|
1383
|
+
@for (item of items(); track item.label; let i = $index) {
|
|
1384
|
+
<li
|
|
1385
|
+
class="relative"
|
|
1386
|
+
[class.z-dropdown]="openDropdown() === i"
|
|
1387
|
+
[attr.data-open]="openDropdown() === i || null"
|
|
1388
|
+
[attr.data-variant]="item.dropdown ? resolveVariant(item) : null"
|
|
1389
|
+
(mouseenter)="onItemEnter(i)"
|
|
1390
|
+
(focusin)="onItemEnter(i)"
|
|
1391
|
+
>
|
|
1392
|
+
@if (item.dropdown) {
|
|
1393
|
+
<button
|
|
1394
|
+
type="button"
|
|
1395
|
+
[class]="navItemClass(!!item.current, openDropdown() === i)"
|
|
1396
|
+
[attr.aria-expanded]="openDropdown() === i"
|
|
1397
|
+
[attr.aria-haspopup]="'true'"
|
|
1398
|
+
(click)="toggleDropdown(i, $event)"
|
|
1399
|
+
>
|
|
1400
|
+
<span
|
|
1401
|
+
aria-hidden="true"
|
|
1402
|
+
[class]="indicatorClass(!!item.current || openDropdown() === i)"
|
|
1403
|
+
></span>
|
|
1404
|
+
<span class="whitespace-nowrap">{{ item.label }}</span>
|
|
1405
|
+
<dga-icon
|
|
1406
|
+
name="chevronDown"
|
|
1407
|
+
size="md"
|
|
1408
|
+
[class]="
|
|
1409
|
+
openDropdown() === i
|
|
1410
|
+
? 'rotate-180 transition-transform duration-200'
|
|
1411
|
+
: 'transition-transform duration-200'
|
|
1412
|
+
"
|
|
1413
|
+
/>
|
|
1414
|
+
</button>
|
|
1415
|
+
|
|
1416
|
+
@if (openDropdown() === i && resolveVariant(item) === 'menu') {
|
|
1417
|
+
<div
|
|
1418
|
+
class="absolute start-0 top-full z-dropdown min-w-[16rem]
|
|
1419
|
+
max-w-[min(100vw-2rem,20rem)]"
|
|
1420
|
+
role="menu"
|
|
1421
|
+
[attr.aria-label]="item.label"
|
|
1422
|
+
>
|
|
1423
|
+
<div class="h-xs" aria-hidden="true"></div>
|
|
1424
|
+
<div
|
|
1425
|
+
class="dga-panel-enter rounded-md border border-border bg-card p-sm
|
|
1426
|
+
shadow-lg"
|
|
1427
|
+
>
|
|
1428
|
+
@if (item.dropdown.columns?.length) {
|
|
1429
|
+
<div class="flex flex-col gap-lg p-md">
|
|
1430
|
+
@for (col of item.dropdown.columns!; track col.title ?? $index) {
|
|
1431
|
+
<div class="flex flex-col gap-xs">
|
|
1432
|
+
@if (col.title) {
|
|
1433
|
+
<p class="px-xl text-body-sm font-medium text-fg-primary">
|
|
1434
|
+
{{ col.title }}
|
|
1435
|
+
</p>
|
|
1436
|
+
}
|
|
1437
|
+
<ul class="m-0 flex list-none flex-col gap-none p-0" role="list">
|
|
1438
|
+
@for (link of col.links; track link.label) {
|
|
1439
|
+
<li role="none">
|
|
1440
|
+
<a
|
|
1441
|
+
role="menuitem"
|
|
1442
|
+
[class]="dropLink"
|
|
1443
|
+
[href]="appHref(link.href || '#')"
|
|
1444
|
+
(click)="onNavLinkClick(link, $event)"
|
|
1445
|
+
>{{ link.label }}</a
|
|
1446
|
+
>
|
|
1447
|
+
</li>
|
|
1448
|
+
}
|
|
1449
|
+
</ul>
|
|
1450
|
+
</div>
|
|
1451
|
+
}
|
|
1452
|
+
</div>
|
|
1453
|
+
} @else {
|
|
1454
|
+
<ul class="m-0 flex list-none flex-col gap-none p-0" role="list">
|
|
1455
|
+
@for (link of item.dropdown.links || []; track link.label) {
|
|
1456
|
+
<li role="none">
|
|
1457
|
+
<a
|
|
1458
|
+
role="menuitem"
|
|
1459
|
+
[class]="dropLink"
|
|
1460
|
+
[href]="appHref(link.href || '#')"
|
|
1461
|
+
(click)="onNavLinkClick(link, $event)"
|
|
1462
|
+
>{{ link.label }}</a
|
|
1463
|
+
>
|
|
1464
|
+
</li>
|
|
1465
|
+
}
|
|
1466
|
+
</ul>
|
|
1467
|
+
}
|
|
1468
|
+
</div>
|
|
1469
|
+
</div>
|
|
1470
|
+
}
|
|
1471
|
+
} @else {
|
|
1472
|
+
<a
|
|
1473
|
+
[class]="navItemClass(!!item.current)"
|
|
1474
|
+
[attr.aria-current]="item.current ? 'page' : null"
|
|
1475
|
+
[href]="appHref(item.href || '#')"
|
|
1476
|
+
(click)="onNavLinkClick(item, $event)"
|
|
1477
|
+
>
|
|
1478
|
+
<span aria-hidden="true" [class]="indicatorClass(!!item.current)"></span>
|
|
1479
|
+
<span class="whitespace-nowrap">{{ item.label }}</span>
|
|
1480
|
+
</a>
|
|
1481
|
+
}
|
|
1482
|
+
</li>
|
|
1483
|
+
}
|
|
1484
|
+
</ul>
|
|
1485
|
+
}
|
|
1486
|
+
<div class="contents">
|
|
1487
|
+
<ng-content />
|
|
1488
|
+
</div>
|
|
1489
|
+
</nav>
|
|
1490
|
+
|
|
1491
|
+
<div [class]="actionsClasses()">
|
|
1492
|
+
@for (action of actions(); track action.id) {
|
|
1493
|
+
<dga-tooltip
|
|
1494
|
+
class="relative flex h-full"
|
|
1495
|
+
[text]="actionTooltip(action)"
|
|
1496
|
+
placement="bottom"
|
|
1497
|
+
[showIcon]="false"
|
|
1498
|
+
[disabled]="!isIconOnly(action) && !(isLoginAction(action) && authenticated())"
|
|
1499
|
+
>
|
|
1500
|
+
@if (action.href) {
|
|
1501
|
+
<a
|
|
1502
|
+
[class]="actionClass(action)"
|
|
1503
|
+
[href]="appHref(action.href)"
|
|
1504
|
+
[attr.aria-label]="actionAriaLabel(action)"
|
|
1505
|
+
[attr.data-dga-action]="action.id"
|
|
1506
|
+
>
|
|
1507
|
+
<span aria-hidden="true" [class]="indicatorClass(false)"></span>
|
|
1508
|
+
@if (action.icon) {
|
|
1509
|
+
<dga-icon [name]="action.icon" size="xl" />
|
|
1510
|
+
}
|
|
1511
|
+
@if (!isIconOnly(action)) {
|
|
1512
|
+
<span>{{ action.label }}</span>
|
|
1513
|
+
}
|
|
1514
|
+
@if (action.badge) {
|
|
1515
|
+
<span [class]="badgeClass()">{{ action.badge }}</span>
|
|
1516
|
+
}
|
|
1517
|
+
</a>
|
|
1518
|
+
} @else {
|
|
1519
|
+
<button
|
|
1520
|
+
type="button"
|
|
1521
|
+
[class]="actionClass(action)"
|
|
1522
|
+
[attr.aria-label]="actionAriaLabel(action)"
|
|
1523
|
+
[attr.aria-expanded]="actionExpanded(action)"
|
|
1524
|
+
[attr.aria-controls]="actionControls(action)"
|
|
1525
|
+
[attr.data-dga-action]="action.id"
|
|
1526
|
+
(click)="onAction(action, $event)"
|
|
1527
|
+
>
|
|
1528
|
+
<span
|
|
1529
|
+
aria-hidden="true"
|
|
1530
|
+
[class]="indicatorClass(actionIndicatorActive(action))"
|
|
1531
|
+
></span>
|
|
1532
|
+
@if (isLoginAction(action) && authenticated() && userConfig(); as u) {
|
|
1533
|
+
<dga-avatar [name]="u.name" [src]="u.avatarSrc" size="sm" />
|
|
1534
|
+
<span class="hidden max-w-11xl truncate lg:inline">{{ u.name }}</span>
|
|
1535
|
+
} @else {
|
|
1536
|
+
@if (action.icon) {
|
|
1537
|
+
<dga-icon [name]="action.icon" size="xl" />
|
|
1538
|
+
}
|
|
1539
|
+
@if (!isIconOnly(action)) {
|
|
1540
|
+
<span>{{ action.label }}</span>
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
@if (action.badge) {
|
|
1544
|
+
<span [class]="badgeClass()">{{ action.badge }}</span>
|
|
1545
|
+
}
|
|
1546
|
+
</button>
|
|
1547
|
+
}
|
|
1548
|
+
</dga-tooltip>
|
|
1549
|
+
}
|
|
1550
|
+
<ng-content select="[dgaHeaderEnd]" />
|
|
1551
|
+
</div>
|
|
1552
|
+
</div>
|
|
1553
|
+
|
|
1554
|
+
<!-- Desktop mega / featured -->
|
|
1555
|
+
@if (activeWideDropdown(); as drop) {
|
|
1556
|
+
<div
|
|
1557
|
+
class="absolute start-0 end-0 top-full z-dropdown hidden w-full md:block"
|
|
1558
|
+
role="region"
|
|
1559
|
+
[attr.aria-label]="drop.item.label"
|
|
1560
|
+
[attr.data-variant]="drop.variant"
|
|
1561
|
+
(mouseenter)="onPanelEnter()"
|
|
1562
|
+
>
|
|
1563
|
+
<div
|
|
1564
|
+
class="dga-panel-enter border-b border-border bg-card shadow-lg md:rounded-b-lg"
|
|
1565
|
+
>
|
|
1566
|
+
<div class="w-full px-(--wrapper-padding) py-2xl lg:py-3xl">
|
|
1567
|
+
<div [class]="featuredGridClass(drop.variant, !!drop.item.dropdown!.featured)">
|
|
1568
|
+
<div class="min-w-0">
|
|
1569
|
+
@switch (resolveLayout(drop.item)) {
|
|
1570
|
+
@case ('columns') {
|
|
1571
|
+
<div [class]="columnsGridClass(colCount(drop.item))">
|
|
1572
|
+
@for (
|
|
1573
|
+
col of drop.item.dropdown!.columns!;
|
|
1574
|
+
track col.title ?? $index
|
|
1575
|
+
) {
|
|
1576
|
+
<div class="flex min-w-0 flex-col gap-md">
|
|
1577
|
+
@if (col.title) {
|
|
1578
|
+
<p
|
|
1579
|
+
class="border-b border-border-subtle pb-sm text-body-lg
|
|
1580
|
+
font-medium text-fg-primary"
|
|
1581
|
+
>
|
|
1582
|
+
{{ col.title }}
|
|
1583
|
+
</p>
|
|
1584
|
+
}
|
|
1585
|
+
<ul class="m-0 flex list-none flex-col gap-none p-0" role="list">
|
|
1586
|
+
@for (link of col.links; track link.label) {
|
|
1587
|
+
<li>
|
|
1588
|
+
<a
|
|
1589
|
+
[class]="dropLink"
|
|
1590
|
+
[href]="appHref(link.href || '#')"
|
|
1591
|
+
(click)="onNavLinkClick(link, $event)"
|
|
1592
|
+
>
|
|
1593
|
+
<span>{{ link.label }}</span>
|
|
1594
|
+
@if (link.description) {
|
|
1595
|
+
<span class="text-body-sm text-muted">{{
|
|
1596
|
+
link.description
|
|
1597
|
+
}}</span>
|
|
1598
|
+
}
|
|
1599
|
+
</a>
|
|
1600
|
+
</li>
|
|
1601
|
+
}
|
|
1602
|
+
</ul>
|
|
1603
|
+
</div>
|
|
1604
|
+
}
|
|
1605
|
+
</div>
|
|
1606
|
+
}
|
|
1607
|
+
@case ('rows') {
|
|
1608
|
+
<ul
|
|
1609
|
+
class="m-0 grid w-full list-none grid-cols-1 gap-md p-0
|
|
1610
|
+
sm:grid-cols-2 lg:grid-cols-4"
|
|
1611
|
+
role="list"
|
|
1612
|
+
>
|
|
1613
|
+
@for (link of drop.item.dropdown!.links || []; track link.label) {
|
|
1614
|
+
<li class="min-w-0">
|
|
1615
|
+
<a
|
|
1616
|
+
[class]="dropTile"
|
|
1617
|
+
[href]="appHref(link.href || '#')"
|
|
1618
|
+
(click)="onNavLinkClick(link, $event)"
|
|
1619
|
+
>
|
|
1620
|
+
<span class="text-body-md font-medium text-fg">{{
|
|
1621
|
+
link.label
|
|
1622
|
+
}}</span>
|
|
1623
|
+
@if (link.description) {
|
|
1624
|
+
<span class="text-body-sm text-muted">{{
|
|
1625
|
+
link.description
|
|
1626
|
+
}}</span>
|
|
1627
|
+
}
|
|
1628
|
+
</a>
|
|
1629
|
+
</li>
|
|
1630
|
+
}
|
|
1631
|
+
</ul>
|
|
1632
|
+
}
|
|
1633
|
+
@default {
|
|
1634
|
+
<ul
|
|
1635
|
+
class="m-0 grid w-full max-w-(--container-5xl) list-none grid-cols-1 gap-xs
|
|
1636
|
+
p-0 sm:grid-cols-2 lg:grid-cols-3"
|
|
1637
|
+
role="list"
|
|
1638
|
+
>
|
|
1639
|
+
@for (link of flatLinks(drop.item); track link.label) {
|
|
1640
|
+
<li class="min-w-0">
|
|
1641
|
+
<a
|
|
1642
|
+
[class]="dropLink"
|
|
1643
|
+
[href]="appHref(link.href || '#')"
|
|
1644
|
+
(click)="onNavLinkClick(link, $event)"
|
|
1645
|
+
>
|
|
1646
|
+
<span>{{ link.label }}</span>
|
|
1647
|
+
@if (link.description) {
|
|
1648
|
+
<span class="text-body-sm text-muted">{{
|
|
1649
|
+
link.description
|
|
1650
|
+
}}</span>
|
|
1651
|
+
}
|
|
1652
|
+
</a>
|
|
1653
|
+
</li>
|
|
1654
|
+
}
|
|
1655
|
+
</ul>
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
</div>
|
|
1659
|
+
|
|
1660
|
+
@if (drop.variant === 'featured' && drop.item.dropdown!.featured; as feat) {
|
|
1661
|
+
<aside
|
|
1662
|
+
class="flex min-w-0 flex-col gap-lg overflow-hidden rounded-md
|
|
1663
|
+
border border-border bg-primary-faint p-2xl lg:self-start"
|
|
1664
|
+
>
|
|
1665
|
+
@if (feat.imageUrl) {
|
|
1666
|
+
<img
|
|
1667
|
+
class="aspect-[16/10] h-auto w-full rounded-sm object-cover"
|
|
1668
|
+
[src]="feat.imageUrl"
|
|
1669
|
+
alt=""
|
|
1670
|
+
/>
|
|
1671
|
+
}
|
|
1672
|
+
<div class="flex min-w-0 flex-col gap-md">
|
|
1673
|
+
<p class="text-body-lg font-semibold text-display">{{ feat.title }}</p>
|
|
1674
|
+
@if (feat.description) {
|
|
1675
|
+
<p class="text-body-sm leading-relaxed text-paragraph">
|
|
1676
|
+
{{ feat.description }}
|
|
1677
|
+
</p>
|
|
1678
|
+
}
|
|
1679
|
+
@if (feat.cta) {
|
|
1680
|
+
<a
|
|
1681
|
+
class="mt-xs inline-flex h-5xl cursor-pointer items-center justify-center gap-sm
|
|
1682
|
+
rounded-sm bg-primary px-xl text-body-md font-medium text-on-color
|
|
1683
|
+
transition-opacity hover:opacity-90
|
|
1684
|
+
focus-visible:outline focus-visible:outline-2
|
|
1685
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
1686
|
+
[href]="appHref(feat.href || '#')"
|
|
1687
|
+
>
|
|
1688
|
+
<span>{{ feat.cta }}</span>
|
|
1689
|
+
<dga-icon name="chevronLeft" size="sm" />
|
|
1690
|
+
</a>
|
|
1691
|
+
}
|
|
1692
|
+
</div>
|
|
1693
|
+
</aside>
|
|
1694
|
+
}
|
|
1695
|
+
</div>
|
|
1696
|
+
</div>
|
|
1697
|
+
</div>
|
|
1698
|
+
</div>
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
<!-- Header search popup (dga-modal) -->
|
|
1702
|
+
@if (searchConfig(); as cfg) {
|
|
1703
|
+
<dga-modal
|
|
1704
|
+
class="dga-header-search-modal"
|
|
1705
|
+
[id]="searchPanelId"
|
|
1706
|
+
[open]="searchOpen()"
|
|
1707
|
+
(openChange)="onSearchModalOpenChange($event)"
|
|
1708
|
+
[title]="cfg.title || cfg.submitLabel || 'Search'"
|
|
1709
|
+
[description]="cfg.description || ''"
|
|
1710
|
+
[closeLabel]="cfg.closeLabel || 'Close'"
|
|
1711
|
+
size="lg"
|
|
1712
|
+
animation="scale"
|
|
1713
|
+
[scrollable]="false"
|
|
1714
|
+
(opened)="focusSearchInput()"
|
|
1715
|
+
>
|
|
1716
|
+
<form
|
|
1717
|
+
class="flex flex-col gap-xl"
|
|
1718
|
+
role="search"
|
|
1719
|
+
[attr.aria-label]="cfg.submitLabel || 'Search'"
|
|
1720
|
+
(submit)="onSearchFormSubmit($event)"
|
|
1721
|
+
>
|
|
1722
|
+
<div class="flex w-full flex-col gap-md sm:flex-row sm:items-stretch sm:gap-lg">
|
|
1723
|
+
<div class="min-w-0 flex-1">
|
|
1724
|
+
<dga-form-control size="lg" startIcon="search" [filled]="!!searchQuery()">
|
|
1725
|
+
<input
|
|
1726
|
+
#searchInput
|
|
1727
|
+
type="search"
|
|
1728
|
+
name="q"
|
|
1729
|
+
class="dga-search-input placeholder:text-muted"
|
|
1730
|
+
[placeholder]="cfg.placeholder || 'Search...'"
|
|
1731
|
+
[attr.aria-label]="cfg.placeholder || 'Search...'"
|
|
1732
|
+
[value]="searchQuery()"
|
|
1733
|
+
(input)="searchQuery.set($any($event.target).value)"
|
|
1734
|
+
/>
|
|
1735
|
+
@if (searchQuery()) {
|
|
1736
|
+
<button
|
|
1737
|
+
type="button"
|
|
1738
|
+
dgaEnd
|
|
1739
|
+
[attr.aria-label]="cfg.clearLabel || 'Clear search'"
|
|
1740
|
+
(click)="clearSearchQuery()"
|
|
1741
|
+
>
|
|
1742
|
+
<dga-icon name="close" size="sm" />
|
|
1743
|
+
</button>
|
|
1744
|
+
}
|
|
1745
|
+
@if (cfg.voice !== false) {
|
|
1746
|
+
<button
|
|
1747
|
+
type="button"
|
|
1748
|
+
dgaEnd
|
|
1749
|
+
class="dga-search-voice"
|
|
1750
|
+
[class.dga-search-voice--active]="voiceListening()"
|
|
1751
|
+
[attr.aria-label]="cfg.voiceLabel || 'Voice input'"
|
|
1752
|
+
[attr.aria-pressed]="voiceListening()"
|
|
1753
|
+
(click)="onSearchVoice()"
|
|
1754
|
+
>
|
|
1755
|
+
<dga-icon
|
|
1756
|
+
name="mic"
|
|
1757
|
+
size="sm"
|
|
1758
|
+
[tone]="voiceListening() ? 'current' : 'muted'"
|
|
1759
|
+
/>
|
|
1760
|
+
</button>
|
|
1761
|
+
}
|
|
1762
|
+
</dga-form-control>
|
|
1763
|
+
</div>
|
|
1764
|
+
<button
|
|
1765
|
+
type="submit"
|
|
1766
|
+
class="inline-flex min-h-6xl shrink-0 cursor-pointer items-center justify-center gap-sm
|
|
1767
|
+
rounded-md bg-primary px-xl text-body-md font-medium text-on-color shadow-sm
|
|
1768
|
+
transition-opacity hover:opacity-90
|
|
1769
|
+
focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2
|
|
1770
|
+
focus-visible:outline-focus sm:px-2xl"
|
|
1771
|
+
>
|
|
1772
|
+
<dga-icon name="search" size="md" />
|
|
1773
|
+
<span>{{ cfg.submitLabel || 'Search' }}</span>
|
|
1774
|
+
</button>
|
|
1775
|
+
</div>
|
|
1776
|
+
|
|
1777
|
+
@if (cfg.suggestions?.length) {
|
|
1778
|
+
<div class="flex flex-col gap-md">
|
|
1779
|
+
<span class="text-body-sm font-semibold text-display">
|
|
1780
|
+
{{ cfg.suggestionsLabel || 'Suggestions:' }}
|
|
1781
|
+
</span>
|
|
1782
|
+
<div class="flex flex-wrap gap-sm">
|
|
1783
|
+
@for (item of cfg.suggestions!; track item.value ?? item.label; let i = $index) {
|
|
1784
|
+
<button
|
|
1785
|
+
type="button"
|
|
1786
|
+
class="dga-search-chip inline-flex h-4xl cursor-pointer items-center gap-xs
|
|
1787
|
+
rounded-full border border-border bg-neutral-light px-lg text-body-sm
|
|
1788
|
+
text-paragraph transition-[background-color,transform,border-color]
|
|
1789
|
+
duration-150 ease-out hover:-translate-y-px hover:border-primary
|
|
1790
|
+
hover:bg-sunken
|
|
1791
|
+
focus-visible:outline focus-visible:outline-2
|
|
1792
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
1793
|
+
[style.animation-delay]="i * 40 + 'ms'"
|
|
1794
|
+
(click)="applySearchSuggestion(item)"
|
|
1795
|
+
>
|
|
1796
|
+
<dga-icon [name]="item.icon || 'plus'" size="xs" />
|
|
1797
|
+
<span>{{ item.label }}</span>
|
|
1798
|
+
</button>
|
|
1799
|
+
}
|
|
1800
|
+
</div>
|
|
1801
|
+
</div>
|
|
1802
|
+
}
|
|
1803
|
+
</form>
|
|
1804
|
+
</dga-modal>
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
<!--
|
|
1808
|
+
Utility overlays (notifications / login / user): portaled to body at z-urgent
|
|
1809
|
+
so sticky announcement + chatbot/a11y FABs stay underneath.
|
|
1810
|
+
-->
|
|
1811
|
+
@if (utilityOverlayOpen()) {
|
|
1812
|
+
<div #utilLayer class="dga-header-util-layer">
|
|
1813
|
+
<button
|
|
1814
|
+
type="button"
|
|
1815
|
+
class="dga-util-backdrop absolute inset-0 cursor-default bg-overlay/50"
|
|
1816
|
+
tabindex="-1"
|
|
1817
|
+
aria-label="Close"
|
|
1818
|
+
(click)="closeUtilityOverlays()"
|
|
1819
|
+
></button>
|
|
1820
|
+
|
|
1821
|
+
<!-- Header notifications panel -->
|
|
1822
|
+
@if (notificationsOpen() && notificationsConfig(); as ncfg) {
|
|
1823
|
+
<div
|
|
1824
|
+
[id]="notificationsPanelId"
|
|
1825
|
+
class="dga-header-util-panel fixed w-[min(28rem,calc(100vw-2rem))] max-md:inset-x-3
|
|
1826
|
+
max-md:bottom-3 max-md:top-auto max-md:w-auto"
|
|
1827
|
+
role="region"
|
|
1828
|
+
[attr.aria-label]="ncfg.title || ncfg.viewAllLabel || 'Notifications'"
|
|
1829
|
+
[style]="dropdownPanelStyle()"
|
|
1830
|
+
>
|
|
1831
|
+
<div
|
|
1832
|
+
class="dga-panel-enter dga-panel-enter--anchor-end flex max-h-[min(85svh,40rem)]
|
|
1833
|
+
flex-col overflow-hidden rounded-2xl border border-border bg-card shadow-xl
|
|
1834
|
+
md:max-h-[none] md:rounded-md"
|
|
1835
|
+
>
|
|
1836
|
+
<div
|
|
1837
|
+
class="flex shrink-0 flex-col gap-sm border-b border-border-subtle px-xl py-md
|
|
1838
|
+
md:flex-row md:items-center md:justify-between md:gap-md"
|
|
1839
|
+
>
|
|
1840
|
+
<div class="flex min-w-0 items-center justify-between gap-sm md:justify-start">
|
|
1841
|
+
<div class="flex min-w-0 items-center gap-sm">
|
|
1842
|
+
<h2 class="m-0 truncate text-body-lg font-semibold text-display md:text-body-md">
|
|
1843
|
+
{{ ncfg.title || 'Notifications' }}
|
|
1844
|
+
</h2>
|
|
1845
|
+
@if (unreadNotificationCount() > 0) {
|
|
1846
|
+
<span
|
|
1847
|
+
class="inline-flex min-w-4xl items-center justify-center rounded-full
|
|
1848
|
+
bg-error px-sm py-xxs text-body-2xs font-semibold text-on-color"
|
|
1849
|
+
>
|
|
1850
|
+
{{ unreadNotificationCount() }}
|
|
1851
|
+
</span>
|
|
1852
|
+
}
|
|
1853
|
+
</div>
|
|
1854
|
+
<button
|
|
1855
|
+
type="button"
|
|
1856
|
+
class="inline-flex size-5xl shrink-0 cursor-pointer items-center justify-center
|
|
1857
|
+
rounded-sm text-muted transition-colors hover:bg-neutral-light hover:text-fg
|
|
1858
|
+
focus-visible:outline focus-visible:outline-2
|
|
1859
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus md:hidden"
|
|
1860
|
+
[attr.aria-label]="ncfg.closeLabel || 'Close'"
|
|
1861
|
+
(click)="closeNotifications()"
|
|
1862
|
+
>
|
|
1863
|
+
<dga-icon name="close" size="md" />
|
|
1864
|
+
</button>
|
|
1865
|
+
</div>
|
|
1866
|
+
<div class="flex shrink-0 items-center gap-xxs max-md:justify-stretch">
|
|
1867
|
+
@if (unreadNotificationCount() > 0) {
|
|
1868
|
+
<button
|
|
1869
|
+
type="button"
|
|
1870
|
+
class="inline-flex h-4xl flex-1 cursor-pointer items-center justify-center
|
|
1871
|
+
rounded-sm px-md text-body-sm font-medium text-fg-primary
|
|
1872
|
+
transition-colors hover:bg-primary-faint
|
|
1873
|
+
focus-visible:outline focus-visible:outline-2
|
|
1874
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus
|
|
1875
|
+
md:flex-none"
|
|
1876
|
+
(click)="markAllNotificationsRead()"
|
|
1877
|
+
>
|
|
1878
|
+
{{ ncfg.markAllReadLabel || 'Mark all as read' }}
|
|
1879
|
+
</button>
|
|
1880
|
+
}
|
|
1881
|
+
<button
|
|
1882
|
+
type="button"
|
|
1883
|
+
class="hidden size-5xl cursor-pointer items-center justify-center rounded-sm
|
|
1884
|
+
text-muted transition-colors hover:bg-neutral-light hover:text-fg
|
|
1885
|
+
focus-visible:outline focus-visible:outline-2
|
|
1886
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus md:inline-flex"
|
|
1887
|
+
[attr.aria-label]="ncfg.closeLabel || 'Close'"
|
|
1888
|
+
(click)="closeNotifications()"
|
|
1889
|
+
>
|
|
1890
|
+
<dga-icon name="close" size="md" />
|
|
1891
|
+
</button>
|
|
1892
|
+
</div>
|
|
1893
|
+
</div>
|
|
1894
|
+
|
|
1895
|
+
<div class="min-h-0 flex-1 overflow-y-auto overscroll-contain md:max-h-[min(48svh,28rem)]">
|
|
1896
|
+
@if (visibleNotifications().length === 0) {
|
|
1897
|
+
<div class="flex flex-col items-center gap-md px-xl py-3xl text-center">
|
|
1898
|
+
<span
|
|
1899
|
+
class="inline-flex size-6xl items-center justify-center rounded-full
|
|
1900
|
+
bg-neutral-light text-muted"
|
|
1901
|
+
aria-hidden="true"
|
|
1902
|
+
>
|
|
1903
|
+
<dga-icon name="bell" size="xl" tone="muted" />
|
|
1904
|
+
</span>
|
|
1905
|
+
<p class="m-0 text-body-sm text-muted">
|
|
1906
|
+
{{ ncfg.emptyLabel || 'No notifications' }}
|
|
1907
|
+
</p>
|
|
1908
|
+
</div>
|
|
1909
|
+
} @else {
|
|
1910
|
+
<ul class="m-0 flex list-none flex-col p-0" role="list">
|
|
1911
|
+
@for (item of visibleNotifications(); track item.id) {
|
|
1912
|
+
<li
|
|
1913
|
+
class="border-b border-border-subtle last:border-b-0"
|
|
1914
|
+
[class]="item.read ? 'bg-surface' : 'bg-card'"
|
|
1915
|
+
>
|
|
1916
|
+
<button
|
|
1917
|
+
type="button"
|
|
1918
|
+
class="flex w-full cursor-pointer items-start gap-lg px-xl py-lg text-start
|
|
1919
|
+
transition-colors hover:bg-neutral-light
|
|
1920
|
+
focus-visible:outline focus-visible:outline-2
|
|
1921
|
+
focus-visible:outline-offset-[-2px] focus-visible:outline-focus"
|
|
1922
|
+
[attr.aria-expanded]="expandedNotificationId() === item.id"
|
|
1923
|
+
(click)="toggleNotificationExpand(item)"
|
|
1924
|
+
>
|
|
1925
|
+
<span class="relative mt-xxs shrink-0">
|
|
1926
|
+
<dga-icon-badge size="sm">
|
|
1927
|
+
<dga-icon [name]="item.icon || 'bell'" size="sm" />
|
|
1928
|
+
</dga-icon-badge>
|
|
1929
|
+
@if (!item.read) {
|
|
1930
|
+
<span
|
|
1931
|
+
class="absolute -end-xxs -top-xxs size-[0.5rem] rounded-full bg-primary
|
|
1932
|
+
ring-2 ring-white"
|
|
1933
|
+
aria-hidden="true"
|
|
1934
|
+
></span>
|
|
1935
|
+
}
|
|
1936
|
+
</span>
|
|
1937
|
+
<span class="min-w-0 flex-1">
|
|
1938
|
+
<span class="mb-xs flex flex-wrap items-center gap-sm">
|
|
1939
|
+
@if (item.statusLabel) {
|
|
1940
|
+
<dga-badge [variant]="item.tone || 'neutral'" size="sm">
|
|
1941
|
+
{{ item.statusLabel }}
|
|
1942
|
+
</dga-badge>
|
|
1943
|
+
}
|
|
1944
|
+
<span
|
|
1945
|
+
class="min-w-0 truncate text-body-md text-display"
|
|
1946
|
+
[class.font-semibold]="!item.read"
|
|
1947
|
+
[class.font-medium]="item.read"
|
|
1948
|
+
[class.text-muted]="item.read"
|
|
1949
|
+
>
|
|
1950
|
+
{{ item.title }}
|
|
1951
|
+
</span>
|
|
1952
|
+
</span>
|
|
1953
|
+
<span
|
|
1954
|
+
class="text-body-sm text-paragraph"
|
|
1955
|
+
[class.line-clamp-2]="expandedNotificationId() !== item.id"
|
|
1956
|
+
>
|
|
1957
|
+
{{ item.message }}
|
|
1958
|
+
</span>
|
|
1959
|
+
</span>
|
|
1960
|
+
<dga-icon
|
|
1961
|
+
class="mt-xs shrink-0 text-muted transition-transform duration-200"
|
|
1962
|
+
[class.rotate-180]="expandedNotificationId() === item.id"
|
|
1963
|
+
name="chevronDown"
|
|
1964
|
+
size="sm"
|
|
1965
|
+
/>
|
|
1966
|
+
</button>
|
|
1967
|
+
|
|
1968
|
+
@if (expandedNotificationId() === item.id) {
|
|
1969
|
+
<div
|
|
1970
|
+
class="dga-notif-actions flex flex-wrap gap-sm border-t border-border-subtle
|
|
1971
|
+
bg-surface px-xl py-md"
|
|
1972
|
+
>
|
|
1973
|
+
@if (!item.read) {
|
|
1974
|
+
<button
|
|
1975
|
+
type="button"
|
|
1976
|
+
class="inline-flex h-4xl cursor-pointer items-center gap-xs rounded-sm
|
|
1977
|
+
px-md text-body-sm text-fg transition-colors hover:bg-neutral-light
|
|
1978
|
+
focus-visible:outline focus-visible:outline-2
|
|
1979
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
1980
|
+
(click)="onNotificationAction(item, 'read'); $event.stopPropagation()"
|
|
1981
|
+
>
|
|
1982
|
+
<dga-icon name="success" size="sm" />
|
|
1983
|
+
<span>{{ ncfg.markReadLabel || 'Mark as read' }}</span>
|
|
1984
|
+
</button>
|
|
1985
|
+
}
|
|
1986
|
+
<button
|
|
1987
|
+
type="button"
|
|
1988
|
+
class="inline-flex h-4xl cursor-pointer items-center gap-xs rounded-sm
|
|
1989
|
+
px-md text-body-sm text-fg transition-colors hover:bg-neutral-light
|
|
1990
|
+
focus-visible:outline focus-visible:outline-2
|
|
1991
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
1992
|
+
(click)="onNotificationAction(item, 'view'); $event.stopPropagation()"
|
|
1993
|
+
>
|
|
1994
|
+
<dga-icon name="eye" size="sm" />
|
|
1995
|
+
<span>{{ ncfg.viewLabel || 'View' }}</span>
|
|
1996
|
+
</button>
|
|
1997
|
+
<button
|
|
1998
|
+
type="button"
|
|
1999
|
+
class="inline-flex h-4xl cursor-pointer items-center gap-xs rounded-sm
|
|
2000
|
+
px-md text-body-sm text-fg-error transition-colors hover:bg-error-light
|
|
2001
|
+
focus-visible:outline focus-visible:outline-2
|
|
2002
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
2003
|
+
(click)="onNotificationAction(item, 'dismiss'); $event.stopPropagation()"
|
|
2004
|
+
>
|
|
2005
|
+
<dga-icon name="close" size="sm" />
|
|
2006
|
+
<span>{{ ncfg.dismissLabel || 'Dismiss' }}</span>
|
|
2007
|
+
</button>
|
|
2008
|
+
</div>
|
|
2009
|
+
}
|
|
2010
|
+
</li>
|
|
2011
|
+
}
|
|
2012
|
+
</ul>
|
|
2013
|
+
}
|
|
2014
|
+
</div>
|
|
2015
|
+
|
|
2016
|
+
@if (ncfg.viewAllHref || ncfg.viewAllLabel) {
|
|
2017
|
+
<div
|
|
2018
|
+
class="shrink-0 border-t border-border
|
|
2019
|
+
pb-[max(0px,env(safe-area-inset-bottom))] md:pb-0"
|
|
2020
|
+
>
|
|
2021
|
+
<a
|
|
2022
|
+
class="inline-flex w-full cursor-pointer items-center justify-center gap-sm
|
|
2023
|
+
px-xl py-lg text-body-sm font-medium text-fg-primary
|
|
2024
|
+
transition-colors hover:bg-neutral-light
|
|
2025
|
+
focus-visible:outline focus-visible:outline-2
|
|
2026
|
+
focus-visible:outline-offset-[-2px] focus-visible:outline-focus"
|
|
2027
|
+
[href]="appHref(ncfg.viewAllHref || '#')"
|
|
2028
|
+
(click)="closeNotifications()"
|
|
2029
|
+
>
|
|
2030
|
+
<span>{{ ncfg.viewAllLabel || 'View all notifications' }}</span>
|
|
2031
|
+
<dga-icon name="chevronLeft" size="sm" />
|
|
2032
|
+
</a>
|
|
2033
|
+
</div>
|
|
2034
|
+
}
|
|
2035
|
+
</div>
|
|
2036
|
+
</div>
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
<!-- Header login panel (guest) -->
|
|
2040
|
+
@if (loginOpen() && loginConfig(); as lcfg) {
|
|
2041
|
+
<div
|
|
2042
|
+
[id]="loginPanelId"
|
|
2043
|
+
class="dga-header-util-panel fixed max-md:inset-x-3 max-md:bottom-3 max-md:top-auto
|
|
2044
|
+
max-md:w-auto"
|
|
2045
|
+
role="dialog"
|
|
2046
|
+
[attr.aria-label]="lcfg.title || 'Login'"
|
|
2047
|
+
[style]="loginPanelOuterStyle()"
|
|
2048
|
+
>
|
|
2049
|
+
<div
|
|
2050
|
+
class="dga-panel-enter dga-panel-enter--anchor-end overflow-y-auto overscroll-contain
|
|
2051
|
+
rounded-2xl border border-border bg-card shadow-xl md:overflow-visible
|
|
2052
|
+
md:rounded-md"
|
|
2053
|
+
[style]="loginPanelInnerStyle()"
|
|
2054
|
+
>
|
|
2055
|
+
<div class="flex items-start justify-between gap-md px-2xl pt-2xl max-md:pt-xl">
|
|
2056
|
+
<div class="flex min-w-0 flex-col gap-xs">
|
|
2057
|
+
<h2 class="m-0 text-body-lg font-semibold text-display">
|
|
2058
|
+
{{ lcfg.title || 'Login' }}
|
|
2059
|
+
</h2>
|
|
2060
|
+
<p class="m-0 text-body-sm text-paragraph">
|
|
2061
|
+
{{ lcfg.description || 'Sign in to access your account' }}
|
|
2062
|
+
</p>
|
|
2063
|
+
</div>
|
|
2064
|
+
<button
|
|
2065
|
+
type="button"
|
|
2066
|
+
class="inline-flex size-5xl shrink-0 cursor-pointer items-center justify-center
|
|
2067
|
+
rounded-sm text-muted transition-colors hover:bg-neutral-light hover:text-fg
|
|
2068
|
+
focus-visible:outline focus-visible:outline-2
|
|
2069
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
2070
|
+
[attr.aria-label]="lcfg.closeLabel || lcfg.cancelLabel || 'Close'"
|
|
2071
|
+
(click)="closeLogin()"
|
|
2072
|
+
>
|
|
2073
|
+
<dga-icon name="close" size="md" />
|
|
2074
|
+
</button>
|
|
2075
|
+
</div>
|
|
2076
|
+
|
|
2077
|
+
<ng-content select="[dgaHeaderLoginBeforeForm]" />
|
|
2078
|
+
|
|
2079
|
+
@if (hasCustomLoginForm()) {
|
|
2080
|
+
<div
|
|
2081
|
+
class="px-2xl pb-[max(1.5rem,env(safe-area-inset-bottom))] pt-xl md:pb-2xl"
|
|
2082
|
+
>
|
|
2083
|
+
<ng-content select="[dgaHeaderLoginForm]" />
|
|
2084
|
+
</div>
|
|
2085
|
+
} @else {
|
|
2086
|
+
<form
|
|
2087
|
+
class="flex flex-col gap-xl px-2xl pb-[max(1.5rem,env(safe-area-inset-bottom))]
|
|
2088
|
+
pt-xl md:pb-2xl"
|
|
2089
|
+
(submit)="onLoginSubmit($event)"
|
|
2090
|
+
>
|
|
2091
|
+
<dga-field
|
|
2092
|
+
[label]="lcfg.emailLabel || 'Email'"
|
|
2093
|
+
controlId="dga-header-login-email"
|
|
2094
|
+
[hint]="loginEmailError() ? '' : lcfg.emailHint || ''"
|
|
2095
|
+
[error]="loginEmailError()"
|
|
2096
|
+
required
|
|
2097
|
+
>
|
|
2098
|
+
<dga-form-control startIcon="mail" [filled]="!!loginEmail()">
|
|
2099
|
+
<input
|
|
2100
|
+
id="dga-header-login-email"
|
|
2101
|
+
type="email"
|
|
2102
|
+
name="email"
|
|
2103
|
+
autocomplete="username"
|
|
2104
|
+
required
|
|
2105
|
+
class="placeholder:text-muted"
|
|
2106
|
+
[placeholder]="lcfg.emailPlaceholder || 'name@example.gov.sa'"
|
|
2107
|
+
[value]="loginEmail()"
|
|
2108
|
+
(input)="onLoginEmailInput($any($event.target).value)"
|
|
2109
|
+
/>
|
|
2110
|
+
</dga-form-control>
|
|
2111
|
+
</dga-field>
|
|
2112
|
+
|
|
2113
|
+
<dga-field
|
|
2114
|
+
[label]="lcfg.passwordLabel || 'Password'"
|
|
2115
|
+
controlId="dga-header-login-password"
|
|
2116
|
+
[hint]="loginPasswordError() ? '' : lcfg.passwordHint || ''"
|
|
2117
|
+
[error]="loginPasswordError()"
|
|
2118
|
+
required
|
|
2119
|
+
>
|
|
2120
|
+
<dga-form-control [filled]="!!loginPassword()">
|
|
2121
|
+
<input
|
|
2122
|
+
id="dga-header-login-password"
|
|
2123
|
+
[type]="showLoginPassword() ? 'text' : 'password'"
|
|
2124
|
+
name="password"
|
|
2125
|
+
autocomplete="current-password"
|
|
2126
|
+
required
|
|
2127
|
+
class="placeholder:text-muted"
|
|
2128
|
+
[placeholder]="lcfg.passwordPlaceholder || 'Enter your password'"
|
|
2129
|
+
[value]="loginPassword()"
|
|
2130
|
+
(input)="onLoginPasswordInput($any($event.target).value)"
|
|
2131
|
+
/>
|
|
2132
|
+
<button
|
|
2133
|
+
type="button"
|
|
2134
|
+
dgaEnd
|
|
2135
|
+
[attr.aria-label]="
|
|
2136
|
+
showLoginPassword()
|
|
2137
|
+
? lcfg.hidePasswordLabel || 'Hide password'
|
|
2138
|
+
: lcfg.showPasswordLabel || 'Show password'
|
|
2139
|
+
"
|
|
2140
|
+
(click)="showLoginPassword.set(!showLoginPassword())"
|
|
2141
|
+
>
|
|
2142
|
+
<dga-icon [name]="showLoginPassword() ? 'eyeOff' : 'eye'" size="sm" />
|
|
2143
|
+
</button>
|
|
2144
|
+
</dga-form-control>
|
|
2145
|
+
</dga-field>
|
|
2146
|
+
|
|
2147
|
+
@if (lcfg.forgotPasswordHref || lcfg.forgotPasswordLabel) {
|
|
2148
|
+
<a
|
|
2149
|
+
class="self-start text-body-sm font-medium text-fg-primary transition-opacity
|
|
2150
|
+
hover:opacity-80
|
|
2151
|
+
focus-visible:outline focus-visible:outline-2
|
|
2152
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
2153
|
+
[href]="appHref(lcfg.forgotPasswordHref || '#')"
|
|
2154
|
+
>
|
|
2155
|
+
{{ lcfg.forgotPasswordLabel || 'Forgot password?' }}
|
|
2156
|
+
</a>
|
|
2157
|
+
}
|
|
2158
|
+
|
|
2159
|
+
<ng-content select="[dgaHeaderLoginAfterFields]" />
|
|
2160
|
+
|
|
2161
|
+
@if (loginError() || lcfg.errorMessage) {
|
|
2162
|
+
<p class="m-0 text-body-sm text-fg-error" role="alert">
|
|
2163
|
+
{{ loginError() || lcfg.errorMessage }}
|
|
2164
|
+
</p>
|
|
2165
|
+
}
|
|
2166
|
+
|
|
2167
|
+
<div class="flex flex-col gap-md pt-xs">
|
|
2168
|
+
<button
|
|
2169
|
+
type="submit"
|
|
2170
|
+
class="inline-flex h-5xl w-full cursor-pointer items-center justify-center gap-sm
|
|
2171
|
+
rounded-sm bg-primary px-xl text-body-md font-medium text-on-color shadow-sm
|
|
2172
|
+
transition-opacity hover:opacity-90 disabled:cursor-wait disabled:opacity-60
|
|
2173
|
+
focus-visible:outline focus-visible:outline-2
|
|
2174
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
2175
|
+
[disabled]="loginSubmitting()"
|
|
2176
|
+
>
|
|
2177
|
+
@if (loginSubmitting()) {
|
|
2178
|
+
<span
|
|
2179
|
+
class="dga-login-spinner size-md rounded-full border-2 border-on-color/30
|
|
2180
|
+
border-t-on-color"
|
|
2181
|
+
aria-hidden="true"
|
|
2182
|
+
></span>
|
|
2183
|
+
}
|
|
2184
|
+
<span>
|
|
2185
|
+
{{
|
|
2186
|
+
loginSubmitting()
|
|
2187
|
+
? lcfg.submittingLabel || '…'
|
|
2188
|
+
: lcfg.submitLabel || 'Login'
|
|
2189
|
+
}}
|
|
2190
|
+
</span>
|
|
2191
|
+
</button>
|
|
2192
|
+
@if (lcfg.showCancel !== false) {
|
|
2193
|
+
<button
|
|
2194
|
+
type="button"
|
|
2195
|
+
class="inline-flex h-5xl w-full cursor-pointer items-center justify-center
|
|
2196
|
+
rounded-sm px-xl text-body-md font-medium text-fg transition-colors
|
|
2197
|
+
hover:bg-neutral-light
|
|
2198
|
+
focus-visible:outline focus-visible:outline-2
|
|
2199
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
2200
|
+
(click)="closeLogin()"
|
|
2201
|
+
>
|
|
2202
|
+
{{ lcfg.cancelLabel || 'Cancel' }}
|
|
2203
|
+
</button>
|
|
2204
|
+
}
|
|
2205
|
+
</div>
|
|
2206
|
+
</form>
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
@if (hasCustomLoginFooter()) {
|
|
2210
|
+
<div
|
|
2211
|
+
class="border-t border-border-subtle px-2xl py-xl pb-[max(1.5rem,env(safe-area-inset-bottom))]"
|
|
2212
|
+
>
|
|
2213
|
+
<ng-content select="[dgaHeaderLoginFooter]" />
|
|
2214
|
+
</div>
|
|
2215
|
+
} @else if (showLoginRegisterRow(lcfg) || (lcfg.footerLinks?.length ?? 0) > 0) {
|
|
2216
|
+
<div
|
|
2217
|
+
class="flex flex-col gap-md border-t border-border-subtle px-2xl py-xl
|
|
2218
|
+
pb-[max(1.5rem,env(safe-area-inset-bottom))]"
|
|
2219
|
+
>
|
|
2220
|
+
@if (showLoginRegisterRow(lcfg)) {
|
|
2221
|
+
<p class="m-0 text-center text-body-sm text-muted">
|
|
2222
|
+
{{ lcfg.registerPrompt || "Don't have an account?" }}
|
|
2223
|
+
@if (lcfg.registerLabel || lcfg.registerHref) {
|
|
2224
|
+
<a
|
|
2225
|
+
class="ms-xs font-medium text-fg-primary transition-opacity hover:opacity-80
|
|
2226
|
+
focus-visible:outline focus-visible:outline-2
|
|
2227
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
2228
|
+
[href]="appHref(lcfg.registerHref || '#')"
|
|
2229
|
+
>
|
|
2230
|
+
{{ lcfg.registerLabel || 'Sign up' }}
|
|
2231
|
+
</a>
|
|
2232
|
+
}
|
|
2233
|
+
</p>
|
|
2234
|
+
}
|
|
2235
|
+
@if (lcfg.footerLinks?.length) {
|
|
2236
|
+
<div class="flex flex-col gap-xs">
|
|
2237
|
+
@for (link of lcfg.footerLinks; track link.id ?? link.label) {
|
|
2238
|
+
<a
|
|
2239
|
+
class="text-center text-body-sm font-medium text-fg-primary transition-opacity
|
|
2240
|
+
hover:opacity-80
|
|
2241
|
+
focus-visible:outline focus-visible:outline-2
|
|
2242
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
2243
|
+
[href]="appHref(link.href || '#')"
|
|
2244
|
+
>
|
|
2245
|
+
{{ link.label }}
|
|
2246
|
+
</a>
|
|
2247
|
+
}
|
|
2248
|
+
</div>
|
|
2249
|
+
}
|
|
2250
|
+
</div>
|
|
2251
|
+
}
|
|
2252
|
+
</div>
|
|
2253
|
+
</div>
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
<!-- Header user menu (authenticated) -->
|
|
2257
|
+
@if (userMenuOpen() && userConfig(); as ucfg) {
|
|
2258
|
+
<div
|
|
2259
|
+
[id]="userPanelId"
|
|
2260
|
+
class="dga-header-util-panel fixed w-[min(22rem,calc(100vw-2rem))] max-md:inset-x-3
|
|
2261
|
+
max-md:bottom-3 max-md:top-auto max-md:w-auto"
|
|
2262
|
+
role="menu"
|
|
2263
|
+
[attr.aria-label]="ucfg.name"
|
|
2264
|
+
[style]="dropdownPanelStyle()"
|
|
2265
|
+
>
|
|
2266
|
+
<div
|
|
2267
|
+
class="dga-panel-enter dga-panel-enter--anchor-end max-h-[min(85svh,36rem)]
|
|
2268
|
+
overflow-y-auto overscroll-contain rounded-2xl border border-border bg-card
|
|
2269
|
+
shadow-xl md:max-h-[none] md:overflow-visible md:rounded-md"
|
|
2270
|
+
>
|
|
2271
|
+
<div class="flex items-center gap-lg border-b border-border-subtle px-xl py-lg">
|
|
2272
|
+
<dga-avatar [name]="ucfg.name" [src]="ucfg.avatarSrc" size="md" />
|
|
2273
|
+
<div class="flex min-w-0 flex-1 flex-col gap-xxs">
|
|
2274
|
+
<span class="truncate text-body-md font-semibold text-display">{{ ucfg.name }}</span>
|
|
2275
|
+
@if (ucfg.role) {
|
|
2276
|
+
<span class="truncate text-body-sm text-muted">{{ ucfg.role }}</span>
|
|
2277
|
+
}
|
|
2278
|
+
@if (ucfg.email) {
|
|
2279
|
+
<span class="truncate text-body-sm text-paragraph">{{ ucfg.email }}</span>
|
|
2280
|
+
}
|
|
2281
|
+
</div>
|
|
2282
|
+
<button
|
|
2283
|
+
type="button"
|
|
2284
|
+
class="inline-flex size-5xl shrink-0 cursor-pointer items-center justify-center
|
|
2285
|
+
rounded-sm text-muted transition-colors hover:bg-neutral-light hover:text-fg
|
|
2286
|
+
focus-visible:outline focus-visible:outline-2
|
|
2287
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
2288
|
+
aria-label="Close"
|
|
2289
|
+
(click)="closeUserMenu()"
|
|
2290
|
+
>
|
|
2291
|
+
<dga-icon name="close" size="md" />
|
|
2292
|
+
</button>
|
|
2293
|
+
</div>
|
|
2294
|
+
<div class="flex flex-col gap-xxs p-sm">
|
|
2295
|
+
@for (link of ucfg.links || []; track link.id) {
|
|
2296
|
+
@if (link.id === 'logout') {
|
|
2297
|
+
<div class="my-xs border-t border-border-subtle" role="separator"></div>
|
|
2298
|
+
<button
|
|
2299
|
+
type="button"
|
|
2300
|
+
role="menuitem"
|
|
2301
|
+
class="flex w-full cursor-pointer items-center gap-md rounded-sm px-lg py-sm
|
|
2302
|
+
text-start text-body-md text-fg-error transition-colors hover:bg-error-light
|
|
2303
|
+
focus-visible:outline focus-visible:outline-2
|
|
2304
|
+
focus-visible:outline-offset-[-2px] focus-visible:outline-focus"
|
|
2305
|
+
(click)="onUserLink(link)"
|
|
2306
|
+
>
|
|
2307
|
+
@if (link.icon) {
|
|
2308
|
+
<dga-icon [name]="link.icon" size="md" />
|
|
2309
|
+
}
|
|
2310
|
+
<span>{{ link.label }}</span>
|
|
2311
|
+
</button>
|
|
2312
|
+
} @else if (link.href) {
|
|
2313
|
+
<a
|
|
2314
|
+
role="menuitem"
|
|
2315
|
+
class="flex w-full cursor-pointer items-center gap-md rounded-sm px-lg py-sm
|
|
2316
|
+
text-start text-body-md text-fg transition-colors hover:bg-neutral-light
|
|
2317
|
+
focus-visible:outline focus-visible:outline-2
|
|
2318
|
+
focus-visible:outline-offset-[-2px] focus-visible:outline-focus"
|
|
2319
|
+
[href]="appHref(link.href)"
|
|
2320
|
+
(click)="onUserLink(link)"
|
|
2321
|
+
>
|
|
2322
|
+
@if (link.icon) {
|
|
2323
|
+
<dga-icon [name]="link.icon" size="md" />
|
|
2324
|
+
}
|
|
2325
|
+
<span>{{ link.label }}</span>
|
|
2326
|
+
</a>
|
|
2327
|
+
} @else {
|
|
2328
|
+
<button
|
|
2329
|
+
type="button"
|
|
2330
|
+
role="menuitem"
|
|
2331
|
+
class="flex w-full cursor-pointer items-center gap-md rounded-sm px-lg py-sm
|
|
2332
|
+
text-start text-body-md text-fg transition-colors hover:bg-neutral-light
|
|
2333
|
+
focus-visible:outline focus-visible:outline-2
|
|
2334
|
+
focus-visible:outline-offset-[-2px] focus-visible:outline-focus"
|
|
2335
|
+
(click)="onUserLink(link)"
|
|
2336
|
+
>
|
|
2337
|
+
@if (link.icon) {
|
|
2338
|
+
<dga-icon [name]="link.icon" size="md" />
|
|
2339
|
+
}
|
|
2340
|
+
<span>{{ link.label }}</span>
|
|
2341
|
+
</button>
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
</div>
|
|
2345
|
+
</div>
|
|
2346
|
+
</div>
|
|
2347
|
+
}
|
|
2348
|
+
</div>
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
<!-- Mobile navigation: sheet | fullscreen | push -->
|
|
2352
|
+
@if (isPortal() && items().length) {
|
|
2353
|
+
@if (mobileOpen() && mobileNav() !== 'push') {
|
|
2354
|
+
<button
|
|
2355
|
+
type="button"
|
|
2356
|
+
class="fixed inset-0 cursor-default md:hidden"
|
|
2357
|
+
[class]="
|
|
2358
|
+
mobileNav() === 'fullscreen'
|
|
2359
|
+
? 'z-[35] bg-overlay/60 backdrop-blur-[3px]'
|
|
2360
|
+
: 'z-10 bg-overlay/40 backdrop-blur-[1px]'
|
|
2361
|
+
"
|
|
2362
|
+
tabindex="-1"
|
|
2363
|
+
[attr.aria-label]="menuCloseLabel()"
|
|
2364
|
+
(click)="closeAll()"
|
|
2365
|
+
></button>
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2368
|
+
<div
|
|
2369
|
+
[id]="collapseId"
|
|
2370
|
+
[class]="mobilePanelClass()"
|
|
2371
|
+
[attr.data-mobile-nav]="mobileNav()"
|
|
2372
|
+
[attr.aria-hidden]="!mobileOpen()"
|
|
2373
|
+
[attr.inert]="mobileOpen() ? null : ''"
|
|
2374
|
+
>
|
|
2375
|
+
@if (mobileNav() === 'fullscreen') {
|
|
2376
|
+
<div
|
|
2377
|
+
class="flex h-(--size-header-portal) shrink-0 items-center justify-between
|
|
2378
|
+
gap-lg border-b border-border px-xl"
|
|
2379
|
+
>
|
|
2380
|
+
<div class="flex min-w-0 items-center gap-lg">
|
|
2381
|
+
@if (brandLogo()) {
|
|
2382
|
+
<img
|
|
2383
|
+
class="h-5xl w-auto max-w-[10rem] shrink-0 object-contain"
|
|
2384
|
+
[src]="brandLogo()"
|
|
2385
|
+
[alt]="brandLogoAlt()"
|
|
2386
|
+
/>
|
|
2387
|
+
} @else {
|
|
2388
|
+
<span class="truncate text-body-md font-semibold text-display">{{
|
|
2389
|
+
brand() || brandLogoAlt() || navLabel()
|
|
2390
|
+
}}</span>
|
|
2391
|
+
}
|
|
2392
|
+
</div>
|
|
2393
|
+
<button
|
|
2394
|
+
type="button"
|
|
2395
|
+
class="inline-flex size-6xl shrink-0 cursor-pointer items-center justify-center
|
|
2396
|
+
rounded-md text-fg transition-colors hover:bg-neutral-light
|
|
2397
|
+
focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2
|
|
2398
|
+
focus-visible:outline-focus"
|
|
2399
|
+
[attr.aria-label]="menuCloseLabel()"
|
|
2400
|
+
(click)="closeAll()"
|
|
2401
|
+
>
|
|
2402
|
+
<dga-icon name="close" size="xl" />
|
|
2403
|
+
</button>
|
|
2404
|
+
</div>
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
@if (mobileNav() === 'sheet') {
|
|
2408
|
+
<div
|
|
2409
|
+
class="flex min-h-(--size-header-portal) shrink-0 items-center justify-end
|
|
2410
|
+
border-b border-border-subtle px-md
|
|
2411
|
+
pt-[env(safe-area-inset-top,0px)]"
|
|
2412
|
+
>
|
|
2413
|
+
<button
|
|
2414
|
+
type="button"
|
|
2415
|
+
class="inline-flex size-6xl shrink-0 cursor-pointer items-center justify-center
|
|
2416
|
+
rounded-md text-fg transition-colors hover:bg-neutral-light
|
|
2417
|
+
focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2
|
|
2418
|
+
focus-visible:outline-focus"
|
|
2419
|
+
[attr.aria-label]="menuCloseLabel()"
|
|
2420
|
+
(click)="closeAll()"
|
|
2421
|
+
>
|
|
2422
|
+
<dga-icon name="close" size="xl" />
|
|
2423
|
+
</button>
|
|
2424
|
+
</div>
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
@if (mobileNav() === 'push') {
|
|
2428
|
+
<div class="border-b border-border-subtle px-xl py-md">
|
|
2429
|
+
<p class="m-0 text-body-sm font-medium text-muted">{{ navLabel() }}</p>
|
|
2430
|
+
</div>
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2433
|
+
<div
|
|
2434
|
+
class="min-h-0 flex-1 overflow-y-auto overscroll-contain px-xl py-lg
|
|
2435
|
+
pb-[max(1rem,env(safe-area-inset-bottom))]"
|
|
2436
|
+
>
|
|
2437
|
+
<ul class="m-0 flex list-none flex-col gap-none p-0" role="list">
|
|
2438
|
+
@for (item of items(); track item.label; let i = $index) {
|
|
2439
|
+
<li class="border-b border-border-subtle last:border-b-0">
|
|
2440
|
+
@if (item.dropdown) {
|
|
2441
|
+
<button
|
|
2442
|
+
type="button"
|
|
2443
|
+
[class]="mobileItemClass(!!item.current, openDropdown() === i)"
|
|
2444
|
+
[attr.aria-expanded]="openDropdown() === i"
|
|
2445
|
+
(click)="toggleDropdown(i, $event)"
|
|
2446
|
+
>
|
|
2447
|
+
<span class="min-w-0 flex-1" [class]="item.current ? 'text-fg-primary' : ''">{{
|
|
2448
|
+
item.label
|
|
2449
|
+
}}</span>
|
|
2450
|
+
<dga-icon
|
|
2451
|
+
name="chevronDown"
|
|
2452
|
+
size="md"
|
|
2453
|
+
class="shrink-0"
|
|
2454
|
+
[class]="
|
|
2455
|
+
openDropdown() === i
|
|
2456
|
+
? 'rotate-180 text-fg-primary transition-transform duration-200'
|
|
2457
|
+
: 'text-muted transition-transform duration-200'
|
|
2458
|
+
"
|
|
2459
|
+
/>
|
|
2460
|
+
</button>
|
|
2461
|
+
|
|
2462
|
+
@if (openDropdown() === i) {
|
|
2463
|
+
<div
|
|
2464
|
+
class="dga-panel-enter space-y-md border-s-2 border-primary/30 pb-lg ps-lg
|
|
2465
|
+
ms-sm"
|
|
2466
|
+
>
|
|
2467
|
+
@if (item.dropdown.featured; as feat) {
|
|
2468
|
+
<a
|
|
2469
|
+
class="flex flex-col gap-sm rounded-md border border-border
|
|
2470
|
+
bg-primary-faint p-xl text-start no-underline"
|
|
2471
|
+
[href]="appHref(feat.href || '#')"
|
|
2472
|
+
(click)="closeAll()"
|
|
2473
|
+
>
|
|
2474
|
+
<span class="text-body-md font-semibold text-display">{{
|
|
2475
|
+
feat.title
|
|
2476
|
+
}}</span>
|
|
2477
|
+
@if (feat.description) {
|
|
2478
|
+
<span class="text-body-sm text-paragraph">{{
|
|
2479
|
+
feat.description
|
|
2480
|
+
}}</span>
|
|
2481
|
+
}
|
|
2482
|
+
@if (feat.cta) {
|
|
2483
|
+
<span class="text-body-sm font-medium text-fg-primary">{{
|
|
2484
|
+
feat.cta
|
|
2485
|
+
}}</span>
|
|
2486
|
+
}
|
|
2487
|
+
</a>
|
|
2488
|
+
}
|
|
2489
|
+
|
|
2490
|
+
@if (item.dropdown.columns?.length) {
|
|
2491
|
+
@for (col of item.dropdown.columns!; track col.title ?? $index) {
|
|
2492
|
+
<div class="flex flex-col gap-xs">
|
|
2493
|
+
@if (col.title) {
|
|
2494
|
+
<p class="px-xl text-body-sm font-medium text-fg-primary">
|
|
2495
|
+
{{ col.title }}
|
|
2496
|
+
</p>
|
|
2497
|
+
}
|
|
2498
|
+
<ul class="m-0 flex list-none flex-col gap-none p-0">
|
|
2499
|
+
@for (link of col.links; track link.label) {
|
|
2500
|
+
<li>
|
|
2501
|
+
<a
|
|
2502
|
+
[class]="mobileLink"
|
|
2503
|
+
[href]="appHref(link.href || '#')"
|
|
2504
|
+
(click)="onNavLinkClick(link, $event); closeAll()"
|
|
2505
|
+
>
|
|
2506
|
+
<span>{{ link.label }}</span>
|
|
2507
|
+
@if (link.description) {
|
|
2508
|
+
<span class="text-body-sm text-muted">{{
|
|
2509
|
+
link.description
|
|
2510
|
+
}}</span>
|
|
2511
|
+
}
|
|
2512
|
+
</a>
|
|
2513
|
+
</li>
|
|
2514
|
+
}
|
|
2515
|
+
</ul>
|
|
2516
|
+
</div>
|
|
2517
|
+
}
|
|
2518
|
+
} @else {
|
|
2519
|
+
<ul class="m-0 flex list-none flex-col gap-none p-0">
|
|
2520
|
+
@for (link of flatLinks(item); track link.label) {
|
|
2521
|
+
<li>
|
|
2522
|
+
<a
|
|
2523
|
+
[class]="mobileLink"
|
|
2524
|
+
[href]="appHref(link.href || '#')"
|
|
2525
|
+
(click)="onNavLinkClick(link, $event); closeAll()"
|
|
2526
|
+
>
|
|
2527
|
+
<span>{{ link.label }}</span>
|
|
2528
|
+
@if (link.description) {
|
|
2529
|
+
<span class="text-body-sm text-muted">{{
|
|
2530
|
+
link.description
|
|
2531
|
+
}}</span>
|
|
2532
|
+
}
|
|
2533
|
+
</a>
|
|
2534
|
+
</li>
|
|
2535
|
+
}
|
|
2536
|
+
</ul>
|
|
2537
|
+
}
|
|
2538
|
+
</div>
|
|
2539
|
+
}
|
|
2540
|
+
} @else {
|
|
2541
|
+
<a
|
|
2542
|
+
[class]="mobileItemClass(!!item.current)"
|
|
2543
|
+
[attr.aria-current]="item.current ? 'page' : null"
|
|
2544
|
+
[href]="appHref(item.href || '#')"
|
|
2545
|
+
(click)="onNavLinkClick(item, $event); closeAll()"
|
|
2546
|
+
>
|
|
2547
|
+
@if (item.current) {
|
|
2548
|
+
<span
|
|
2549
|
+
class="absolute inset-y-md start-0 w-1 rounded-e-sm bg-primary"
|
|
2550
|
+
aria-hidden="true"
|
|
2551
|
+
></span>
|
|
2552
|
+
}
|
|
2553
|
+
<span class="min-w-0 flex-1" [class]="item.current ? 'text-fg-primary' : ''">{{
|
|
2554
|
+
item.label
|
|
2555
|
+
}}</span>
|
|
2556
|
+
</a>
|
|
2557
|
+
}
|
|
2558
|
+
</li>
|
|
2559
|
+
}
|
|
2560
|
+
</ul>
|
|
2561
|
+
</div>
|
|
2562
|
+
|
|
2563
|
+
@if (actions().length) {
|
|
2564
|
+
<div
|
|
2565
|
+
class="flex shrink-0 items-center justify-around gap-sm border-t border-border
|
|
2566
|
+
bg-nav px-xl py-md pb-[max(0.75rem,env(safe-area-inset-bottom))]"
|
|
2567
|
+
>
|
|
2568
|
+
@for (action of actions(); track action.id) {
|
|
2569
|
+
@if (action.href) {
|
|
2570
|
+
<a
|
|
2571
|
+
class="relative inline-flex min-h-6xl min-w-6xl cursor-pointer flex-col
|
|
2572
|
+
items-center justify-center gap-xxs rounded-md px-md text-fg
|
|
2573
|
+
hover:bg-neutral-light
|
|
2574
|
+
focus-visible:outline focus-visible:outline-2
|
|
2575
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
2576
|
+
[href]="appHref(action.href)"
|
|
2577
|
+
[attr.aria-label]="action.label"
|
|
2578
|
+
[attr.data-dga-action]="action.id"
|
|
2579
|
+
(click)="closeAll()"
|
|
2580
|
+
>
|
|
2581
|
+
@if (action.icon) {
|
|
2582
|
+
<dga-icon [name]="action.icon" size="xl" />
|
|
2583
|
+
}
|
|
2584
|
+
<span class="max-w-11xl truncate text-body-2xs">{{ action.label }}</span>
|
|
2585
|
+
@if (action.badge) {
|
|
2586
|
+
<span [class]="badgeClass()">{{ action.badge }}</span>
|
|
2587
|
+
}
|
|
2588
|
+
</a>
|
|
2589
|
+
} @else {
|
|
2590
|
+
<button
|
|
2591
|
+
type="button"
|
|
2592
|
+
class="relative inline-flex min-h-6xl min-w-6xl cursor-pointer flex-col
|
|
2593
|
+
items-center justify-center gap-xxs rounded-md px-md text-fg
|
|
2594
|
+
hover:bg-neutral-light
|
|
2595
|
+
focus-visible:outline focus-visible:outline-2
|
|
2596
|
+
focus-visible:outline-offset-2 focus-visible:outline-focus"
|
|
2597
|
+
[attr.aria-label]="action.label"
|
|
2598
|
+
[attr.data-dga-action]="action.id"
|
|
2599
|
+
(click)="onMobileAction(action, $event)"
|
|
2600
|
+
>
|
|
2601
|
+
@if (action.icon) {
|
|
2602
|
+
<dga-icon [name]="action.icon" size="xl" />
|
|
2603
|
+
}
|
|
2604
|
+
<span class="max-w-11xl truncate text-body-2xs">{{ action.label }}</span>
|
|
2605
|
+
@if (action.badge) {
|
|
2606
|
+
<span [class]="badgeClass()">{{ action.badge }}</span>
|
|
2607
|
+
}
|
|
2608
|
+
</button>
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
</div>
|
|
2612
|
+
}
|
|
2613
|
+
</div>
|
|
2614
|
+
}
|
|
2615
|
+
`,host:{role:"banner","[class]":"hostClasses()","[attr.data-appearance]":"appearance()","[attr.data-mobile-nav]":"mobileNav()","[attr.data-mobile-open]":"mobileOpen() || null","(mouseleave)":"onHostLeave($event)"},styles:["@keyframes dga-fade-in{0%{opacity:0}to{opacity:1}}@keyframes dga-panel-in{0%{opacity:0;transform:translateY(-.625rem) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes dga-chip-in{0%{opacity:0;transform:translateY(.25rem)}to{opacity:1;transform:translateY(0)}}@keyframes dga-notif-row-in{0%{opacity:0;transform:translateY(.35rem)}to{opacity:1;transform:translateY(0)}}@keyframes dga-expand-fade{0%{opacity:0;transform:translateY(-.25rem)}to{opacity:1;transform:translateY(0)}}@keyframes dga-spin{to{transform:rotate(360deg)}}@keyframes dga-badge-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.12)}}@keyframes dga-push-in{0%{opacity:0;transform:translateY(-.75rem)}to{opacity:1;transform:translateY(0)}}@keyframes dga-sheet-in-ltr{0%{opacity:.85;transform:translate3d(-100%,0,0)}to{opacity:1;transform:translateZ(0)}}@keyframes dga-sheet-in-rtl{0%{opacity:.85;transform:translate3d(100%,0,0)}to{opacity:1;transform:translateZ(0)}}@keyframes dga-fs-in{0%{opacity:0;transform:translateY(.5rem)}to{opacity:1;transform:translateY(0)}}@keyframes dga-sheet-in{0%{opacity:0;transform:translateY(1.25rem)}to{opacity:1;transform:translateY(0)}}:host .dga-util-backdrop,.dga-header-util-layer .dga-util-backdrop{animation:dga-fade-in .22s ease both}.dga-header-util-layer{position:fixed;inset:0;z-index:var(--z-index-urgent, 400);pointer-events:none}.dga-header-util-layer>.dga-util-backdrop,.dga-header-util-layer>.dga-header-util-panel{pointer-events:auto}:host .dga-panel-enter,.dga-header-util-layer .dga-panel-enter{animation:dga-panel-in .28s cubic-bezier(.16,1,.3,1) both;transform-origin:top center;will-change:transform,opacity}:host .dga-panel-enter--anchor-end,.dga-header-util-layer .dga-panel-enter--anchor-end{transform-origin:top right}:host-context([dir=\"rtl\"]) .dga-panel-enter--anchor-end,:host([dir=\"rtl\"]) .dga-panel-enter--anchor-end,:host-context([dir=\"rtl\"]) .dga-header-util-layer .dga-panel-enter--anchor-end,[dir=rtl] .dga-header-util-layer .dga-panel-enter--anchor-end{transform-origin:top left}@media(max-width:767px){:host .dga-panel-enter--anchor-end,.dga-header-util-layer .dga-panel-enter--anchor-end{animation-name:dga-sheet-in;transform-origin:bottom center}}:host .dga-search-chip{animation:dga-chip-in .28s cubic-bezier(.16,1,.3,1) both}:host .dga-search-input{-webkit-appearance:none;appearance:none}:host .dga-search-input::-webkit-search-decoration,:host .dga-search-input::-webkit-search-cancel-button,:host .dga-search-input::-webkit-search-results-button,:host .dga-search-input::-webkit-search-results-decoration{-webkit-appearance:none;appearance:none;display:none}:host .dga-search-voice.dga-search-voice--active{color:var(--dga-text-primary, #1b8354)!important;background:var(--dga-bg-primary-faint, #f3faf6)!important}:host .dga-notif-item,.dga-header-util-layer .dga-notif-item{animation:dga-notif-row-in .26s cubic-bezier(.16,1,.3,1) both}:host .dga-notif-actions,.dga-header-util-layer .dga-notif-actions{animation:dga-expand-fade .2s ease both}:host .dga-login-spinner,.dga-header-util-layer .dga-login-spinner{animation:dga-spin .7s linear infinite}:host .dga-action-badge{animation:dga-badge-pulse 1.8s ease-in-out infinite;transform-origin:center}@media(prefers-reduced-motion:reduce){:host .dga-util-backdrop,:host .dga-panel-enter,:host .dga-search-chip,:host .dga-notif-item,:host .dga-notif-actions,.dga-header-util-layer .dga-util-backdrop,.dga-header-util-layer .dga-panel-enter{animation-duration:.01ms!important;animation-delay:0ms!important}}:host .dga-burger__box{position:relative;display:block;width:1.375rem;height:1rem}:host .dga-burger__line{position:absolute;inset-inline:0;height:2px;border-radius:1px;background:currentColor;transition:transform .22s cubic-bezier(.4,0,.2,1),opacity .16s ease,top .22s cubic-bezier(.4,0,.2,1)}:host .dga-burger__line:nth-child(1){top:0}:host .dga-burger__line:nth-child(2){top:calc(50% - 1px)}:host .dga-burger__line:nth-child(3){top:calc(100% - 2px)}:host .dga-burger--open{background:var(--color-neutral-light, #f3f4f6)}:host .dga-burger--hidden{visibility:hidden;pointer-events:none}:host .dga-burger--open .dga-burger__line:nth-child(1){top:calc(50% - 1px);transform:rotate(45deg)}:host .dga-burger--open .dga-burger__line:nth-child(2){opacity:0;transform:scaleX(.4)}:host .dga-burger--open .dga-burger__line:nth-child(3){top:calc(50% - 1px);transform:rotate(-45deg)}:host .dga-mobile-nav-closed{display:none}:host .dga-mobile-nav-open{display:flex}:host .dga-mobile-push-open{animation:dga-push-in .24s cubic-bezier(.4,0,.2,1) forwards}:host .dga-mobile-sheet-open{animation:dga-sheet-in-rtl .28s cubic-bezier(.4,0,.2,1) forwards}:host-context([dir=\"rtl\"]) .dga-mobile-sheet-open{animation:dga-sheet-in-ltr .28s cubic-bezier(.4,0,.2,1) forwards}:host .dga-mobile-fs-open{animation:dga-fs-in .24s cubic-bezier(.4,0,.2,1) forwards}@media(prefers-reduced-motion:reduce){:host .dga-action-badge,:host .dga-mobile-push-open,:host .dga-mobile-sheet-open,:host .dga-mobile-fs-open,:host-context([dir=\"rtl\"]) .dga-mobile-sheet-open,:host .dga-burger__line{animation:none;transition:none}}\n"]}]}],ctorParameters:()=>[],propDecorators:{brand:[{type:i.Input,args:[{isSignal:!0,alias:"brand",required:!1}]}],brandSlogan:[{type:i.Input,args:[{isSignal:!0,alias:"brandSlogan",required:!1}]}],brandLogo:[{type:i.Input,args:[{isSignal:!0,alias:"brandLogo",required:!1}]}],brandLogoAlt:[{type:i.Input,args:[{isSignal:!0,alias:"brandLogoAlt",required:!1}]}],brandPlaceholder:[{type:i.Input,args:[{isSignal:!0,alias:"brandPlaceholder",required:!1}]}],brandHref:[{type:i.Input,args:[{isSignal:!0,alias:"brandHref",required:!1}]}],navLabel:[{type:i.Input,args:[{isSignal:!0,alias:"navLabel",required:!1}]}],menuToggleLabel:[{type:i.Input,args:[{isSignal:!0,alias:"menuToggleLabel",required:!1}]}],menuCloseLabel:[{type:i.Input,args:[{isSignal:!0,alias:"menuCloseLabel",required:!1}]}],appearance:[{type:i.Input,args:[{isSignal:!0,alias:"appearance",required:!1}]}],mobileNav:[{type:i.Input,args:[{isSignal:!0,alias:"mobileNav",required:!1}]}],sticky:[{type:i.Input,args:[{isSignal:!0,alias:"sticky",required:!1}]}],items:[{type:i.Input,args:[{isSignal:!0,alias:"items",required:!1}]}],actions:[{type:i.Input,args:[{isSignal:!0,alias:"actions",required:!1}]}],search:[{type:i.Input,args:[{isSignal:!0,alias:"search",required:!1}]}],searchQuery:[{type:i.Input,args:[{isSignal:!0,alias:"searchQuery",required:!1}]},{type:i.Output,args:["searchQueryChange"]}],notifications:[{type:i.Input,args:[{isSignal:!0,alias:"notifications",required:!1}]}],login:[{type:i.Input,args:[{isSignal:!0,alias:"login",required:!1}]}],user:[{type:i.Input,args:[{isSignal:!0,alias:"user",required:!1}]}],authenticated:[{type:i.Input,args:[{isSignal:!0,alias:"authenticated",required:!1}]},{type:i.Output,args:["authenticatedChange"]}],loginSubmitting:[{type:i.Input,args:[{isSignal:!0,alias:"loginSubmitting",required:!1}]},{type:i.Output,args:["loginSubmittingChange"]}],loginError:[{type:i.Input,args:[{isSignal:!0,alias:"loginError",required:!1}]},{type:i.Output,args:["loginErrorChange"]}],actionClick:[{type:i.Output,args:["actionClick"]}],searchSubmit:[{type:i.Output,args:["searchSubmit"]}],searchSuggestionSelect:[{type:i.Output,args:["searchSuggestionSelect"]}],searchVoice:[{type:i.Output,args:["searchVoice"]}],notificationAction:[{type:i.Output,args:["notificationAction"]}],loginSubmit:[{type:i.Output,args:["loginSubmit"]}],logout:[{type:i.Output,args:["logout"]}],userLinkClick:[{type:i.Output,args:["userLinkClick"]}],navLinkClick:[{type:i.Output,args:["navLinkClick"]}],customLoginForm:[{type:i.ContentChild,args:[i.forwardRef(()=>m),{isSignal:!0}]}],customLoginFooter:[{type:i.ContentChild,args:[i.forwardRef(()=>p),{isSignal:!0}]}],searchInputRef:[{type:i.ViewChild,args:["searchInput",{isSignal:!0}]}],utilLayerRef:[{type:i.ViewChild,args:["utilLayer",{isSignal:!0}]}],onCloseHeaderOverlays:[{type:b,args:["document:dga-close-header-overlays"]}],onKey:[{type:b,args:["document:keydown",["$event"]]}],onScroll:[{type:b,args:["window:scroll"]}],onResize:[{type:b,args:["window:resize"]}],onDocClick:[{type:b,args:["document:click",["$event"]]}]}});export{v as DgaHeader,x as DgaHeaderLoginAfterFields,h as DgaHeaderLoginBeforeForm,p as DgaHeaderLoginFooter,m as DgaHeaderLoginForm};
|