@kompasid/lit-web-components 0.8.7 → 0.8.9

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.
Files changed (27) hide show
  1. package/assets/empty-state-notification.png +0 -0
  2. package/demo/index.html +24 -7
  3. package/dist/src/components/kompasid-grace-period/KompasGracePeriod.d.ts +1 -0
  4. package/dist/src/components/kompasid-grace-period/KompasGracePeriod.js +20 -6
  5. package/dist/src/components/kompasid-grace-period/KompasGracePeriod.js.map +1 -1
  6. package/dist/src/components/kompasid-header-notification/KompasHeaderNotification.d.ts +35 -0
  7. package/dist/src/components/kompasid-header-notification/KompasHeaderNotification.js +482 -0
  8. package/dist/src/components/kompasid-header-notification/KompasHeaderNotification.js.map +1 -0
  9. package/dist/src/components/kompasid-header-notification/types.d.ts +35 -0
  10. package/dist/src/components/kompasid-header-notification/types.js +2 -0
  11. package/dist/src/components/kompasid-header-notification/types.js.map +1 -0
  12. package/dist/src/components/kompasid-header-notification/utils.d.ts +21 -0
  13. package/dist/src/components/kompasid-header-notification/utils.js +43 -0
  14. package/dist/src/components/kompasid-header-notification/utils.js.map +1 -0
  15. package/dist/src/components/kompasid-paywall-body/KompasPaywallBody.js +2 -1
  16. package/dist/src/components/kompasid-paywall-body/KompasPaywallBody.js.map +1 -1
  17. package/dist/src/index.d.ts +1 -0
  18. package/dist/src/index.js +1 -0
  19. package/dist/src/index.js.map +1 -1
  20. package/dist/tsconfig.tsbuildinfo +1 -1
  21. package/package.json +1 -1
  22. package/src/components/kompasid-grace-period/KompasGracePeriod.ts +24 -6
  23. package/src/components/kompasid-header-notification/KompasHeaderNotification.ts +548 -0
  24. package/src/components/kompasid-header-notification/types.ts +39 -0
  25. package/src/components/kompasid-header-notification/utils.ts +86 -0
  26. package/src/components/kompasid-paywall-body/KompasPaywallBody.ts +2 -1
  27. package/src/index.ts +1 -0
@@ -0,0 +1,548 @@
1
+ import { LitElement, html, css } from 'lit'
2
+ import { format, isToday, formatDistanceStrict, subDays } from 'date-fns'
3
+ import { id } from 'date-fns/locale/id'
4
+ import { customElement, property, state } from 'lit/decorators.js'
5
+ import { unsafeSVG } from 'lit/directives/unsafe-svg.js'
6
+ import { getFontAwesomeIcon } from '../../utils/fontawesome-setup.js'
7
+ import { TWStyles } from '../../../tailwind/tailwind.js'
8
+ import {
9
+ UserNotification,
10
+ NotificationList,
11
+ ApiResponse,
12
+ ApiRubrikResponse,
13
+ } from './types.js'
14
+ import { customFetch } from './utils.js'
15
+
16
+ @customElement('kompasid-header-notification')
17
+ export class KompasHeaderNotification extends LitElement {
18
+ static styles = [
19
+ css`
20
+ :host {
21
+ font-family: 'PT Sans', sans-serif;
22
+ }
23
+
24
+ .header-account--notification-indicator {
25
+ position: absolute;
26
+ top: 0;
27
+ height: 0.5rem;
28
+ width: 0.5rem;
29
+ background-color: #ff7a00;
30
+ border-radius: 50%;
31
+ right: -0.403rem;
32
+ top: -0.281rem;
33
+ }
34
+
35
+ .header-notificaion-dropdown {
36
+ width: 20.5rem;
37
+ background-color: #ffffff;
38
+ font-family: 'PT Sans', sans-serif;
39
+ font-size: 0.875rem;
40
+ position: absolute;
41
+ right: -7.5vmax;
42
+ }
43
+
44
+ .w-14 {
45
+ width: 3.25rem;
46
+ }
47
+
48
+ .h-\\[300px\\] {
49
+ height: 300px;
50
+ }
51
+
52
+ .h-14 {
53
+ height: 3.25rem;
54
+ }
55
+
56
+ .bg-green-100 {
57
+ --tw-bg-opacity: 1;
58
+ background-color: rgb(238 252 210 / var(--tw-bg-opacity));
59
+ }
60
+
61
+ .overflow-y-scroll {
62
+ overflow-y: scroll;
63
+ }
64
+
65
+ .link-active {
66
+ color: #0468cb;
67
+ border-color: #0468cb;
68
+ border-bottom-width: 3px;
69
+ background-color: transparent !important;
70
+ }
71
+
72
+ .animate-spin {
73
+ animation: spin 2s linear infinite;
74
+ }
75
+
76
+ @keyframes spin {
77
+ from {
78
+ transform: rotate(0deg);
79
+ }
80
+ to {
81
+ transform: rotate(360deg);
82
+ }
83
+ }
84
+
85
+ .object-cover {
86
+ object-fit: cover;
87
+ }
88
+
89
+ .z-index-max {
90
+ z-index: 99999;
91
+ }
92
+
93
+ /* Custom Scrollbar for header */
94
+ /* width */
95
+ ::-webkit-scrollbar {
96
+ width: 4px;
97
+ }
98
+
99
+ /* Track */
100
+ ::-webkit-scrollbar-track {
101
+ background: transparent;
102
+ }
103
+
104
+ /* Handle */
105
+ ::-webkit-scrollbar-thumb {
106
+ background: #0356a8;
107
+ border-radius: 100px;
108
+ }
109
+
110
+ /* Handle on hover */
111
+ ::-webkit-scrollbar-thumb:hover {
112
+ background: #0356a8;
113
+ }
114
+
115
+ @media (min-width: 1024px) {
116
+ .header-notificaion-dropdown {
117
+ right: -4vmax;
118
+ }
119
+ }
120
+
121
+ @media (max-width: 360px) {
122
+ .header-notificaion-dropdown {
123
+ right: -10vmax;
124
+ }
125
+ }
126
+ `,
127
+ TWStyles,
128
+ ]
129
+
130
+ @state() isShowDropdown: boolean = false
131
+ @state() selectedTab: string = 'Info'
132
+ @state() notificationInfoData: UserNotification = {} as UserNotification
133
+ @state() notificationContentData: any[] = []
134
+ @state() isDataLoaded: boolean = false
135
+
136
+ @property({ type: String }) accessToken = '' // prod || dev
137
+ @property({ type: String }) refreshToken = '' // prod || dev
138
+
139
+ constructor() {
140
+ super()
141
+ this.handleClickOutside = this.handleClickOutside.bind(this)
142
+ }
143
+
144
+ /**
145
+ * Function to format date
146
+ */
147
+ formatDate(date: string) {
148
+ // Check if the provided date is today
149
+ let result
150
+ if (isToday(date)) {
151
+ // Return time difference if it's today (e.g., "7 hours ago")
152
+ result = `${formatDistanceStrict(date, new Date(), { locale: id })} lalu`
153
+ } else {
154
+ // Return formatted date (e.g., "12 Sep 2024, 09:00")
155
+ result = format(date, 'dd MMM yyyy, HH:mm', { locale: id })
156
+ }
157
+ return result
158
+ }
159
+
160
+ override async connectedCallback() {
161
+ super.connectedCallback()
162
+ this.isShowDropdown = false
163
+
164
+ if (this.accessToken && this.refreshToken) await this.loadData()
165
+ document.addEventListener('click', this.handleClickOutside)
166
+ }
167
+
168
+ override async disconnectedCallback() {
169
+ super.disconnectedCallback()
170
+ document.removeEventListener('click', this.handleClickOutside)
171
+ }
172
+
173
+ private async apiFetch(url: string, options: any) {
174
+ const response = await customFetch(
175
+ url,
176
+ this.refreshToken,
177
+ this.accessToken,
178
+ { ...options }
179
+ )
180
+
181
+ return response
182
+ }
183
+
184
+ private async getNotifRubrik() {
185
+ const req = this.apiFetch(
186
+ 'https://cds.kompas.cloud/api/v1/article/pilihanku',
187
+ {
188
+ method: 'GET',
189
+ headers: {
190
+ 'Content-Type': 'application/json',
191
+ },
192
+ }
193
+ )
194
+ return req
195
+ }
196
+
197
+ private async getNotifList() {
198
+ const req = await this.apiFetch(
199
+ 'https://api.kompas.cloud/account/api/v1/users/notification',
200
+ {
201
+ method: 'GET',
202
+ headers: {
203
+ 'Content-Type': 'application/json',
204
+ },
205
+ }
206
+ )
207
+ return req
208
+ }
209
+
210
+ private async getEpaperData() {
211
+ const formatDate = 'yyyy/MM/dd'
212
+ const startDate = format(subDays(new Date(), 1), formatDate)
213
+ const endDate = format(new Date(), formatDate).toString()
214
+ const req = await this.apiFetch(
215
+ `https://apiepaper.kompas.cloud/products?startDate=${startDate}&endDate=${endDate}&sort=desc`,
216
+ {
217
+ method: 'GET',
218
+ headers: {
219
+ 'Content-Type': 'application/json',
220
+ },
221
+ }
222
+ )
223
+
224
+ return req
225
+ }
226
+
227
+ private async notifRead(notifId: string) {
228
+ const req = await this.apiFetch(
229
+ 'https://api.kompas.cloud/account/api/v1/users/notification/read',
230
+ {
231
+ headers: {
232
+ 'Content-Type': 'application/json',
233
+ },
234
+ method: 'PUT',
235
+ body: JSON.stringify({
236
+ notificationId: notifId,
237
+ }),
238
+ }
239
+ )
240
+ return req
241
+ }
242
+
243
+ private async loadData() {
244
+ const apiCalls = [
245
+ this.getNotifList(),
246
+ this.getNotifRubrik(),
247
+ this.getEpaperData(),
248
+ ]
249
+ this.isDataLoaded = false
250
+
251
+ Promise.all(apiCalls)
252
+ .then(responses =>
253
+ Promise.all(responses.map(response => response.json()))
254
+ )
255
+ .then(values => {
256
+ this.notificationInfoData = (
257
+ values[0] as ApiResponse<UserNotification>
258
+ ).data
259
+ const rubrikData = (values[1] as ApiRubrikResponse<any>).result
260
+ const ePaperData = (values[2] as ApiResponse<any>).data[0]
261
+ const { publishDate, description, thumbnail, title, url } = ePaperData
262
+
263
+ const data = {
264
+ title,
265
+ category: [{ name: 'ePaper', slug: 'epaper' }],
266
+ publishedDateGmt: format(
267
+ new Date(publishDate),
268
+ 'yyyy-MM-dd HH:mm:ss'
269
+ ),
270
+ permalink: url,
271
+ thumbnails: {
272
+ sizes: { thumbnailSquareMedium: { permalink: thumbnail } },
273
+ },
274
+ excerpt: description,
275
+ }
276
+
277
+ this.notificationContentData = [data, ...rubrikData]
278
+ this.notificationContentData.sort(
279
+ (a: any, b: any) =>
280
+ new Date(b.publishedDateGmt).getTime() -
281
+ new Date(a.publishedDateGmt).getTime()
282
+ )
283
+
284
+ this.isDataLoaded = true
285
+ })
286
+ }
287
+
288
+ private toggleDropdown() {
289
+ this.isShowDropdown = !this.isShowDropdown
290
+ }
291
+
292
+ private notificationIcon() {
293
+ const notificationIndicator = () => {
294
+ if (!this.notificationInfoData.notificationCount) return html``
295
+ return html`<div
296
+ class="header-account--notification-indicator animate-ping"
297
+ ></div>`
298
+ }
299
+
300
+ return html`
301
+ <button
302
+ @click=${this.toggleDropdown}
303
+ class="cursor-pointer relative flex items-center"
304
+ >
305
+ ${notificationIndicator()}
306
+ <div class="flex flex-row items-center self-center">
307
+ <div class="text-white cursor-pointer mt-0.5">
308
+ ${unsafeSVG(getFontAwesomeIcon('fas', 'bell', 21, 21))}
309
+ </div>
310
+ </div>
311
+ </button>
312
+ `
313
+ }
314
+
315
+ private handleClick = (value: string) => {
316
+ this.selectedTab = value
317
+ }
318
+
319
+ private redirectTo = async (notifId: string, link: string) => {
320
+ const res = await this.notifRead(notifId)
321
+
322
+ if (res.status === 200) {
323
+ this.notificationInfoData = {
324
+ ...this.notificationInfoData,
325
+ notificationList: this.notificationInfoData.notificationList.map(
326
+ notifItem => ({
327
+ ...notifItem,
328
+ isRead:
329
+ notifItem.notificationId === notifId ? true : notifItem.isRead,
330
+ })
331
+ ),
332
+ }
333
+ }
334
+
335
+ if (link) {
336
+ const url = new URL(decodeURIComponent(link))
337
+
338
+ window.open(url, '_blank')
339
+ }
340
+ }
341
+
342
+ private handleClickOutside(event: Event) {
343
+ if (!this.isShowDropdown) return
344
+
345
+ const popup = this.shadowRoot?.getElementById('headerNotification')
346
+ const ev = event.composedPath()
347
+ if (this.isShowDropdown && popup && !ev?.includes(popup as HTMLElement)) {
348
+ this.isShowDropdown = false // Close the popup
349
+ }
350
+ }
351
+
352
+ // Notification Info
353
+ private notificationInfoSection() {
354
+ const { notificationList }: { notificationList: NotificationList[] } =
355
+ this.notificationInfoData
356
+
357
+ // Empty state
358
+ if (!notificationList.length)
359
+ return html`
360
+ <div class="text-center px-4 pt-6 pb-32">
361
+ <img
362
+ src="../../assets/empty-state-notification.png"
363
+ alt="empty-state-notification"
364
+ class="w-auto mx-auto"
365
+ />
366
+ <p class="font-bold text-center text-lg py-2">Belum Ada Notifikasi</p>
367
+ <p class="px-2">
368
+ Kami akan memberitahukan Anda ketika ada informasi dan pemberitahuan
369
+ terbaru.
370
+ </p>
371
+ </div>
372
+ `
373
+
374
+ const notificationInfoListTemplate = (item: NotificationList) => {
375
+ const imgUrl =
376
+ item.label === 'Akun'
377
+ ? `https://cdn-www.kompas.id/assets/notifikasi-akun.svg`
378
+ : `https://cdn-www.kompas.id/assets/langganan-anda-telah-berakhir.svg`
379
+
380
+ return html`<div class="w-3/4 pr-1">
381
+ <div class="flex items-center mb-1 text-xs">
382
+ <span class="text-green-500 bg-green-100 rounded-sm p-1 px-2">
383
+ ${item.label}
384
+ </span>
385
+ <span class="text-grey-400 ml-2"
386
+ >${this.formatDate(item.time)}</span
387
+ >
388
+ </div>
389
+ <div>
390
+ <p class="text-sm font-bold">${item.title}</p>
391
+ <p class="text-sm">${item.description}</p>
392
+ </div>
393
+ </div>
394
+ <div class="w-1/4">
395
+ <img src="${imgUrl}" alt="${item.label}-alt" class="w-14 h-14" />
396
+ </div>`
397
+ }
398
+
399
+ return html`<div class="h-[300px] overflow-y-scroll">
400
+ ${notificationList.map(
401
+ item =>
402
+ html`<button
403
+ class="flex w-full text-left items-start p-4 cursor-pointer justify-between ${!item.isRead
404
+ ? 'bg-blue-100'
405
+ : ''}"
406
+ @click=${() => this.redirectTo(item.notificationId, item.link)}
407
+ >
408
+ ${notificationInfoListTemplate(item)}
409
+ </button> `
410
+ )}
411
+ </div>
412
+ <!-- Footer Link -->
413
+ <div class="px-4 py-4 text-center">
414
+ <a href="#" @click="${() =>
415
+ this.redirectToNotification(
416
+ 'info'
417
+ )}" class="text-base font-bold text-blue-500">
418
+ Lihat Selengkapnya</a
419
+ >
420
+ </div>
421
+ </div>`
422
+ }
423
+
424
+ private redirectToNotification(tab: string) {
425
+ window.open(
426
+ `https://account.kompas.id/manage-account/notification/${tab}`,
427
+ '_blank'
428
+ )
429
+ }
430
+
431
+ // Notification Content
432
+ private notificationContentSection() {
433
+ // Empty state
434
+ if (!this.notificationContentData.length) {
435
+ return html`
436
+ <div class="text-center px-4 pt-6 pb-32">
437
+ <img
438
+ src="../../assets/empty-state-notification.png"
439
+ alt="empty-state-notification"
440
+ class="w-auto mx-auto"
441
+ />
442
+ <p class="font-bold text-center text-lg py-2">Belum Ada Notifikasi</p>
443
+ <p class="px-2">
444
+ Kami akan memberitahukan Anda ketika ada informasi dan pemberitahuan
445
+ terbaru.
446
+ </p>
447
+ </div>
448
+ `
449
+ }
450
+ const notificationContentListTemplate = (item: any) => html`<div
451
+ class="w-3/4 pr-1 "
452
+ >
453
+ <div class="flex items-center mb-1 text-xs">
454
+ <span class="text-green-500 bg-green-100 rounded-sm p-1 px-2">
455
+ ${item.category[0].name}
456
+ </span>
457
+ <span class="text-grey-400 ml-2">
458
+ ${this.formatDate(item.publishedDateGmt)}</span
459
+ >
460
+ </div>
461
+ <p class="font-bold text-base text-customTextColor py-1">
462
+ ${item.title}
463
+ </p>
464
+ </div>
465
+ <div class="w-1/4">
466
+ <img
467
+ src="${item.thumbnails.sizes.thumbnailSquareMedium.permalink}"
468
+ alt="content-img-alt"
469
+ class="w-14 h-14 object-cover"
470
+ />
471
+ </div>`
472
+
473
+ return html`<div class="h-[300px] overflow-y-scroll">
474
+ ${this.notificationContentData.map(
475
+ item =>
476
+ html`<button
477
+ class="flex w-full text-left items-start p-4 cursor-pointer justify-between ${!item.isRead
478
+ ? 'bg-blue-100'
479
+ : ''}"
480
+ @click=${() => window.open(item.permalink, '_blank')}
481
+ >
482
+ ${notificationContentListTemplate(item)}
483
+ </button> `
484
+ )}
485
+ </div>
486
+ <!-- Footer Link -->
487
+ <div class="px-4 py-4 text-center">
488
+ <a href="#" @click="${() =>
489
+ this.redirectToNotification(
490
+ 'konten'
491
+ )}" class="text-base font-bold text-blue-500">
492
+ Lihat Selengkapnya</a
493
+ >
494
+ </div>
495
+ </div>`
496
+ }
497
+
498
+ private notificationPopup() {
499
+ const tab = ['Info', 'Konten']
500
+
501
+ return html`
502
+ <div
503
+ id="notificationPopup"
504
+ class="header-notificaion-dropdown rounded-lg shadow-lg z-50 mt-2 ${this
505
+ .isShowDropdown
506
+ ? 'active'
507
+ : ''}"
508
+ >
509
+ <div class="sticky">
510
+ <div class="flex justify-center py-2 border-b border-grey-300">
511
+ <span class="font-bold text-base">Notifikasi</span>
512
+ </div>
513
+ <!-- Tabs for Info and Content -->
514
+ <div class="flex justify-between">
515
+ ${tab.map(
516
+ item =>
517
+ html`
518
+ <button
519
+ class="focus:outline-none py-2 w-1/2 ${this.selectedTab ===
520
+ item && 'link-active'}"
521
+ @click=${() => this.handleClick(item)}
522
+ >
523
+ ${item}
524
+ </button>
525
+ `
526
+ )}
527
+ </div>
528
+ </div>
529
+
530
+ <!-- Notification Content -->
531
+ ${this.selectedTab === 'Info'
532
+ ? this.notificationInfoSection()
533
+ : this.notificationContentSection()}
534
+ </div>
535
+ `
536
+ }
537
+
538
+ render() {
539
+ return html`<div id="headerNotification" class="relative">
540
+ ${this.isDataLoaded
541
+ ? this.notificationIcon()
542
+ : html`<div class="text-white cursor-pointer mt-0.5 animate-spin">
543
+ ${unsafeSVG(getFontAwesomeIcon('fa', 'circle-notch', 21, 21))}
544
+ </div>`}
545
+ ${this.isShowDropdown ? this.notificationPopup() : ''}
546
+ </div>`
547
+ }
548
+ }
@@ -0,0 +1,39 @@
1
+ export interface NotificationList {
2
+ notificationId: string
3
+ id: number
4
+ title: string
5
+ label: string
6
+ description: string
7
+ isRead: boolean
8
+ time: string // ISO date string
9
+ link: string
10
+ }
11
+
12
+ // Interface for the overall notification state
13
+ export interface UserNotification {
14
+ notificationList: NotificationList[]
15
+ notificationCount: number
16
+ loadMore: boolean
17
+ next: number
18
+ }
19
+
20
+ interface Meta {
21
+ cache: boolean
22
+ time: number
23
+ }
24
+
25
+ export interface ApiResponse<T> {
26
+ success: boolean
27
+ code: number
28
+ message: string
29
+ meta: Meta
30
+ data: T
31
+ }
32
+
33
+ export interface ApiRubrikResponse<T> {
34
+ success: boolean
35
+ code: number
36
+ message: string
37
+ meta: Meta
38
+ result: T
39
+ }
@@ -0,0 +1,86 @@
1
+ /* eslint-disable no-param-reassign */
2
+ /* eslint-disable no-undef */
3
+ // Define types for the API responses
4
+ interface RefreshTokenResponse {
5
+ data: {
6
+ accessToken: string
7
+ deviceKeyId: string
8
+ isVerified: boolean
9
+ refreshToken: string
10
+ }
11
+ }
12
+
13
+ interface ApiResponse<T> extends Response {
14
+ json(): Promise<T>
15
+ }
16
+
17
+ interface RequestInit {
18
+ method?: string
19
+ headers?: Headers | { [key: string]: string }
20
+ body?: BodyInit | null
21
+ mode?: RequestMode
22
+ credentials?: RequestCredentials
23
+ cache?: RequestCache
24
+ redirect?: RequestRedirect
25
+ referrer?: string
26
+ referrerPolicy?: ReferrerPolicy
27
+ integrity?: string
28
+ keepalive?: boolean
29
+ signal?: AbortSignal
30
+ }
31
+
32
+ // Function to refresh the token
33
+ async function refreshAccessToken(refreshToken: string): Promise<string> {
34
+ const response = await fetch(
35
+ 'https://api.kompas.cloud/account/api/v1/tokens/refresh',
36
+ {
37
+ method: 'POST',
38
+ body: JSON.stringify({
39
+ refreshToken,
40
+ }),
41
+ headers: {
42
+ 'Content-Type': 'application/json',
43
+ },
44
+ }
45
+ )
46
+
47
+ if (!response.ok) {
48
+ throw new Error('Failed to refresh token')
49
+ }
50
+
51
+ const data: RefreshTokenResponse = await response.json()
52
+ return data.data.accessToken
53
+ }
54
+
55
+ // Custom fetch function that retries after 401
56
+ export async function customFetch<T>(
57
+ url: string,
58
+ refreshToken: string,
59
+ accessToken: string,
60
+ options: RequestInit = {}
61
+ ): Promise<ApiResponse<T>> {
62
+ try {
63
+ // Retrieve and set access token in headers
64
+ const headers = new Headers(options.headers || {})
65
+ if (accessToken) {
66
+ headers.set('Authorization', `Bearer ${accessToken}`)
67
+ }
68
+
69
+ // Set updated headers
70
+ options.headers = headers
71
+ let response = await fetch(url, options)
72
+
73
+ // Retry request if 401 error occurs
74
+ if (response.status === 401) {
75
+ const newToken = await refreshAccessToken(refreshToken)
76
+ headers.set('Authorization', `Bearer ${newToken}`)
77
+ // Retry the original request with the new token
78
+ response = await fetch(url, { ...options, headers })
79
+ }
80
+
81
+ return response as ApiResponse<T>
82
+ } catch (error) {
83
+ console.error('Error making API call:', error)
84
+ throw error
85
+ }
86
+ }
@@ -597,8 +597,9 @@ export class KompasIdPaywallBody extends LitElement {
597
597
  let buttonContent
598
598
  const textColorClass = this.isDark ? 'text-blue-300' : 'text-blue-600'
599
599
  const buttonTextColorClass = this.isDark ? 'text-white' : 'text-grey-600'
600
+ const isPrevHistoryExist = window.history.length > 1
600
601
 
601
- if (type === 'epaper') {
602
+ if (type === 'epaper' && isPrevHistoryExist) {
602
603
  buttonContent = html` <button
603
604
  @click=${this.redirectToPrevUrl}
604
605
  class="hidden md:block w-8 h-8 pl-4 ${textColorClass}"
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@ export { KompasMeteredPaywall } from './components/kompasid-metered-paywall/Komp
7
7
  export { KompasFreewall } from './components/kompasid-freewall/KompasFreewall.js'
8
8
  export { KompasMeteredWallRegister } from './components/kompasid-metered-wall-register/KompasMeteredWallRegister.js'
9
9
  export { KompasHeaderAccount } from './components/kompasid-header-account/KompasHeaderAccount.js'
10
+ export { KompasHeaderNotification } from './components/kompasid-header-notification/KompasHeaderNotification.js'
10
11
  export { KompasGracePeriod } from './components/kompasid-grace-period/KompasGracePeriod.js'
11
12
 
12
13
  declare global {