@kompasid/lit-web-components 0.6.7 → 0.7.0

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 (31) hide show
  1. package/demo/index.html +35 -1
  2. package/dist/src/components/kompasid-paywall-body/KompasPaywallBody.js +39 -11
  3. package/dist/src/components/kompasid-paywall-body/KompasPaywallBody.js.map +1 -1
  4. package/dist/src/components/kompasid-widget-recirculations-default/KompasWidgetRecirculationsDefault.d.ts +39 -0
  5. package/dist/src/components/kompasid-widget-recirculations-default/KompasWidgetRecirculationsDefault.js +340 -0
  6. package/dist/src/components/kompasid-widget-recirculations-default/KompasWidgetRecirculationsDefault.js.map +1 -0
  7. package/dist/src/components/kompasid-widget-recirculations-default/types.d.ts +27 -0
  8. package/dist/src/components/kompasid-widget-recirculations-default/types.js +2 -0
  9. package/dist/src/components/kompasid-widget-recirculations-default/types.js.map +1 -0
  10. package/dist/src/components/kompasid-widget-recirculations-list/KompasWidgetRecirculationsList.d.ts +28 -0
  11. package/dist/src/components/kompasid-widget-recirculations-list/KompasWidgetRecirculationsList.js +188 -0
  12. package/dist/src/components/kompasid-widget-recirculations-list/KompasWidgetRecirculationsList.js.map +1 -0
  13. package/dist/src/index.d.ts +2 -0
  14. package/dist/src/index.js +2 -0
  15. package/dist/src/index.js.map +1 -1
  16. package/dist/tailwind/tailwind.js +88 -170
  17. package/dist/tailwind/tailwind.js.map +1 -1
  18. package/dist/tsconfig.tsbuildinfo +1 -1
  19. package/package.json +2 -1
  20. package/src/components/kompasid-paywall-body/KompasPaywallBody.ts +39 -11
  21. package/src/components/kompasid-widget-recirculations-default/KompasWidgetRecirculationsDefault.ts +342 -0
  22. package/src/components/kompasid-widget-recirculations-default/readme.md +57 -0
  23. package/src/components/kompasid-widget-recirculations-default/types.ts +28 -0
  24. package/src/components/kompasid-widget-recirculations-list/KompasWidgetRecirculationsList.ts +230 -0
  25. package/src/components/kompasid-widget-recirculations-list/readme.md +27 -0
  26. package/src/index.ts +2 -0
  27. package/tailwind/tailwind.css +85 -170
  28. package/tailwind/tailwind.ts +88 -170
  29. package/tailwind.config.js +2 -1
  30. package/assets/kompas-free-trial.png +0 -0
  31. package/assets/qr-code.png +0 -0
@@ -933,8 +933,8 @@ export class KompasIdPaywallBody extends LitElement {
933
933
  ? this.primaryPackages(item)
934
934
  : this.secondaryPackages(item)
935
935
  )}
936
- ${this.swgEnable ? this.swgPackageSection() : nothing}
937
936
  ${this.freeTrialPackageSection()} ${this.freeTrialPopUp()}
937
+ ${this.swgEnable ? this.swgPackageSection() : nothing}
938
938
  </div>
939
939
  `
940
940
  }
@@ -1075,12 +1075,16 @@ export class KompasIdPaywallBody extends LitElement {
1075
1075
  class="fixed w-full h-full inset-0 flex justify-center items-center z-50 bg-black bg-opacity-75 hidden"
1076
1076
  >
1077
1077
  <div
1078
- class="bg-white rounded w-11/12 sm:w-3/4 md:w-1/2 lg:w-1/3 2xl:w-1/4 p-6 text-center"
1078
+ class="${this.isDark
1079
+ ? 'bg-dark-4'
1080
+ : 'bg-white'} rounded w-11/12 sm:w-3/4 md:w-1/2 lg:w-1/3 2xl:w-1/4 p-6 text-center"
1079
1081
  >
1080
1082
  <div class="w-full flex justify-end px-2">
1081
1083
  <button
1082
1084
  @click=${this.closeFreeTrialPopup}
1083
- class="w-8 h-8 pl-4 text-grey-400"
1085
+ class="w-8 h-8 pl-4 ${this.isDark
1086
+ ? 'text-grey-300'
1087
+ : 'text-grey-400'}"
1084
1088
  >
1085
1089
  ${unsafeSVG(getFontAwesomeIcon('fas', 'xmark', 24, 24))}
1086
1090
  </button>
@@ -1093,11 +1097,17 @@ export class KompasIdPaywallBody extends LitElement {
1093
1097
  />
1094
1098
  </div>
1095
1099
  </div>
1096
- <p class="font-bold text-lg text-grey-600 mt-4">
1100
+ <p
1101
+ class="font-bold text-lg ${this.isDark
1102
+ ? 'text-white'
1103
+ : 'text-grey-600'} mt-4"
1104
+ >
1097
1105
  Coba Gratis Kompas.id di Aplikasi
1098
1106
  </p>
1099
1107
  <div
1100
- class="hidden lg:block lg:flex flex border border-grey-300 rounded mt-4 px-8 py-4 items-center"
1108
+ class="${this.isDark
1109
+ ? 'bg-dark-3 border border-dark-9'
1110
+ : 'bg-white border border-grey-300'} hidden lg:block lg:flex flex rounded mt-4 px-8 py-4 items-center"
1101
1111
  >
1102
1112
  <div class="w-1/3 flex mr-6">
1103
1113
  <img
@@ -1105,13 +1115,19 @@ export class KompasIdPaywallBody extends LitElement {
1105
1115
  alt="QR Code Deep Link"
1106
1116
  />
1107
1117
  </div>
1108
- <div class="w-2/3 text-base text-grey-600 text-left">
1118
+ <div
1119
+ class="w-2/3 text-base ${this.isDark
1120
+ ? 'text-dark-7'
1121
+ : 'text-grey-600'} text-left"
1122
+ >
1109
1123
  Coba gratis 3 hari Kompas.id melalui aplikasi. Pindai kode QR
1110
1124
  dengan ponsel atau tablet untuk mengunduh aplikasi.
1111
1125
  </div>
1112
1126
  </div>
1113
1127
  <div
1114
- class="text-base text-grey-600 text-center lg:hidden px-2 md:px-8"
1128
+ class="text-base ${this.isDark
1129
+ ? 'text-dark-7'
1130
+ : 'text-grey-600'} text-center lg:hidden px-2 md:px-8"
1115
1131
  >
1116
1132
  Dapatkan akses gratis selama 3 hari ke konten dan fitur premium
1117
1133
  Kompas.id di aplikasi.
@@ -1121,22 +1137,34 @@ export class KompasIdPaywallBody extends LitElement {
1121
1137
  href="https://play.google.com/store/apps/details?id=id.kompas.app"
1122
1138
  target="_blank"
1123
1139
  ><img
1124
- src="https://cdn-www.kompas.id/halaman-unduh/image/google-play-badge.png"
1140
+ src="${this.isDark
1141
+ ? 'https://kompasid-production-www.s3.ap-southeast-1.amazonaws.com/web-component/Button_Download%20Google%20Play_Dark%20Mode.svg'
1142
+ : 'https://kompasid-production-www.s3.ap-southeast-1.amazonaws.com/web-component/Button_Download%20Google%20Play_Light%20Mode.svg'}"
1125
1143
  alt="Google Play Badge"
1126
1144
  /></a>
1127
1145
  <a
1128
1146
  href="https://apps.apple.com/id/app/kompas-id/id1242195037?l=id"
1129
1147
  target="_blank"
1130
1148
  ><img
1131
- src="https://cdn-www.kompas.id/halaman-unduh/image/ios-badge.png"
1149
+ src="${this.isDark
1150
+ ? 'https://kompasid-production-www.s3.ap-southeast-1.amazonaws.com/web-component/Button_Download%20App%20Store_Dark%20Mode.svg'
1151
+ : 'https://kompasid-production-www.s3.ap-southeast-1.amazonaws.com/web-component/Button_Download%20App%20Store_Light%20Mode.svg'}"
1132
1152
  alt="iOS App Store Badge"
1133
1153
  /></a>
1134
1154
  </div>
1135
1155
  <button
1136
1156
  onclick="window.open('https://app.komp.as/langganan', '_blank')"
1137
- class="h-12 bg-green-500 rounded-md mt-4 flex w-full items-center justify-center lg:hidden"
1157
+ class="h-12 ${this.isDark
1158
+ ? 'bg-green-300'
1159
+ : 'bg-green-500'} rounded-md mt-4 flex w-full items-center justify-center lg:hidden"
1138
1160
  >
1139
- <h6 class="text-white font-bold p-4">Unduh Sekarang</h6>
1161
+ <h6
1162
+ class="${this.isDark
1163
+ ? 'text-dark-5'
1164
+ : 'text-white'} font-bold p-4"
1165
+ >
1166
+ Unduh Sekarang
1167
+ </h6>
1140
1168
  </button>
1141
1169
  </div>
1142
1170
  </div>
@@ -0,0 +1,342 @@
1
+ import { html, css, LitElement } from 'lit'
2
+ import { customElement, property } from 'lit/decorators.js'
3
+ import { format } from 'date-fns'
4
+ import { id } from 'date-fns/locale/id'
5
+ import { TWStyles } from '../../../tailwind/tailwind.js'
6
+ import { Post, Navigation } from './types.js'
7
+
8
+ @customElement('kompasid-widget-recirculations-default')
9
+ export class KompasWidgetRecirculationsDefault extends LitElement {
10
+ static styles = [
11
+ css`
12
+ :host {
13
+ font-family: 'PT Sans', sans-serif;
14
+ }
15
+ .chip {
16
+ align-items: center;
17
+ border-radius: 0.25rem;
18
+ display: flex;
19
+ font-family: 'PT Sans', sans-serif;
20
+ font-size: 0.75rem;
21
+ font-weight: bold;
22
+ height: 1.5rem;
23
+ justify-content: center;
24
+ line-height: 1rem;
25
+ margin-bottom: 0.25rem;
26
+ padding: 0.375rem 0.5rem;
27
+ }
28
+ `,
29
+ TWStyles,
30
+ ]
31
+
32
+ /**
33
+ * Props
34
+ */
35
+ @property({ type: Array }) posts: Post[][] = []
36
+ @property({ type: Object }) navigation: Navigation | undefined = undefined
37
+ @property({ type: String }) accessToken = ''
38
+ @property({ type: String }) permalinkArticle = ''
39
+ @property({ type: String }) userGuid = '0'
40
+ @property({ type: String }) slugs = ''
41
+ @property({ type: String }) type: 'relatedArticle' | 'otherArticle' =
42
+ 'relatedArticle'
43
+ @property({ type: String }) mainCategory = ''
44
+
45
+ /**
46
+ * Getters
47
+ */
48
+ get navigationPermalink(): string | undefined {
49
+ return this.navigation?.permalink
50
+ }
51
+
52
+ /**
53
+ * Fetch Data
54
+ */
55
+ async connectedCallback() {
56
+ super.connectedCallback()
57
+ try {
58
+ await this.fetchAccessToken()
59
+ if (this.type === 'relatedArticle') {
60
+ await this.relatedArticles()
61
+ } else if (this.type === 'otherArticle') {
62
+ await this.otherArticles()
63
+ }
64
+ } catch (error) {
65
+ this.handleFetchError(error)
66
+ }
67
+ }
68
+
69
+ async fetchAccessToken() {
70
+ const response = await fetch(
71
+ 'https://api.kompas.id/account/api/v1/login/guest',
72
+ {
73
+ method: 'POST',
74
+ headers: {
75
+ 'Content-Type': 'application/json',
76
+ },
77
+ body: JSON.stringify({
78
+ email: 'anonynous.user@kompas.id',
79
+ }),
80
+ }
81
+ )
82
+
83
+ const result = await response.json()
84
+
85
+ if (result?.data?.accessToken) {
86
+ this.accessToken = result.data.accessToken
87
+ } else {
88
+ throw new Error('Token akses tidak tersedia dalam respons')
89
+ }
90
+ }
91
+
92
+ async relatedArticles() {
93
+ if (!this.accessToken) {
94
+ throw new Error('Token akses tidak tersedia')
95
+ }
96
+
97
+ const kompasApiAi = 'https://ai.kompas.id/api/v1'
98
+
99
+ // Constructing parameters
100
+ const params = new URLSearchParams()
101
+ params.append('page_url', this.permalinkArticle)
102
+ params.append('page_type', 'read')
103
+ params.append('item_type', 'articles')
104
+ params.append('guid', this.userGuid)
105
+ params.append('slugs', this.slugs)
106
+
107
+ // Constructing the URL with parameters
108
+ const endpoint = `${kompasApiAi}/recommendation?${params.toString()}`
109
+
110
+ const response = await fetch(endpoint, {
111
+ headers: {
112
+ Authorization: `Bearer ${this.accessToken}`,
113
+ 'Content-Type': 'application/json',
114
+ },
115
+ })
116
+
117
+ const result = await response.json()
118
+
119
+ if (result?.result) {
120
+ const items = result.result
121
+ const firstChunk = items.slice(0, 5)
122
+ const secondChunk = items.slice(5, 7)
123
+ this.posts = [Object.freeze(firstChunk), Object.freeze(secondChunk)]
124
+ console.log('related article:', this.posts)
125
+ } else {
126
+ throw new Error('Data artikel terkait tidak ditemukan')
127
+ }
128
+ }
129
+
130
+ async otherArticles() {
131
+ if (!this.accessToken) {
132
+ throw new Error('Token akses tidak tersedia')
133
+ }
134
+
135
+ const kompasApiCdsSPA = 'https://cds.kompas.id/api/v1'
136
+
137
+ // Constructing the URL with parameters
138
+ const endpoint = `${kompasApiCdsSPA}/article/list/category/${this.mainCategory}`
139
+
140
+ const response = await fetch(endpoint, {
141
+ headers: {
142
+ Authorization: `Bearer ${this.accessToken}`,
143
+ 'Content-Type': 'application/json',
144
+ },
145
+ })
146
+
147
+ const result = await response.json()
148
+
149
+ if (result?.result) {
150
+ const items = result.result
151
+ const firstChunk = items.slice(0, 5)
152
+ const secondChunk = items.slice(5, 7)
153
+ this.posts = [Object.freeze(firstChunk), Object.freeze(secondChunk)]
154
+ console.log('other article:', this.posts)
155
+ } else {
156
+ throw new Error('Data artikel lainnya tidak ditemukan')
157
+ }
158
+ }
159
+
160
+ handleFetchError(error: unknown) {
161
+ const errorMessage =
162
+ error instanceof Error ? error.message : 'Kesalahan tidak diketahui'
163
+ alert(`Terjadi kesalahan: ${errorMessage}`)
164
+ }
165
+
166
+ /**
167
+ * Function to format date
168
+ */
169
+ formatDate(date: string) {
170
+ return format(new Date(date), 'dd MMMM yyyy', { locale: id })
171
+ }
172
+
173
+ /**
174
+ * Render widget components
175
+ */
176
+
177
+ private WidgetTitle() {
178
+ if (this.navigationPermalink) {
179
+ return html`
180
+ <a
181
+ href="${this.navigationPermalink}"
182
+ class="flex font-sans uppercase items-start mb-6 mt-8"
183
+ >
184
+ <h5
185
+ class="${[
186
+ 'capitalize font-bold font-sans',
187
+ this.navigationPermalink ? 'text-brand-1' : 'text-grey-600',
188
+ ].join(' ')}"
189
+ >
190
+ ${this.navigation?.name}
191
+ </h5>
192
+ </a>
193
+ `
194
+ }
195
+
196
+ return html`
197
+ <div class="flex font-sans uppercase items-start mb-6 mt-8">
198
+ <div>
199
+ <h5
200
+ class="${[
201
+ 'capitalize font-bold font-sans',
202
+ this.navigationPermalink ? 'text-brand-1' : 'text-grey-600',
203
+ ].join(' ')}"
204
+ >
205
+ ${this.navigation?.name}
206
+ </h5>
207
+ </div>
208
+ </div>
209
+ `
210
+ }
211
+
212
+ renderChips(post: Post) {
213
+ const chips = []
214
+ const isAnalisis = post.postTag?.some(tag => tag.slug === 'analisis')
215
+ const isEksklusif = post.postTag?.some(tag => tag.slug === 'eksklusif')
216
+ const isFreemium = post.isFreemium === true
217
+
218
+ if (isEksklusif) {
219
+ chips.push(
220
+ html`
221
+ <div class="flex">
222
+ <div class="chip bg-grey-600 text-white">
223
+ <img
224
+ src="https://cdn-www.kompas.id/assets/img/icons/kompas-icon-small.svg"
225
+ alt="Kompas Icon"
226
+ style="width: 16px; height: 16px; margin-right: 4px;"
227
+ />
228
+ Eksklusif
229
+ </div>
230
+ </div>
231
+ `
232
+ )
233
+ } else if (isFreemium) {
234
+ chips.push(
235
+ html`
236
+ <div class="flex">
237
+ <div class="chip bg-blue-100 text-brand-1">Bebas Akses</div>
238
+ </div>
239
+ `
240
+ )
241
+ } else if (isAnalisis) {
242
+ chips.push(
243
+ html`
244
+ <div class="flex">
245
+ <div class="chip bg-orange-100 text-orange-500">Analisis</div>
246
+ </div>
247
+ `
248
+ )
249
+ }
250
+
251
+ return chips
252
+ }
253
+
254
+ renderImage(post: Post) {
255
+ const { thumbnailMedium } = post.thumbnails?.sizes || {}
256
+ if (!thumbnailMedium) return ''
257
+
258
+ const { permalink, width, height } = thumbnailMedium
259
+ return html`
260
+ <img
261
+ src="${permalink}"
262
+ width="${width}"
263
+ height="${height}"
264
+ alt="${post.title}"
265
+ class="aspect-video object-cover w-full"
266
+ />
267
+ `
268
+ }
269
+
270
+ render() {
271
+ return html`
272
+ <div class="w-full">
273
+ <!-- start: widget title -->
274
+ ${this.WidgetTitle()}
275
+ <!-- end: widget title -->
276
+
277
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6 md:gap-8">
278
+ <!-- start: left-post-loop -->
279
+ <div class="grid grid-cols-1 gap-6">
280
+ ${this.posts[0]
281
+ ? this.posts[0].map(
282
+ post => html`
283
+ <div class="w-full">
284
+ <div class="flex">
285
+ <div class="w-1/2">${this.renderImage(post)}</div>
286
+ <div class="flex-grow pl-4 w-1/2">
287
+ <a href="${post.permalink}">
288
+ ${this.renderChips(post)}
289
+ <h5
290
+ class="hover:underline font-bold font-sans leading-tight text-grey-600"
291
+ >
292
+ ${post.title}
293
+ </h5>
294
+ <p class="text-grey-600 pt-2">
295
+ ${this.formatDate(post.publishedDate)}
296
+ </p>
297
+ </a>
298
+ </div>
299
+ </div>
300
+ </div>
301
+ `
302
+ )
303
+ : 'Belum ada artikel'}
304
+ </div>
305
+ <!-- end: left-post-loop -->
306
+
307
+ <!-- start: right-post-loop -->
308
+ <div class="flex flex-col w-full">
309
+ ${this.posts[1]
310
+ ? this.posts[1].map(
311
+ post => html`
312
+ <div class="mb-6">
313
+ <div class="flex">
314
+ <div class="w-1/2">${this.renderImage(post)}</div>
315
+ <div class="flex-grow pl-4 w-1/2">
316
+ <a href="${post.permalink}">
317
+ ${this.renderChips(post)}
318
+ <h5
319
+ class="hover:underline font-bold font-sans leading-tight text-grey-600"
320
+ >
321
+ ${post.title}
322
+ </h5>
323
+ <p class="text-grey-600 pt-2">
324
+ ${this.formatDate(post.publishedDate)}
325
+ </p>
326
+ </a>
327
+ </div>
328
+ </div>
329
+ </div>
330
+ `
331
+ )
332
+ : ''}
333
+ <!-- start: ads -->
334
+ <slot></slot>
335
+ <!-- end: ads -->
336
+ </div>
337
+ <!-- end: right-post-loop -->
338
+ </div>
339
+ </div>
340
+ `
341
+ }
342
+ }
@@ -0,0 +1,57 @@
1
+ # kompasid-widget-recirculations-list
2
+
3
+ Komponen ini adalah komponen web berbasis LitElement yang digunakan untuk menampilkan daftar aliran artikel dari Kompas.id.
4
+
5
+ ### Contoh Implementasi
6
+
7
+ ```javascript
8
+ const widgetRelatedPost = {
9
+ navigation: {
10
+ name: 'Artikel Terkait',
11
+ permalink: undefined
12
+ },
13
+ permalinkArticle: 'https://www.kompas.id/baca/opini/2024/05/02/pesan-bung-karno-jaga-persatuan-dan-keutuhan?open_from=Section_Artikel_Lainnya',
14
+ slugs: 'persatuan,bung-karno, surat pembaca, eduard lukman, bharoto, wira hardiprakoso, vision'
15
+ }
16
+
17
+ const widgetOtherPost = {
18
+ navigation: {
19
+ name: 'Lainnya Dalam Opini',
20
+ permalink: '/kategori/opini'
21
+ }
22
+ }
23
+
24
+ <div>
25
+ <kompasid-widget-recirculations-default
26
+ .navigation=${widgetRelatedPost.navigation}
27
+ .permalinkArticle=${widgetRelatedPost.permalinkArticle}
28
+ .slugs=${widgetRelatedPost.slugs}
29
+ ></kompasid-widget-recirculations-default>
30
+
31
+ <kompasid-widget-recirculations-default
32
+ .navigation=${widgetOtherPost.navigation}
33
+ type='otherArticle'
34
+ mainCategory='opini'
35
+ ></kompasid-widget-recirculations-default>
36
+ </div>
37
+ ```
38
+
39
+ ## Properti
40
+
41
+ | Property | Attribute | Deskripsi | Tipe | Default | Konten |
42
+ | ------------------ | --------------- | -------------------------------------------------------------------------------------------------- | -------- | --------------- | ------------------------------------------- |
43
+ | `navigation` | `navigation` | Navigasi yang berisi nama dan tautan ke kategori atau halaman terkait. Mengecek value `name` dan `permalink` | `Object` | `undefined` | `Navigation` |
44
+ | `userGuid` | `userGuid` | GUID pengguna yang sedang menggunakan aplikasi untuk fetch data artikel terkait. | `String` | `'0'` | |
45
+ | `slugs` | `slugs` | Daftar slug kategori atau tag yang terkait dengan artikel untuk artikel terkait. | `String` | `''` | |
46
+ | `permalinkArticle` | `permalinkArticle` | Tautan kategori artikel yang sedang ditampilkan atau dibaca untuk rekomendasi artikel terkait. | `String` | `''` | |
47
+ | `type` | `type` | Tipe widget untuk membedakan antara pengambilan data artikel terkait (`relatedArticle`) atau lainnya dalam kategori (`otherArticle`). | `String` | `'relatedArticle'` | `"relatedArticle" \| "otherArticle"` |
48
+ | `mainCategory` | `mainCategory` | Kategori utama artikel yang akan ditampilkan jika menggunakan tipe `otherArticle` untuk lainnya dalam kategori. | `String` | `''` | |
49
+
50
+
51
+ ### Digunakan oleh
52
+
53
+ - [kompasid-widget-recirculations-default](../kompasid-widget-recirculations-default)
54
+
55
+ ## Kontributor
56
+
57
+ *Dokumentasi ini dibuat oleh tim front-end Kompas.id.*
@@ -0,0 +1,28 @@
1
+ interface PostTag {
2
+ slug: string
3
+ }
4
+
5
+ export interface Post {
6
+ title: string
7
+ isAnalisis?: boolean
8
+ isEksklusif?: boolean
9
+ isFreemium?: boolean
10
+ featuredImageThumbnailMedium: string
11
+ permalink: string
12
+ publishedDate: string
13
+ postTag?: PostTag[]
14
+ thumbnails: {
15
+ sizes: {
16
+ thumbnailMedium: {
17
+ permalink: string
18
+ width: number
19
+ height: number
20
+ }
21
+ }
22
+ }
23
+ }
24
+
25
+ export interface Navigation {
26
+ name: string
27
+ permalink: string
28
+ }