@bbki.ng/bbblog 0.0.2 → 0.0.4
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 +75 -0
- package/dist/index.js +1 -1
- package/example/favicon.svg +9 -0
- package/example/index.html +22 -0
- package/example/posts.json +12 -0
- package/package.json +1 -1
- package/src/index.ts +11 -6
package/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# bbblog
|
|
2
|
+
|
|
3
|
+
A minimal web component for rendering blog posts.
|
|
4
|
+
|
|
5
|
+
**Demo:** [b.bbki.ng](https://b.bbki.ng)
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @bbki.ng/bbblog
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or use via CDN:
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/@bbki.ng/bbblog@0.0.3/dist/index.js"></script>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```html
|
|
22
|
+
<bb-blog content="/posts.json">
|
|
23
|
+
<!-- Fallback content shown if fetch fails -->
|
|
24
|
+
<p>Loading...</p>
|
|
25
|
+
</bb-blog>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Custom Logo
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<bb-blog content="/posts.json" logo="data:image/svg+xml;base64,xxxxx">
|
|
32
|
+
</bb-blog>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### JSON Format
|
|
36
|
+
|
|
37
|
+
The `content` attribute should point to a JSON file with an array of posts:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
[
|
|
41
|
+
{
|
|
42
|
+
"title": "Hello World",
|
|
43
|
+
"content": "<p>This is my first post.</p>"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"title": "Another Post",
|
|
47
|
+
"content": "<p>More content here.</p>"
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Components
|
|
53
|
+
|
|
54
|
+
### `<bb-blog>`
|
|
55
|
+
|
|
56
|
+
Main container component that fetches and displays posts.
|
|
57
|
+
|
|
58
|
+
| Attribute | Description |
|
|
59
|
+
|-----------|-------------|
|
|
60
|
+
| `content` | URL to JSON file containing posts |
|
|
61
|
+
| `logo` | Custom logo image (base64 data URI or URL). Falls back to default if not provided |
|
|
62
|
+
|
|
63
|
+
### `<bb-post>`
|
|
64
|
+
|
|
65
|
+
Individual post component (used internally by `<bb-blog>`).
|
|
66
|
+
|
|
67
|
+
| Property | Description |
|
|
68
|
+
|----------|-------------|
|
|
69
|
+
| `title` | Post title |
|
|
70
|
+
| `content` | Post HTML content |
|
|
71
|
+
| `date` | Post date |
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
MIT
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const LOGO_SRC="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyNCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE3LjMzMjEgNy4zNDc0MUMyMC4yNzY5IDcuMzQ3NDEgMjIuNjY0MSA0Ljk2MDE3IDIyLjY2NDEgMi4wMTUzNlYxMC42NjQxQzIyLjY2NDEgMTEuNzcwOCAyMS43NjcgMTIuNjY3OSAyMC42NjAzIDEyLjY2NzlIMy4zMzk3M0MyLjIzMzA0IDEyLjY2NzkgMS4zMzU4OSAxMS43NzA4IDEuMzM1ODkgMTAuNjY0MVYyLjAxNTM2QzEuMzM1ODkgNC45NjAxNyAzLjcyMzE0IDcuMzQ3NDEgNi42Njc5NSA3LjM0NzQxQzkuNjEyNzYgNy4zNDc0MSAxMiA0Ljk2MDE3IDEyIDIuMDE1MzZDMTIgNC45NjAxNyAxNC4zODcyIDcuMzQ3NDEgMTcuMzMyMSA3LjM0NzQxWiIgZmlsbD0iIzlDQTNBRiIvPgo8cGF0aCBkPSJNMTIgMi4wMDM4NEwxMiAyLjAxNTM2QzEyIDIuMDExNTEgMTIgMi4wMDc2OCAxMiAyLjAwMzg0WiIgZmlsbD0iIzlDQTNBRiIvPgo8cGF0aCBkPSJNMTEuMzMyMSAxNC4wMDM4QzExLjMzODMgMTYuOTQzNCAxMy43MjMxIDE5LjMyNDQgMTYuNjY0MSAxOS4zMjQ0QzE5LjYwNTEgMTkuMzI0NCAyMS45ODk5IDE2Ljk0MzQgMjEuOTk2MiAxNC4wMDM4SDExLjMzMjFaIiBmaWxsPSIjOUNBM0FGIi8+CjxwYXRoIGQ9Ik0yLjAwMzg0IDE0LjAwMzhDMi4wMDM4NCAxNC4wMDc3IDIuMDAzODMgMTQuMDExNSAyLjAwMzg0IDE0LjAxNTRDMi4wMTAwNiAxNi45NTQ5IDQuMzk0OTMgMTkuMzM1OSA3LjMzNTkgMTkuMzM1OUMxMC4yNzY5IDE5LjMzNTkgMTIuNjYxNyAxNi45NTQ5IDEyLjY2NzkgMTQuMDE1NEgyLjAwMzg0VjE0LjAwMzhaIiBmaWxsPSIjOUNBM0FGIi8+CjxwYXRoIGQ9Ik0yLjY3MTc5IDIuMDAzODRDMi42NzE3OSAyLjc0MTYzIDIuMDczNjkgMy4zMzk3MyAxLjMzNTg5IDMuMzM5NzNDMC41OTgwOTkgMy4zMzk3MyAwIDIuNzQxNjMgMCAyLjAwMzg0QzAgMS4yNjYwNSAwLjU5ODA5OSAwLjY2Nzk0NiAxLjMzNTg5IDAuNjY3OTQ2QzIuMDczNjkgMC42Njc5NDYgMi42NzE3OSAxLjI2NjA1IDIuNjcxNzkgMi4wMDM4NFoiIGZpbGw9IiM5Q0EzQUYiLz4KPHBhdGggZD0iTTEzLjMzNTkgMS4zMzU4OUMxMy4zMzU5IDIuMDczNjkgMTIuNzM3OCAyLjY3MTc5IDEyIDIuNjcxNzlDMTEuMjYyMiAyLjY3MTc5IDEwLjY2NDEgMi4wNzM2OSAxMC42NjQxIDEuMzM1ODlDMTAuNjY0MSAwLjU5ODA5OSAxMS4yNjIyIDAgMTIgMEMxMi43Mzc4IDAgMTMuMzM1OSAwLjU5ODA5OSAxMy4zMzU5IDEuMzM1ODlaIiBmaWxsPSIjOUNBM0FGIi8+CjxwYXRoIGQ9Ik0yNCAyLjAwMzg0QzI0IDIuNzQxNjMgMjMuNDAxOSAzLjMzOTczIDIyLjY2NDEgMy4zMzk3M0MyMS45MjYzIDMuMzM5NzMgMjEuMzI4MiAyLjc0MTYzIDIxLjMyODIgMi4wMDM4NEMyMS4zMjgyIDEuMjY2MDUgMjEuOTI2MyAwLjY2Nzk0NiAyMi42NjQxIDAuNjY3OTQ2QzIzLjQwMTkgMC42Njc5NDYgMjQgMS4yNjYwNSAyNCAyLjAwMzg0WiIgZmlsbD0iIzlDQTNBRiIvPgo8L3N2Zz4K";class BBPost extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).innerHTML='\n <style>\n .post{margin-bottom: 100px}\n .post-title{font-size:1.2em}\n .post-content{margin-top:4px;color:#121111}\n .post-date{font-size:.8em;color:#999}\n a {color: #007fff; text-decoration: none;}\n </style>\n <div class="post">\n <div class="post-title"></div>\n <div class="post-date"></div>\n <div class="post-content"></div>\n </div>'}set title(M){this.shadowRoot.querySelector(".post-title").textContent=M}set content(M){this.shadowRoot.querySelector(".post-content").innerHTML=M}set date(M){this.shadowRoot.querySelector(".post-date").textContent=M}}class BBBlog extends HTMLElement{static get observedAttributes(){return["content"]}constructor(){super(),this.attachShadow({mode:"open"})}connectedCallback(){this.render()}attributeChangedCallback(M,t,
|
|
1
|
+
"use strict";const LOGO_SRC="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyNCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE3LjMzMjEgNy4zNDc0MUMyMC4yNzY5IDcuMzQ3NDEgMjIuNjY0MSA0Ljk2MDE3IDIyLjY2NDEgMi4wMTUzNlYxMC42NjQxQzIyLjY2NDEgMTEuNzcwOCAyMS43NjcgMTIuNjY3OSAyMC42NjAzIDEyLjY2NzlIMy4zMzk3M0MyLjIzMzA0IDEyLjY2NzkgMS4zMzU4OSAxMS43NzA4IDEuMzM1ODkgMTAuNjY0MVYyLjAxNTM2QzEuMzM1ODkgNC45NjAxNyAzLjcyMzE0IDcuMzQ3NDEgNi42Njc5NSA3LjM0NzQxQzkuNjEyNzYgNy4zNDc0MSAxMiA0Ljk2MDE3IDEyIDIuMDE1MzZDMTIgNC45NjAxNyAxNC4zODcyIDcuMzQ3NDEgMTcuMzMyMSA3LjM0NzQxWiIgZmlsbD0iIzlDQTNBRiIvPgo8cGF0aCBkPSJNMTIgMi4wMDM4NEwxMiAyLjAxNTM2QzEyIDIuMDExNTEgMTIgMi4wMDc2OCAxMiAyLjAwMzg0WiIgZmlsbD0iIzlDQTNBRiIvPgo8cGF0aCBkPSJNMTEuMzMyMSAxNC4wMDM4QzExLjMzODMgMTYuOTQzNCAxMy43MjMxIDE5LjMyNDQgMTYuNjY0MSAxOS4zMjQ0QzE5LjYwNTEgMTkuMzI0NCAyMS45ODk5IDE2Ljk0MzQgMjEuOTk2MiAxNC4wMDM4SDExLjMzMjFaIiBmaWxsPSIjOUNBM0FGIi8+CjxwYXRoIGQ9Ik0yLjAwMzg0IDE0LjAwMzhDMi4wMDM4NCAxNC4wMDc3IDIuMDAzODMgMTQuMDExNSAyLjAwMzg0IDE0LjAxNTRDMi4wMTAwNiAxNi45NTQ5IDQuMzk0OTMgMTkuMzM1OSA3LjMzNTkgMTkuMzM1OUMxMC4yNzY5IDE5LjMzNTkgMTIuNjYxNyAxNi45NTQ5IDEyLjY2NzkgMTQuMDE1NEgyLjAwMzg0VjE0LjAwMzhaIiBmaWxsPSIjOUNBM0FGIi8+CjxwYXRoIGQ9Ik0yLjY3MTc5IDIuMDAzODRDMi42NzE3OSAyLjc0MTYzIDIuMDczNjkgMy4zMzk3MyAxLjMzNTg5IDMuMzM5NzNDMC41OTgwOTkgMy4zMzk3MyAwIDIuNzQxNjMgMCAyLjAwMzg0QzAgMS4yNjYwNSAwLjU5ODA5OSAwLjY2Nzk0NiAxLjMzNTg5IDAuNjY3OTQ2QzIuMDczNjkgMC42Njc5NDYgMi42NzE3OSAxLjI2NjA1IDIuNjcxNzkgMi4wMDM4NFoiIGZpbGw9IiM5Q0EzQUYiLz4KPHBhdGggZD0iTTEzLjMzNTkgMS4zMzU4OUMxMy4zMzU5IDIuMDczNjkgMTIuNzM3OCAyLjY3MTc5IDEyIDIuNjcxNzlDMTEuMjYyMiAyLjY3MTc5IDEwLjY2NDEgMi4wNzM2OSAxMC42NjQxIDEuMzM1ODlDMTAuNjY0MSAwLjU5ODA5OSAxMS4yNjIyIDAgMTIgMEMxMi43Mzc4IDAgMTMuMzM1OSAwLjU5ODA5OSAxMy4zMzU5IDEuMzM1ODlaIiBmaWxsPSIjOUNBM0FGIi8+CjxwYXRoIGQ9Ik0yNCAyLjAwMzg0QzI0IDIuNzQxNjMgMjMuNDAxOSAzLjMzOTczIDIyLjY2NDEgMy4zMzk3M0MyMS45MjYzIDMuMzM5NzMgMjEuMzI4MiAyLjc0MTYzIDIxLjMyODIgMi4wMDM4NEMyMS4zMjgyIDEuMjY2MDUgMjEuOTI2MyAwLjY2Nzk0NiAyMi42NjQxIDAuNjY3OTQ2QzIzLjQwMTkgMC42Njc5NDYgMjQgMS4yNjYwNSAyNCAyLjAwMzg0WiIgZmlsbD0iIzlDQTNBRiIvPgo8L3N2Zz4K";class BBPost extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).innerHTML='\n <style>\n .post{margin-bottom: 100px}\n .post-title{font-size:1.2em}\n .post-content{margin-top:4px;color:#121111;text-autospace: normal;}\n .post-date{font-size:.8em;color:#999}\n a {color: #007fff; text-decoration: none;}\n </style>\n <div class="post">\n <div class="post-title"></div>\n <div class="post-date"></div>\n <div class="post-content"></div>\n </div>'}set title(M){this.shadowRoot.querySelector(".post-title").textContent=M}set content(M){this.shadowRoot.querySelector(".post-content").innerHTML=M}set date(M){this.shadowRoot.querySelector(".post-date").textContent=M}}class BBBlog extends HTMLElement{static get observedAttributes(){return["content","logo"]}constructor(){super(),this.attachShadow({mode:"open"})}connectedCallback(){this.render(),this.fetchPosts()}attributeChangedCallback(M,t,o){if("content"===M&&null!==t&&t!==o&&this.isConnected&&this.fetchPosts(),"logo"===M&&this.isConnected){const M=this.shadowRoot.querySelector(".logo");M&&(M.src=o||LOGO_SRC)}}render(){const M=this.getAttribute("logo")||LOGO_SRC;this.shadowRoot.innerHTML=`\n <style>\n .posts-container {\n display: grid;\n grid-template-columns: 1fr min(45rem, 84%) 1fr;\n line-height: 1.65;\n }\n .posts-container > * {\n grid-column: 2;\n }\n .logo {\n display: block;\n width: 24px;\n margin: 100px 0;\n }\n @media (min-width: 768px) {\n .posts-container {\n grid-template-columns: 1fr min(45rem, 34%) 1fr;\n }\n }\n </style>\n <div class="posts-container">\n <img class="logo" src="${M}" alt="logo">\n <div class="fallback" style="display:none;"><slot></slot></div>\n </div>\n `}async fetchPosts(){const M=this.getAttribute("content");if(!M)return;const t=this.shadowRoot.querySelector(".posts-container"),o=this.shadowRoot.querySelector(".fallback");try{const e=await fetch(M);if(!e.ok)throw new Error("Fetch failed");const n=await e.json();o&&(o.style.display="none"),n.forEach(M=>{const o=document.createElement("bb-post");o.title=M.title,o.content=M.content,t?.appendChild(o)})}catch(M){t&&(t.innerHTML=""),o&&(o.style.display="block")}}}customElements.define("bb-post",BBPost),customElements.define("bb-blog",BBBlog);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<svg width="24" height="20" viewBox="0 0 24 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M17.3321 7.34741C20.2769 7.34741 22.6641 4.96017 22.6641 2.01536V10.6641C22.6641 11.7708 21.767 12.6679 20.6603 12.6679H3.33973C2.23304 12.6679 1.33589 11.7708 1.33589 10.6641V2.01536C1.33589 4.96017 3.72314 7.34741 6.66795 7.34741C9.61276 7.34741 12 4.96017 12 2.01536C12 4.96017 14.3872 7.34741 17.3321 7.34741Z" fill="#121111"/>
|
|
3
|
+
<path d="M12 2.00384L12 2.01536C12 2.01151 12 2.00768 12 2.00384Z" fill="#121111"/>
|
|
4
|
+
<path d="M11.3321 14.0038C11.3383 16.9434 13.7231 19.3244 16.6641 19.3244C19.6051 19.3244 21.9899 16.9434 21.9962 14.0038H11.3321Z" fill="#121111"/>
|
|
5
|
+
<path d="M2.00384 14.0038C2.00384 14.0077 2.00383 14.0115 2.00384 14.0154C2.01006 16.9549 4.39493 19.3359 7.3359 19.3359C10.2769 19.3359 12.6617 16.9549 12.6679 14.0154H2.00384V14.0038Z" fill="#121111"/>
|
|
6
|
+
<path d="M2.67179 2.00384C2.67179 2.74163 2.07369 3.33973 1.33589 3.33973C0.598099 3.33973 0 2.74163 0 2.00384C0 1.26605 0.598099 0.667946 1.33589 0.667946C2.07369 0.667946 2.67179 1.26605 2.67179 2.00384Z" fill="#121111"/>
|
|
7
|
+
<path d="M13.3359 1.33589C13.3359 2.07369 12.7378 2.67179 12 2.67179C11.2622 2.67179 10.6641 2.07369 10.6641 1.33589C10.6641 0.598099 11.2622 0 12 0C12.7378 0 13.3359 0.598099 13.3359 1.33589Z" fill="#121111"/>
|
|
8
|
+
<path d="M24 2.00384C24 2.74163 23.4019 3.33973 22.6641 3.33973C21.9263 3.33973 21.3282 2.74163 21.3282 2.00384C21.3282 1.26605 21.9263 0.667946 22.6641 0.667946C23.4019 0.667946 24 1.26605 24 2.00384Z" fill="#121111"/>
|
|
9
|
+
</svg>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>b.bbki.ng</title>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
7
|
+
<meta name="description" content="plan b or backup for b.bking">
|
|
8
|
+
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyNCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE3LjMzMjEgNy4zNDc0MUMyMC4yNzY5IDcuMzQ3NDEgMjIuNjY0MSA0Ljk2MDE3IDIyLjY2NDEgMi4wMTUzNlYxMC42NjQxQzIyLjY2NDEgMTEuNzcwOCAyMS43NjcgMTIuNjY3OSAyMC42NjAzIDEyLjY2NzlIMy4zMzk3M0MyLjIzMzA0IDEyLjY2NzkgMS4zMzU4OSAxMS43NzA4IDEuMzM1ODkgMTAuNjY0MVYyLjAxNTM2QzEuMzM1ODkgNC45NjAxNyAzLjcyMzE0IDcuMzQ3NDEgNi42Njc5NSA3LjM0NzQxQzkuNjEyNzYgNy4zNDc0MSAxMiA0Ljk2MDE3IDEyIDIuMDE1MzZDMTIgNC45NjAxNyAxNC4zODcyIDcuMzQ3NDEgMTcuMzMyMSA3LjM0NzQxWiIgZmlsbD0iIzlDQTNBRiIvPgo8cGF0aCBkPSJNMTIgMi4wMDM4NEwxMiAyLjAxNTM2QzEyIDIuMDExNTEgMTIgMi4wMDc2OCAxMiAyLjAwMzg0WiIgZmlsbD0iIzlDQTNBRiIvPgo8cGF0aCBkPSJNMTEuMzMyMSAxNC4wMDM4QzExLjMzODMgMTYuOTQzNCAxMy43MjMxIDE5LjMyNDQgMTYuNjY0MSAxOS4zMjQ0QzE5LjYwNTEgMTkuMzI0NCAyMS45ODk5IDE2Ljk0MzQgMjEuOTk2MiAxNC4wMDM4SDExLjMzMjFaIiBmaWxsPSIjOUNBM0FGIi8+CjxwYXRoIGQ9Ik0yLjAwMzg0IDE0LjAwMzhDMi4wMDM4NCAxNC4wMDc3IDIuMDAzODMgMTQuMDExNSAyLjAwMzg0IDE0LjAxNTRDMi4wMTAwNiAxNi45NTQ5IDQuMzk0OTMgMTkuMzM1OSA3LjMzNTkgMTkuMzM1OUMxMC4yNzY5IDE5LjMzNTkgMTIuNjYxNyAxNi45NTQ5IDEyLjY2NzkgMTQuMDE1NEgyLjAwMzg0VjE0LjAwMzhaIiBmaWxsPSIjOUNBM0FGIi8+CjxwYXRoIGQ9Ik0yLjY3MTc5IDIuMDAzODRDMi42NzE3OSAyLjc0MTYzIDIuMDczNjkgMy4zMzk3MyAxLjMzNTg5IDMuMzM5NzNDMC41OTgwOTkgMy4zMzk3MyAwIDIuNzQxNjMgMCAyLjAwMzg0QzAgMS4yNjYwNSAwLjU5ODA5OSAwLjY2Nzk0NiAxLjMzNTg5IDAuNjY3OTQ2QzIuMDczNjkgMC42Njc5NDYgMi42NzE3OSAxLjI2NjA1IDIuNjcxNzkgMi4wMDM4NFoiIGZpbGw9IiM5Q0EzQUYiLz4KPHBhdGggZD0iTTEzLjMzNTkgMS4zMzU4OUMxMy4zMzU5IDIuMDczNjkgMTIuNzM3OCAyLjY3MTc5IDEyIDIuNjcxNzlDMTEuMjYyMiAyLjY3MTc5IDEwLjY2NDEgMi4wNzM2OSAxMC42NjQxIDEuMzM1ODlDMTAuNjY0MSAwLjU5ODA5OSAxMS4yNjIyIDAgMTIgMEMxMi43Mzc4IDAgMTMuMzM1OSAwLjU5ODA5OSAxMy4zMzU5IDEuMzM1ODlaIiBmaWxsPSIjOUNBM0FGIi8+CjxwYXRoIGQ9Ik0yNCAyLjAwMzg0QzI0IDIuNzQxNjMgMjMuNDAxOSAzLjMzOTczIDIyLjY2NDEgMy4zMzk3M0MyMS45MjYzIDMuMzM5NzMgMjEuMzI4MiAyLjc0MTYzIDIxLjMyODIgMi4wMDM4NEMyMS4zMjgyIDEuMjY2MDUgMjEuOTI2MyAwLjY2Nzk0NiAyMi42NjQxIDAuNjY3OTQ2QzIzLjQwMTkgMC42Njc5NDYgMjQgMS4yNjYwNSAyNCAyLjAwMzg0WiIgZmlsbD0iIzlDQTNBRiIvPgo8L3N2Zz4K">
|
|
9
|
+
<script src="../dist/index.js" type="module"></script>
|
|
10
|
+
<style>
|
|
11
|
+
body {
|
|
12
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
|
|
13
|
+
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
|
|
14
|
+
margin: 0;
|
|
15
|
+
background: #b3b2ac;
|
|
16
|
+
}
|
|
17
|
+
</style>
|
|
18
|
+
</head>
|
|
19
|
+
<body>
|
|
20
|
+
<bb-blog content="posts.json" logo="./favicon.svg"></bb-blog>
|
|
21
|
+
</body>
|
|
22
|
+
</html>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"title": "早",
|
|
4
|
+
"content": "<p>早<br />\n早<br />\n吃了吗?<br />\n吃了<br />\n吃的啥?<br />\n粥<br />\n挺好</p>",
|
|
5
|
+
"created_at": "2026-01-17T07:18:47.658Z"
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"title": "键盘",
|
|
9
|
+
"content": "<p>拥有自己的电脑后,只要手没在键盘上,就会觉得在浪费时间。现在慢慢会觉得,手在键盘上才是一种浪费。开始珍惜刷牙、剪指甲、擦眼镜、喝水、走路、洗碗的时间。</p>",
|
|
10
|
+
"created_at": "2026-01-17T14:07:08.412Z"
|
|
11
|
+
}
|
|
12
|
+
]
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -7,7 +7,7 @@ class BBPost extends HTMLElement {
|
|
|
7
7
|
<style>
|
|
8
8
|
.post{margin-bottom: 100px}
|
|
9
9
|
.post-title{font-size:1.2em}
|
|
10
|
-
.post-content{margin-top:4px;color:#121111}
|
|
10
|
+
.post-content{margin-top:4px;color:#121111;text-autospace: normal;}
|
|
11
11
|
.post-date{font-size:.8em;color:#999}
|
|
12
12
|
a {color: #007fff; text-decoration: none;}
|
|
13
13
|
</style>
|
|
@@ -24,7 +24,7 @@ class BBPost extends HTMLElement {
|
|
|
24
24
|
|
|
25
25
|
class BBBlog extends HTMLElement {
|
|
26
26
|
static get observedAttributes() {
|
|
27
|
-
return ['content'];
|
|
27
|
+
return ['content', 'logo'];
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
constructor() {
|
|
@@ -34,16 +34,21 @@ class BBBlog extends HTMLElement {
|
|
|
34
34
|
|
|
35
35
|
connectedCallback() {
|
|
36
36
|
this.render();
|
|
37
|
-
|
|
37
|
+
this.fetchPosts();
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {
|
|
41
|
-
if (name === 'content' && oldValue !== newValue && this.isConnected) {
|
|
41
|
+
if (name === 'content' && oldValue !== null && oldValue !== newValue && this.isConnected) {
|
|
42
42
|
this.fetchPosts();
|
|
43
43
|
}
|
|
44
|
+
if (name === 'logo' && this.isConnected) {
|
|
45
|
+
const logoEl = this.shadowRoot!.querySelector('.logo') as HTMLImageElement | null;
|
|
46
|
+
if (logoEl) logoEl.src = newValue || LOGO_SRC;
|
|
47
|
+
}
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
render() {
|
|
51
|
+
const logoSrc = this.getAttribute('logo') || LOGO_SRC;
|
|
47
52
|
this.shadowRoot!.innerHTML = `
|
|
48
53
|
<style>
|
|
49
54
|
.posts-container {
|
|
@@ -66,7 +71,7 @@ class BBBlog extends HTMLElement {
|
|
|
66
71
|
}
|
|
67
72
|
</style>
|
|
68
73
|
<div class="posts-container">
|
|
69
|
-
<img class="logo" src="${
|
|
74
|
+
<img class="logo" src="${logoSrc}" alt="logo">
|
|
70
75
|
<div class="fallback" style="display:none;"><slot></slot></div>
|
|
71
76
|
</div>
|
|
72
77
|
`;
|
|
@@ -100,4 +105,4 @@ class BBBlog extends HTMLElement {
|
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
customElements.define('bb-post', BBPost);
|
|
103
|
-
customElements.define('bb-blog', BBBlog);
|
|
108
|
+
customElements.define('bb-blog', BBBlog);
|