nostr-components 0.2.7 → 0.3.1
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 +115 -186
- package/dist/assets/{base-styles-BSEzBDsk.js → base-styles-Dmuzg8I4.js} +2 -2
- package/dist/assets/{base-styles-BSEzBDsk.js.map → base-styles-Dmuzg8I4.js.map} +1 -1
- package/dist/assets/{copy-delegation-B7y2q5Kn.js → copy-delegation-xzt-t_do.js} +2 -2
- package/dist/assets/{copy-delegation-B7y2q5Kn.js.map → copy-delegation-xzt-t_do.js.map} +1 -1
- package/dist/assets/dialog-component-Da1ZIYh9.js.map +1 -1
- package/dist/assets/{dialog-likers-BqDn2P_3.js → dialog-likers-B15m_NxI.js} +5 -5
- package/dist/assets/dialog-likers-B15m_NxI.js.map +1 -0
- package/dist/assets/index.esm-ByUtE_cm.js +2159 -0
- package/dist/assets/index.esm-ByUtE_cm.js.map +1 -0
- package/dist/assets/nip05-utils-BNBHUmkr.js.map +1 -1
- package/dist/assets/nostr-login-service-D2FmscPI.js +2 -0
- package/dist/assets/nostr-login-service-D2FmscPI.js.map +1 -0
- package/dist/assets/nostr-service-CA0Qx4nJ.js +266 -0
- package/dist/assets/nostr-service-CA0Qx4nJ.js.map +1 -0
- package/dist/assets/{nostr-user-component-Cbs97dlK.js → nostr-user-component-r-MUbTL6.js} +2 -2
- package/dist/assets/{nostr-user-component-Cbs97dlK.js.map → nostr-user-component-r-MUbTL6.js.map} +1 -1
- package/dist/assets/{pure-DPo-pzxM.js → pure-DOoUcNQv.js} +2 -2
- package/dist/assets/pure-DOoUcNQv.js.map +1 -0
- package/dist/assets/theme-BN1Bvweb.js.map +1 -1
- package/dist/assets/{user-resolver-CMmbtY9Y.js → user-resolver-ArI0680e.js} +2 -2
- package/dist/assets/{user-resolver-CMmbtY9Y.js.map → user-resolver-ArI0680e.js.map} +1 -1
- package/dist/assets/utils--bxLbhGF.js.map +1 -1
- package/dist/assets/zap-utils-QRxLBOst.js +2 -0
- package/dist/assets/zap-utils-QRxLBOst.js.map +1 -0
- package/dist/components/nostr-comment.es.js +26 -26
- package/dist/components/nostr-comment.es.js.map +1 -1
- package/dist/components/nostr-dm.es.js +2 -2
- package/dist/components/nostr-dm.es.js.map +1 -1
- package/dist/components/nostr-follow-button.es.js +6 -7
- package/dist/components/nostr-follow-button.es.js.map +1 -1
- package/dist/components/nostr-like.es.js +16 -16
- package/dist/components/nostr-like.es.js.map +1 -1
- package/dist/components/nostr-live-chat.es.js +3 -3
- package/dist/components/nostr-live-chat.es.js.map +1 -1
- package/dist/components/nostr-post.es.js +19 -19
- package/dist/components/nostr-post.es.js.map +1 -1
- package/dist/components/nostr-profile-badge.es.js +2 -2
- package/dist/components/nostr-profile-badge.es.js.map +1 -1
- package/dist/components/nostr-profile.es.js +5 -5
- package/dist/components/nostr-profile.es.js.map +1 -1
- package/dist/components/nostr-zap.es.js +24 -24
- package/dist/components/nostr-zap.es.js.map +1 -1
- package/dist/nostr-components.es.js +1 -1
- package/dist/nostr-components.es.js.map +1 -1
- package/dist/nostr-components.umd.js +2669 -301
- package/dist/nostr-components.umd.js.map +1 -1
- package/dist/src/common/constants.d.ts +1 -1
- package/dist/src/common/nostr-login-service.d.ts +26 -0
- package/dist/src/nostr-dm/nostr-dm.d.ts +1 -1
- package/dist/src/nostr-like/like-utils.d.ts +2 -6
- package/dist/src/nostr-live-chat/nostr-live-chat.d.ts +1 -1
- package/dist/src/nostr-zap/zap-utils.d.ts +4 -0
- package/package.json +5 -2
- package/dist/assets/dialog-likers-BqDn2P_3.js.map +0 -1
- package/dist/assets/nostr-service-CnaPxjc6.js +0 -78
- package/dist/assets/nostr-service-CnaPxjc6.js.map +0 -1
- package/dist/assets/pure-DPo-pzxM.js.map +0 -1
- package/dist/assets/zap-utils-KFUD_vTU.js +0 -2
- package/dist/assets/zap-utils-KFUD_vTU.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,163 +6,113 @@
|
|
|
6
6
|
|
|
7
7
|
Nostr Components makes it easy to embed Zap button, Nostr profiles, posts, and follow buttons in any website. Inspired by <a href="https://unpkg.com/nostr-web-components@0.0.15/demo.html">fiatjaf's Nostr Web Components</a>, this project adds a beautiful UI, a Storybook component generator (for webmasters), and allows embedding Nostr content anywhere on the Internet.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
🔹 **[Nostr Comment](#8-nostr-comment-)** - Decentralized comment system for any website (Under construction)
|
|
17
|
-
🔹 **[Wordpress Integration](#9-wordpress-integration)** - Wordpress Integration
|
|
9
|
+
* **[Zap button](#1-nostr-zap)**
|
|
10
|
+
* **[Follow button](#2-nostr-follow)**
|
|
11
|
+
* **[Like button](#3-nostr-like)**
|
|
12
|
+
* **[Profile Badge](#4-nostr-profile-badge)**
|
|
13
|
+
* **[Profile](#5-nostr-profile)**
|
|
14
|
+
* **[Post](#6-nostr-post)**
|
|
15
|
+
* **[WordPress Integration](#7-wordpress-integration)**
|
|
18
16
|
|
|
19
17
|
## 🛠️ Usage
|
|
20
18
|
|
|
21
|
-
###
|
|
19
|
+
### Quick Start
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
#### Option 1: CDN (Recommended for Quick Integration)
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
// Import the main package - this automatically registers all components
|
|
27
|
-
import 'nostr-components';
|
|
28
|
-
|
|
29
|
-
// Or import specific components only
|
|
30
|
-
import 'nostr-components/components/nostr-like';
|
|
31
|
-
import 'nostr-components/components/nostr-zap';
|
|
32
|
-
|
|
33
|
-
// Import themes
|
|
34
|
-
import 'nostr-components/themes/dark';
|
|
35
|
-
// or
|
|
36
|
-
import 'nostr-components/themes/light';
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Then use the components in your JSX/HTML:
|
|
40
|
-
|
|
41
|
-
```tsx
|
|
42
|
-
function MyComponent() {
|
|
43
|
-
return (
|
|
44
|
-
<>
|
|
45
|
-
<nostr-like url="https://example.com" text="Like" />
|
|
46
|
-
<nostr-zap npub="npub1..." theme="dark" />
|
|
47
|
-
</>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
**Note:** When importing from the main package (`import 'nostr-components'`), all components are automatically registered. Individual component imports also work and register only that component.
|
|
53
|
-
|
|
54
|
-
### Option 2: Direct Script Tag Usage
|
|
55
|
-
|
|
56
|
-
For direct HTML usage without a bundler:
|
|
23
|
+
Add the component script to your HTML's `<head>`. Each component can be loaded individually or use the full bundle.
|
|
57
24
|
|
|
58
25
|
```html
|
|
59
26
|
<head>
|
|
60
|
-
<!--
|
|
61
|
-
<script src="
|
|
62
|
-
|
|
27
|
+
<!-- Load individual component (recommended for smaller bundles) -->
|
|
28
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/nostr-components@latest/dist/components/nostr-follow-button.es.js"></script>
|
|
29
|
+
|
|
30
|
+
<!-- Or load the full bundle -->
|
|
31
|
+
<script src="https://cdn.jsdelivr.net/npm/nostr-components@latest/dist/nostr-components.umd.js"></script>
|
|
32
|
+
<!-- Components auto-register when the script loads, no init() needed -->
|
|
33
|
+
<!-- Optional: Call init() for explicit initialization (for backward compatibility) -->
|
|
63
34
|
<script>
|
|
64
|
-
//
|
|
65
|
-
|
|
35
|
+
// Components are already registered automatically
|
|
36
|
+
// You can optionally call init() for explicit initialization
|
|
37
|
+
if (window.NostrComponents && window.NostrComponents.default) {
|
|
38
|
+
window.NostrComponents.default.init();
|
|
39
|
+
} else if (window.NostrComponents && window.NostrComponents.init) {
|
|
40
|
+
// Fallback: use named export
|
|
41
|
+
window.NostrComponents.init();
|
|
42
|
+
}
|
|
66
43
|
</script>
|
|
67
|
-
|
|
68
|
-
<!-- Optional: Glide.js CSS for Post Carousel -->
|
|
69
|
-
<!-- Needed only if displaying posts that might contain multiple images/videos -->
|
|
70
|
-
<link
|
|
71
|
-
rel="stylesheet"
|
|
72
|
-
href="https://cdn.jsdelivr.net/npm/@glidejs/glide/dist/css/glide.core.min.css"
|
|
73
|
-
/>
|
|
74
|
-
<link
|
|
75
|
-
rel="stylesheet"
|
|
76
|
-
href="https://cdn.jsdelivr.net/npm/@glidejs/glide/dist/css/glide.theme.min.css"
|
|
77
|
-
/>
|
|
78
44
|
</head>
|
|
79
45
|
```
|
|
80
46
|
|
|
81
|
-
|
|
82
|
-
- **ES Module:** Use `<script type="module">import NostrComponents from './dist/nostr-components.es.js'; NostrComponents.init();</script>`.
|
|
83
|
-
|
|
84
|
-
_Note: Replace `./dist/nostr-components._.js`with the actual path to the file on your server or use a CDN link if available (e.g.,`https://nostr-components.web.app/dist/nostr-components.umd.js`).\*
|
|
85
|
-
|
|
86
|
-
### Using the Components
|
|
47
|
+
#### Option 2: NPM Package
|
|
87
48
|
|
|
88
|
-
|
|
49
|
+
Install the package via npm:
|
|
89
50
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
51
|
+
```bash
|
|
52
|
+
npm install nostr-components
|
|
53
|
+
```
|
|
93
54
|
|
|
94
|
-
|
|
55
|
+
Then import components in your JavaScript/TypeScript:
|
|
95
56
|
|
|
96
|
-
|
|
57
|
+
```javascript
|
|
58
|
+
// Import individual components
|
|
59
|
+
import 'nostr-components/dist/components/nostr-follow-button.es.js';
|
|
60
|
+
import 'nostr-components/dist/components/nostr-zap.es.js';
|
|
61
|
+
import 'nostr-components/dist/components/nostr-like.es.js';
|
|
97
62
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
<script
|
|
101
|
-
type="module"
|
|
102
|
-
src="./dist/components/nostr-profile-badge.es.js"
|
|
103
|
-
></script>
|
|
104
|
-
</head>
|
|
105
|
-
<body>
|
|
106
|
-
<nostr-profile-badge
|
|
107
|
-
pubkey="npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6"
|
|
108
|
-
></nostr-profile-badge>
|
|
109
|
-
</body>
|
|
63
|
+
// Or import the full bundle
|
|
64
|
+
import 'nostr-components/dist/nostr-components.es.js';
|
|
110
65
|
```
|
|
111
66
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-

|
|
115
|
-
|
|
116
|
-
---
|
|
67
|
+
For bundlers (Vite, Webpack, etc.), you can also import the source:
|
|
117
68
|
|
|
118
|
-
|
|
69
|
+
```javascript
|
|
70
|
+
// Import from source (requires bundler)
|
|
71
|
+
import { NostrFollowButton } from 'nostr-components';
|
|
72
|
+
import { NostrZap } from 'nostr-components';
|
|
73
|
+
import { NostrLike } from 'nostr-components';
|
|
74
|
+
```
|
|
119
75
|
|
|
120
|
-
|
|
76
|
+
**Note:** When using npm packages, make sure your bundler is configured to handle Web Components properly.
|
|
121
77
|
|
|
122
|
-
**
|
|
78
|
+
**Use the Components:** Place the component tags anywhere in your `<body>`.
|
|
123
79
|
|
|
124
|
-
|
|
125
|
-
<head>
|
|
126
|
-
<script type="module" src="./dist/components/nostr-profile.es.js"></script>
|
|
127
|
-
</head>
|
|
128
|
-
<body>
|
|
129
|
-
<nostr-profile
|
|
130
|
-
pubkey="npub1a2cww4kn9wqte4ry70vyfwqyqvpswksna27rtxd8vty6c74era8sdcw83a"
|
|
131
|
-
></nostr-profile>
|
|
132
|
-
</body>
|
|
133
|
-
```
|
|
80
|
+
### Authentication
|
|
134
81
|
|
|
135
|
-
|
|
82
|
+
All interactive components (Follow, Like, Zap) require user authentication. Components use [NostrLogin](https://github.com/nostrband/nostr-login) which supports:
|
|
83
|
+
- **NIP-07 Browser Extensions** (Alby, nos2x, etc.)
|
|
84
|
+
- **NIP-46 Remote Signers** (Bunkers)
|
|
136
85
|
|
|
137
|
-
|
|
86
|
+
The authentication flow is handled automatically when users interact with components.
|
|
138
87
|
|
|
139
88
|
---
|
|
140
89
|
|
|
141
|
-
##
|
|
90
|
+
## 1. Nostr Zap
|
|
142
91
|
|
|
143
|
-
|
|
92
|
+
A Lightning Network zap button that allows users to send sats to any Nostr user with a lightning address or LNURL.
|
|
144
93
|
|
|
145
94
|
**Usage:**
|
|
146
95
|
|
|
147
96
|
```html
|
|
148
97
|
<head>
|
|
149
|
-
<script type="module" src="
|
|
98
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/nostr-components@latest/dist/components/nostr-zap.es.js"></script>
|
|
150
99
|
</head>
|
|
151
100
|
<body>
|
|
152
|
-
<nostr-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
101
|
+
<nostr-zap
|
|
102
|
+
npub="npub1qsvv5ttv6mrlh38q8ydmw3gzwq360mdu8re2vr7rk68sqmhmsh4svhsft3"
|
|
103
|
+
theme="dark"
|
|
104
|
+
text="⚡ Zap Me"
|
|
105
|
+
></nostr-zap>
|
|
156
106
|
</body>
|
|
157
107
|
```
|
|
158
108
|
|
|
159
109
|
**Preview:**
|
|
160
110
|
|
|
161
|
-

|
|
162
112
|
|
|
163
113
|
---
|
|
164
114
|
|
|
165
|
-
##
|
|
115
|
+
## 2. Nostr Follow
|
|
166
116
|
|
|
167
117
|
A simple button that allows users to follow a Nostr profile.
|
|
168
118
|
|
|
@@ -172,12 +122,12 @@ A simple button that allows users to follow a Nostr profile.
|
|
|
172
122
|
<head>
|
|
173
123
|
<script
|
|
174
124
|
type="module"
|
|
175
|
-
src="
|
|
125
|
+
src="https://cdn.jsdelivr.net/npm/nostr-components@latest/dist/components/nostr-follow-button.es.js"
|
|
176
126
|
></script>
|
|
177
127
|
</head>
|
|
178
128
|
<body>
|
|
179
129
|
<nostr-follow-button
|
|
180
|
-
|
|
130
|
+
npub="npub1qsvv5ttv6mrlh38q8ydmw3gzwq360mdu8re2vr7rk68sqmhmsh4svhsft3"
|
|
181
131
|
></nostr-follow-button>
|
|
182
132
|
</body>
|
|
183
133
|
```
|
|
@@ -186,142 +136,111 @@ A simple button that allows users to follow a Nostr profile.
|
|
|
186
136
|
|
|
187
137
|

|
|
188
138
|
|
|
189
|
-
|
|
139
|
+
---
|
|
190
140
|
|
|
191
|
-
|
|
141
|
+
## 3. Nostr Like
|
|
142
|
+
|
|
143
|
+
A like button that uses NIP-25 (External Content Reactions) to like any URL on the web.
|
|
144
|
+
When URL is not specified, current URL is taken.
|
|
192
145
|
|
|
193
146
|
**Usage:**
|
|
194
147
|
|
|
195
148
|
```html
|
|
196
149
|
<head>
|
|
197
|
-
<script type="module" src="
|
|
150
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/nostr-components@latest/dist/components/nostr-like.es.js"></script>
|
|
198
151
|
</head>
|
|
199
152
|
<body>
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
amount="1000"
|
|
206
|
-
></nostr-zap>
|
|
153
|
+
<!-- Like the current page URL -->
|
|
154
|
+
<nostr-like></nostr-like>
|
|
155
|
+
|
|
156
|
+
<!-- Like a specific URL with custom text -->
|
|
157
|
+
<nostr-like url="https://github.com/saiy2k/nostr-components" text="❤️"></nostr-like>
|
|
207
158
|
</body>
|
|
208
159
|
```
|
|
209
160
|
|
|
210
161
|
**Preview:**
|
|
211
162
|
|
|
212
|
-

|
|
213
164
|
|
|
214
165
|
---
|
|
215
166
|
|
|
216
|
-
##
|
|
167
|
+
## 4. Nostr Profile Badge
|
|
217
168
|
|
|
218
|
-
A
|
|
169
|
+
A small badge displaying a Nostr profile with a username and avatar.
|
|
219
170
|
|
|
220
171
|
**Usage:**
|
|
221
172
|
|
|
222
173
|
```html
|
|
223
174
|
<head>
|
|
224
|
-
<script
|
|
175
|
+
<script
|
|
176
|
+
type="module"
|
|
177
|
+
src="https://cdn.jsdelivr.net/npm/nostr-components@latest/dist/components/nostr-profile-badge.es.js"
|
|
178
|
+
></script>
|
|
225
179
|
</head>
|
|
226
180
|
<body>
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
<!-- Pre-configured recipient with npub -->
|
|
231
|
-
<nostr-dm
|
|
232
|
-
recipient-npub="npub1g53mukxnjkcmr94fhryzkqutdz2ukq4ks0gvy5af25rgmwsl4ngq43drvk"
|
|
233
|
-
theme="light"
|
|
234
|
-
relays="wss://relay.damus.io,wss://relay.primal.net"
|
|
235
|
-
></nostr-dm>
|
|
236
|
-
|
|
237
|
-
<!-- Using NIP-05 identifier -->
|
|
238
|
-
<nostr-dm
|
|
239
|
-
nip05="user@domain.com"
|
|
240
|
-
theme="dark"
|
|
241
|
-
></nostr-dm>
|
|
181
|
+
<nostr-profile-badge
|
|
182
|
+
pubkey="npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6"
|
|
183
|
+
></nostr-profile-badge>
|
|
242
184
|
</body>
|
|
243
185
|
```
|
|
244
186
|
|
|
245
|
-
|
|
246
187
|
**Preview:**
|
|
247
188
|
|
|
248
|
-

|
|
249
190
|
|
|
250
191
|
---
|
|
251
192
|
|
|
252
|
-
##
|
|
193
|
+
## 5. Nostr Profile
|
|
253
194
|
|
|
254
|
-
|
|
195
|
+
A detailed profile card showing avatar, name, bio, notes count, followers, etc.
|
|
255
196
|
|
|
256
197
|
**Usage:**
|
|
257
198
|
|
|
258
199
|
```html
|
|
259
200
|
<head>
|
|
260
|
-
<script type="module" src="
|
|
201
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/nostr-components@latest/dist/components/nostr-profile.es.js"></script>
|
|
261
202
|
</head>
|
|
262
203
|
<body>
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
<!-- Pre-configured recipient with npub -->
|
|
267
|
-
<nostr-live-chat
|
|
268
|
-
recipient-npub="npub1g53mukxnjkcmr94fhryzkqutdz2ukq4ks0gvy5af25rgmwsl4ngq43drvk"
|
|
269
|
-
theme="light"
|
|
270
|
-
relays="wss://relay.damus.io,wss://relay.primal.net,wss://relay.snort.social"
|
|
271
|
-
></nostr-live-chat>
|
|
272
|
-
|
|
273
|
-
<!-- Using NIP-05 identifier -->
|
|
274
|
-
<nostr-live-chat
|
|
275
|
-
nip05="user@domain.com"
|
|
276
|
-
theme="dark"
|
|
277
|
-
></nostr-live-chat>
|
|
204
|
+
<nostr-profile
|
|
205
|
+
pubkey="npub1a2cww4kn9wqte4ry70vyfwqyqvpswksna27rtxd8vty6c74era8sdcw83a"
|
|
206
|
+
></nostr-profile>
|
|
278
207
|
</body>
|
|
279
208
|
```
|
|
280
209
|
|
|
281
|
-
|
|
282
|
-
|
|
283
210
|
**Preview:**
|
|
284
211
|
|
|
285
|
-

|
|
286
213
|
|
|
287
214
|
---
|
|
288
215
|
|
|
289
|
-
##
|
|
216
|
+
## 6. Nostr Post
|
|
290
217
|
|
|
291
|
-
|
|
218
|
+
Embed any Nostr post by providing the event ID.
|
|
292
219
|
|
|
293
220
|
**Usage:**
|
|
294
221
|
|
|
295
222
|
```html
|
|
296
223
|
<head>
|
|
297
|
-
<script type="
|
|
298
|
-
{
|
|
299
|
-
"imports": {
|
|
300
|
-
"lit": "https://unpkg.com/lit@3.1.0/index.js?module",
|
|
301
|
-
"dayjs": "https://unpkg.com/dayjs@1.11.10/dayjs.min.js?module"
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
</script>
|
|
305
|
-
<script type="module" src="./dist/components/nostr-comment.es.js"></script>
|
|
224
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/nostr-components@latest/dist/components/nostr-post.es.js"></script>
|
|
306
225
|
</head>
|
|
307
226
|
<body>
|
|
308
|
-
<nostr-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
relays="wss://relay.damus.io,wss://nostr.wine,wss://relay.nostr.net"
|
|
312
|
-
></nostr-comment>
|
|
227
|
+
<nostr-post
|
|
228
|
+
eventId="note1t2jvt5vpusrwrxkfu8x8r7q65zzvm32xuur6y7am4zn475r8ucjqmwwhd2"
|
|
229
|
+
></nostr-post>
|
|
313
230
|
</body>
|
|
314
231
|
```
|
|
315
232
|
|
|
316
233
|
**Preview:**
|
|
317
234
|
|
|
318
|
-

|
|
319
236
|
|
|
320
237
|
---
|
|
321
238
|
|
|
322
|
-
##
|
|
239
|
+
## 7. WordPress Integration
|
|
240
|
+
|
|
241
|
+
The Nostr Components WordPress plugin provides Gutenberg blocks and shortcodes for all components, making it easy to embed Nostr functionality in your WordPress site.
|
|
323
242
|
|
|
324
|
-
|
|
243
|
+
For more details, see the [WordPress Plugin](https://wordpress.org/plugins/saiy2k-nostr-components/).
|
|
325
244
|
|
|
326
245
|
---
|
|
327
246
|
|
|
@@ -333,6 +252,15 @@ Check out our full documentation [here](https://nostr-components.web.app).
|
|
|
333
252
|
|
|
334
253
|
## 🛠️ Development
|
|
335
254
|
|
|
255
|
+
### npm Installation Notes (Windows / newer npm versions)
|
|
256
|
+
|
|
257
|
+
If you encounter dependency resolution errors (`ERESOLVE`) when running `npm install`
|
|
258
|
+
with newer versions of npm, use:
|
|
259
|
+
|
|
260
|
+
````bash
|
|
261
|
+
npm install --legacy-peer-deps
|
|
262
|
+
|
|
263
|
+
|
|
336
264
|
### Storybook Setup
|
|
337
265
|
|
|
338
266
|
This project uses Storybook for component development and testing. The setup includes both public showcase stories and private testing stories.
|
|
@@ -345,9 +273,10 @@ npm run storybook
|
|
|
345
273
|
|
|
346
274
|
# Build Storybook for production (excludes testing stories)
|
|
347
275
|
STORYBOOK_ENV=production npm run build-storybook
|
|
348
|
-
|
|
276
|
+
````
|
|
349
277
|
|
|
350
278
|
**Story Organization:**
|
|
279
|
+
|
|
351
280
|
- **Public Stories**: Showcase stories for component demos and documentation
|
|
352
281
|
- **Testing Stories**: Private stories for development testing (excluded from production builds)
|
|
353
282
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var w=Object.defineProperty;var k=(t,r,e)=>r in t?w(t,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[r]=e;var c=(t,r,e)=>k(t,typeof r!="symbol"?r+"":r,e);import{c as v,a as p,e as m,M as E,b as T}from"./nostr-service-
|
|
1
|
+
var w=Object.defineProperty;var k=(t,r,e)=>r in t?w(t,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[r]=e;var c=(t,r,e)=>k(t,typeof r!="symbol"?r+"":r,e);import{c as v,a as p,e as m,M as E,b as T}from"./nostr-service-CA0Qx4nJ.js";const I=t=>{if(typeof t!="string"||!t.startsWith("npub1"))return"";try{const r=p.decode(t);if(r&&typeof r.data=="string")return r.data}catch(r){console.error("Failed to decode npub:",r)}return""};function M(t){if(!t||!S(t))return"";try{return p.npubEncode(t.toLowerCase())}catch(r){return console.error("Failed to encode hex to npub:",r),""}}function O(t="",r=3){const e=t.length;if(!t.startsWith("npub1"))return"Invalid nPub: expected npub1...";if(!N(t))return"Invalid nPub";let s="npub1";for(let n=5;n<r+5;n++)s+=t[n];s+="...";let o="";for(let n=e-1;n>=e-r;n--)o=t[n]+o;return s+=o,s}async function z(t,r){const e=await t.fetchEvents({kinds:[m.Repost],"#e":[r||""]}),s=d=>d.tags.filter(g=>g[0]==="p").length===1,o=d=>d.tags.filter(g=>g[0]==="e").length===1,n=Array.from(e).filter(s).length,a=await t.fetchEvents({kinds:[m.Reaction],"#e":[r||""]}),i=0,u=await t.fetchEvents({kinds:[m.Text],"#e":[r||""]}),l=Array.from(u).filter(o).length;return{likes:a.size,reposts:n,zaps:i/E,replies:l}}function C(t){if(t){const r=t.split(",").map(e=>e.trim()).filter(Boolean).filter(y);return r.length?Array.from(new Set(r)):[...v]}return[...v]}function L(t){const r=t==null?void 0:t.trim().toLowerCase();return r==="light"||r==="dark"?r:"light"}function P(t){return t===null?!1:t===""||t.toLowerCase()==="true"}function B(t){const r=document.createElement("div");return r.textContent=t,r.innerHTML}function F(t){try{const r=new URL(t);return["http:","https:"].includes(r.protocol)}catch{return!1}}function y(t){try{const r=new URL(t);return r.protocol==="wss:"||r.protocol==="ws:"}catch{return!1}}function S(t){return/^[0-9a-fA-F]+$/.test(t)&&t.length===64}function N(t){try{const{type:r}=p.decode(t);return r==="npub"}catch{return!1}}function j(t){return/^[a-zA-Z0-9_\-\.]+@[a-zA-Z0-9_\-\.]+\.[a-zA-Z]{2,}$/.test(t)}function b(t,r){try{const{type:e}=p.decode(t);return e===r}catch{return!1}}function U(t){return b(t,"note")}function D(t){return b(t,"nevent")}function H(t){return navigator.clipboard.writeText(t)}function q(t){try{const r=Date.now(),e=t*1e3,s=r-e,o=Math.floor(s/1e3);if(o<60)return"just now";if(o<3600){const a=Math.floor(o/60);return`${a} ${a===1?"min":"mins"} ago`}if(o<86400){const a=Math.floor(o/3600);return`${a} ${a===1?"hour":"hours"} ago`}if(o<2592e3){const a=Math.floor(o/86400);return`${a} ${a===1?"day":"days"} ago`}if(o<31536e3){const a=Math.floor(o/2592e3);return`${a} ${a===1?"month":"months"} ago`}const n=Math.floor(o/31536e3);return`${n} ${n===1?"year":"years"} ago`}catch(r){return console.error("Error formatting relative time:",r),"unknown"}}var f=(t=>(t[t.Idle=0]="Idle",t[t.Loading=1]="Loading",t[t.Ready=2]="Ready",t[t.Error=3]="Error",t))(f||{});const $="nc:status";class K extends HTMLElement{constructor(e=!0){super();c(this,"nostrService",T.getInstance());c(this,"theme","light");c(this,"errorMessage","");c(this,"nostrReady");c(this,"nostrReadyResolve");c(this,"nostrReadyReject");c(this,"conn",this.channel("connection"));c(this,"_statuses",new Map);c(this,"_overall",0);c(this,"connectSeq",0);e&&this.attachShadow({mode:"open"}),this.resetNostrReadyBarrier()}static get observedAttributes(){return["data-theme","relays"]}connectedCallback(){this.validateInputs()&&(this.getTheme(),this.conn.get()===0&&this.connectToNostr())}disconnectedCallback(){this.shadowRoot&&this._delegated&&this._delegated.clear()}attributeChangedCallback(e,s,o){s!==o&&(e==="data-theme"||e==="relays")&&this.validateInputs()&&(e==="relays"&&(this.resetNostrReadyBarrier(),this.connectToNostr()),e==="data-theme"&&(this.getTheme(),this.render()))}setStatusFor(e,s,o){const n=this._statuses.get(e);if(!(n!==s||s===3&&!!o))return;this._statuses.set(e,s),s===3&&o?this.errorMessage=o:n===3&&s!==3&&(this.errorMessage="");const i=`${e}-status`,u=f[s].toLowerCase();this.getAttribute(i)!==u&&this.setAttribute(i,u);const l=this.computeOverall(),d=f[l].toLowerCase();this._overall!==l?(this._overall=l,this.setAttribute("status",d),this.onStatusChange(l)):l===3&&o&&this.onStatusChange(l),this.dispatchEvent(new CustomEvent($,{detail:{key:e,status:s,all:this.snapshotStatuses(),overall:this._overall,errorMessage:this.errorMessage||void 0},bubbles:!0,composed:!0}))}getStatusFor(e){return this._statuses.get(e)??0}snapshotStatuses(){return Object.fromEntries(this._statuses.entries())}onStatusChange(e){}onNostrRelaysConnected(){}computeOverall(){const e=[...this._statuses.values()];return e.includes(3)?3:e.includes(1)?1:e.includes(2)?2:0}initChannelStatus(e,s,o={reflectOverall:!1}){if(this._statuses.set(e,s),this.setAttribute(`${e}-status`,f[s].toLowerCase()),o.reflectOverall){const n=this.computeOverall();this._overall=n,this.setAttribute("status",f[n].toLowerCase())}}channel(e){return{set:(s,o)=>this.setStatusFor(e,s,o),get:()=>this.getStatusFor(e)}}validateInputs(){const e=this.getAttribute("data-theme")||"light",s=this.getAttribute("relays"),o=this.tagName.toLowerCase();if(e==="light"||e==="dark"){if(s&&typeof s!="string")return this.conn.set(3,"Invalid relays list"),console.error(`Nostr-Components: ${o}: ${this.errorMessage}`),!1;if(s){const a=s.split(",").map(i=>i.trim()).filter(Boolean).filter(i=>!y(i));if(a.length>0){const i=a.join(", ");return this.conn.set(3,`Invalid relay URLs: ${i}. Relay URLs must start with 'wss://' or 'ws://'`),console.error(`Nostr-Components: ${o}: ${this.errorMessage}`),!1}}}else return this.conn.set(3,`Invalid theme '${e}'. Accepted values are 'light', 'dark'`),console.error(`Nostr-Components: ${o}: ${this.errorMessage}`),!1;return this.errorMessage="",!0}async connectToNostr(){var s,o;const e=++this.connectSeq;this.conn.set(1);try{if(await this.nostrService.connectToNostr(this.getRelays()),e!==this.connectSeq)return;this.conn.set(2),(s=this.nostrReadyResolve)==null||s.call(this);try{this.onNostrRelaysConnected()}catch(n){console.error("Error in onNostrRelaysConnected hook:",n)}}catch(n){if(e!==this.connectSeq)return;console.error("Failed to connect to Nostr relays:",n),this.conn.set(3,"Failed to connect to relays"),(o=this.nostrReadyReject)==null||o.call(this,n)}}ensureNostrConnected(){return this.nostrReady}getRelays(){return C(this.getAttribute("relays"))}getTheme(){this.theme=L(this.getAttribute("data-theme"))}delegateEvent(e,s,o){var i;const n=this.shadowRoot;if(!n)return;const a=`${e}:${s}`;(i=this._delegated)!=null&&i.has(a)||(this._delegated||(this._delegated=new Set),this._delegated.add(a),n.addEventListener(e,u=>{u.target.closest(s)&&o(u)}))}addDelegatedListener(e,s,o){this.delegateEvent(e,s,o)}renderError(e){return`Error: ${e}`}updateHostClasses(){const e=this.computeOverall()===1,s=this.computeOverall()===3,o=this.computeOverall()===2;this.classList.remove("is-clickable","is-disabled","is-error"),e?this.classList.add("is-disabled"):s?this.classList.add("is-error"):o&&this.classList.add("is-clickable")}render(){this.updateHostClasses(),this.renderContent()}handleNjumpClick(e,s,o){if(this.computeOverall()!==2)return;const n=new CustomEvent(e,{detail:s,bubbles:!0,composed:!0,cancelable:!0});this.dispatchEvent(n)&&window.open(`https://njump.me/${o}`,"_blank","noopener,noreferrer")}resetNostrReadyBarrier(){this.connectSeq++,this.nostrReady=new Promise((e,s)=>{this.nostrReadyResolve=e,this.nostrReadyReject=s})}}function x(){return`
|
|
2
2
|
:host {
|
|
3
3
|
/* === GENERIC DESIGN TOKENS === */
|
|
4
4
|
--nostrc-color-background: #ffffff;
|
|
@@ -142,4 +142,4 @@ var w=Object.defineProperty;var k=(t,r,e)=>r in t?w(t,r,{enumerable:!0,configura
|
|
|
142
142
|
margin: auto;
|
|
143
143
|
}
|
|
144
144
|
`};export{f as N,S as a,D as b,K as c,z as d,B as e,H as f,V as g,I as h,F as i,M as j,q as k,j as l,O as m,N as n,P as p,U as v};
|
|
145
|
-
//# sourceMappingURL=base-styles-
|
|
145
|
+
//# sourceMappingURL=base-styles-Dmuzg8I4.js.map
|