@oslokommune/punkt-elements
Version:
Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo
148 lines (135 loc) • 5.63 kB
text/typescript
import { PktElementWithSlot } from '@/base-elements/element-with-slot'
import { slotContent } from '@/directives/slot-content'
import { html, nothing, PropertyValues } from 'lit'
import { customElement, property } from 'lit/decorators.js'
import { ifDefined } from 'lit/directives/if-defined.js'
import {
User,
Representing,
UserMenuItem,
THeaderMenu,
TLogOutButtonPlacement,
THeaderPosition,
THeaderScrollBehavior,
TSlotMenuVariant,
IPktHeader,
Booleanish,
booleanishConverter,
} from './types'
import './header-service'
/**
* PktHeader - Main header component for Oslo kommune services
*
* This component provides a complete header solution with:
* - Logo and service name
* - User menu with login/logout functionality
* - Search functionality
* - Responsive mobile menu
* - Fixed positioning with scroll-to-hide
*
* TODO: Add `type` prop to switch between `service` and `global` header types
*/
export class PktHeader extends PktElementWithSlot<IPktHeader> implements IPktHeader {
serviceName?: string
serviceLink?: string
logoLink?: string
searchPlaceholder = 'Søk'
searchValue = ''
mobileBreakpoint: number = 768
tabletBreakpoint: number = 1280
openedMenu: THeaderMenu = 'none'
logOutButtonPlacement: TLogOutButtonPlacement = 'none'
position: THeaderPosition = 'fixed'
scrollBehavior: THeaderScrollBehavior =
'hide'
slotMenuVariant: TSlotMenuVariant = 'icon-only'
slotMenuText = 'Meny'
hideLogo: Booleanish = false
compact: Booleanish = false
showSearch: Booleanish = false
canChangeRepresentation: Booleanish = false
hasLogOut: Booleanish = false
user?: User
userMenu?: UserMenuItem[]
representing?: Representing
// Deprecated props - emit warnings
userMenuFooter?: UserMenuItem[]
userOptions?: UserMenuItem[]
firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated(changedProperties)
this.emitDeprecationWarnings()
}
private emitDeprecationWarnings() {
if (this.userMenuFooter !== undefined) {
// eslint-disable-next-line no-console -- Deprecation warnings are intentional for library consumers
console.warn('[PktHeader] userMenuFooter is deprecated. Use userMenu instead.')
}
if (this.userOptions !== undefined) {
// eslint-disable-next-line no-console -- Deprecation warnings are intentional for library consumers
console.warn('[PktHeader] userOptions is deprecated. Use userMenu instead.')
}
}
/**
* Convert deprecated props to new props
*/
private get effectiveUserMenu(): UserMenuItem[] | undefined {
const menu = this.userMenu || []
const footer = this.userMenuFooter || []
const options = this.userOptions || []
if (footer.length || options.length) {
return [...menu, ...options, ...footer]
}
return this.userMenu
}
render() {
return html`
<pkt-header-service
service-name=${ifDefined(this.serviceName)}
service-link=${ifDefined(this.serviceLink)}
logo-link=${ifDefined(this.logoLink)}
search-placeholder=${this.searchPlaceholder}
search-value=${this.searchValue}
mobile-breakpoint=${this.mobileBreakpoint}
tablet-breakpoint=${this.tabletBreakpoint}
opened-menu=${this.openedMenu}
log-out-button-placement=${this.logOutButtonPlacement}
position=${this.position}
scroll-behavior=${this.scrollBehavior}
slot-menu-variant=${this.slotMenuVariant}
slot-menu-text=${this.slotMenuText}
.hideLogo=${this.hideLogo}
.compact=${this.compact}
.showSearch=${this.showSearch}
.canChangeRepresentation=${this.canChangeRepresentation}
.hasLogOut=${this.hasLogOut}
.user=${this.user}
.userMenu=${this.effectiveUserMenu}
.representing=${this.representing}
>
${this.hasSlotContent()
? html`<div class="pkt-contents">${slotContent(this)}</div>`
: nothing}
</pkt-header-service>
`
}
}
declare global {
interface HTMLElementTagNameMap {
'pkt-header': PktHeader
}
}
try {
customElement('pkt-header')(PktHeader)
} catch (e) {
console.warn('Forsøker å definere <pkt-header>, men den er allerede definert')
}