nostr-components 0.2.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 (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +334 -0
  3. package/dist/assets/base-styles-CBypR3FR.js +145 -0
  4. package/dist/assets/base-styles-CBypR3FR.js.map +1 -0
  5. package/dist/assets/copy-delegation-C4uvRTVM.js +15 -0
  6. package/dist/assets/copy-delegation-C4uvRTVM.js.map +1 -0
  7. package/dist/assets/dialog-component-Dqg0QU9I.js +66 -0
  8. package/dist/assets/dialog-component-Dqg0QU9I.js.map +1 -0
  9. package/dist/assets/dialog-likers-BzTesCZa.js +238 -0
  10. package/dist/assets/dialog-likers-BzTesCZa.js.map +1 -0
  11. package/dist/assets/icons-Dr_d9MII.js +105 -0
  12. package/dist/assets/icons-Dr_d9MII.js.map +1 -0
  13. package/dist/assets/nip05-utils-BNBHUmkr.js +2 -0
  14. package/dist/assets/nip05-utils-BNBHUmkr.js.map +1 -0
  15. package/dist/assets/nostr-service-pr_crY62.js +78 -0
  16. package/dist/assets/nostr-service-pr_crY62.js.map +1 -0
  17. package/dist/assets/nostr-user-component-Q7GeeFyu.js +2 -0
  18. package/dist/assets/nostr-user-component-Q7GeeFyu.js.map +1 -0
  19. package/dist/assets/preload-helper-D7HrI6pR.js +2 -0
  20. package/dist/assets/preload-helper-D7HrI6pR.js.map +1 -0
  21. package/dist/assets/pure-jrVhRVpB.js +2 -0
  22. package/dist/assets/pure-jrVhRVpB.js.map +1 -0
  23. package/dist/assets/theme-C1r1Zw8r.js +2 -0
  24. package/dist/assets/theme-C1r1Zw8r.js.map +1 -0
  25. package/dist/assets/user-resolver-C-E6KdwY.js +2 -0
  26. package/dist/assets/user-resolver-C-E6KdwY.js.map +1 -0
  27. package/dist/assets/utils--bxLbhGF.js +2 -0
  28. package/dist/assets/utils--bxLbhGF.js.map +1 -0
  29. package/dist/assets/zap-utils-B1sz0Abx.js +2 -0
  30. package/dist/assets/zap-utils-B1sz0Abx.js.map +1 -0
  31. package/dist/components/nostr-comment.es.js +924 -0
  32. package/dist/components/nostr-comment.es.js.map +1 -0
  33. package/dist/components/nostr-dm.es.js +217 -0
  34. package/dist/components/nostr-dm.es.js.map +1 -0
  35. package/dist/components/nostr-follow-button.es.js +103 -0
  36. package/dist/components/nostr-follow-button.es.js.map +1 -0
  37. package/dist/components/nostr-like.es.js +296 -0
  38. package/dist/components/nostr-like.es.js.map +1 -0
  39. package/dist/components/nostr-live-chat.es.js +523 -0
  40. package/dist/components/nostr-live-chat.es.js.map +1 -0
  41. package/dist/components/nostr-post.es.js +441 -0
  42. package/dist/components/nostr-post.es.js.map +1 -0
  43. package/dist/components/nostr-profile-badge.es.js +100 -0
  44. package/dist/components/nostr-profile-badge.es.js.map +1 -0
  45. package/dist/components/nostr-profile.es.js +287 -0
  46. package/dist/components/nostr-profile.es.js.map +1 -0
  47. package/dist/components/nostr-zap.es.js +694 -0
  48. package/dist/components/nostr-zap.es.js.map +1 -0
  49. package/dist/index.d.ts +2 -0
  50. package/dist/nostr-comment.d.ts +4 -0
  51. package/dist/nostr-components.es.js +2 -0
  52. package/dist/nostr-components.es.js.map +1 -0
  53. package/dist/nostr-components.umd.js +4200 -0
  54. package/dist/nostr-components.umd.js.map +1 -0
  55. package/dist/nostr-dm.d.ts +4 -0
  56. package/dist/nostr-follow-button.d.ts +4 -0
  57. package/dist/nostr-like.d.ts +4 -0
  58. package/dist/nostr-live-chat.d.ts +4 -0
  59. package/dist/nostr-post.d.ts +4 -0
  60. package/dist/nostr-profile-badge.d.ts +4 -0
  61. package/dist/nostr-profile.d.ts +4 -0
  62. package/dist/nostr-zap.d.ts +4 -0
  63. package/dist/src/base/base-component/nostr-base-component.d.ts +116 -0
  64. package/dist/src/base/copy-delegation.d.ts +5 -0
  65. package/dist/src/base/dialog-component/dialog-component.d.ts +67 -0
  66. package/dist/src/base/dialog-component/style.d.ts +5 -0
  67. package/dist/src/base/event-component/nostr-event-component.d.ts +53 -0
  68. package/dist/src/base/render-options.d.ts +5 -0
  69. package/dist/src/base/resolvers/event-resolver.d.ts +20 -0
  70. package/dist/src/base/resolvers/user-resolver.d.ts +19 -0
  71. package/dist/src/base/text-row/render-name.d.ts +7 -0
  72. package/dist/src/base/text-row/render-nip05.d.ts +1 -0
  73. package/dist/src/base/text-row/render-npub.d.ts +1 -0
  74. package/dist/src/base/text-row/render-text-row.d.ts +9 -0
  75. package/dist/src/base/user-component/nostr-user-component.d.ts +43 -0
  76. package/dist/src/common/base-styles.d.ts +44 -0
  77. package/dist/src/common/constants.d.ts +4 -0
  78. package/dist/src/common/date-utils.d.ts +9 -0
  79. package/dist/src/common/icons.d.ts +7 -0
  80. package/dist/src/common/nip05-utils.d.ts +13 -0
  81. package/dist/src/common/nostr-service.d.ts +40 -0
  82. package/dist/src/common/theme.d.ts +4 -0
  83. package/dist/src/common/types.d.ts +1 -0
  84. package/dist/src/common/utils.d.ts +34 -0
  85. package/dist/src/index.d.ts +10 -0
  86. package/dist/src/nostr-comment/nostr-comment.d.ts +60 -0
  87. package/dist/src/nostr-comment/render.d.ts +15 -0
  88. package/dist/src/nostr-comment/utils.d.ts +81 -0
  89. package/dist/src/nostr-dm/nostr-dm.d.ts +34 -0
  90. package/dist/src/nostr-dm/render.d.ts +15 -0
  91. package/dist/src/nostr-follow-button/nostr-follow-button.d.ts +24 -0
  92. package/dist/src/nostr-follow-button/render.d.ts +11 -0
  93. package/dist/src/nostr-follow-button/style.d.ts +1 -0
  94. package/dist/src/nostr-like/dialog-help-style.d.ts +1 -0
  95. package/dist/src/nostr-like/dialog-help.d.ts +2 -0
  96. package/dist/src/nostr-like/dialog-likers-style.d.ts +1 -0
  97. package/dist/src/nostr-like/dialog-likers.d.ts +24 -0
  98. package/dist/src/nostr-like/like-utils.d.ts +52 -0
  99. package/dist/src/nostr-like/nostr-like.d.ts +49 -0
  100. package/dist/src/nostr-like/render.d.ts +10 -0
  101. package/dist/src/nostr-like/style.d.ts +1 -0
  102. package/dist/src/nostr-live-chat/nostr-live-chat.d.ts +65 -0
  103. package/dist/src/nostr-live-chat/render.d.ts +31 -0
  104. package/dist/src/nostr-post/nostr-post.d.ts +25 -0
  105. package/dist/src/nostr-post/parse-text.d.ts +8 -0
  106. package/dist/src/nostr-post/render-content.d.ts +5 -0
  107. package/dist/src/nostr-post/render.d.ts +19 -0
  108. package/dist/src/nostr-post/style.d.ts +1 -0
  109. package/dist/src/nostr-profile/nostr-profile.d.ts +24 -0
  110. package/dist/src/nostr-profile/render-stats.d.ts +1 -0
  111. package/dist/src/nostr-profile/render.d.ts +22 -0
  112. package/dist/src/nostr-profile/style.d.ts +1 -0
  113. package/dist/src/nostr-profile-badge/nostr-profile-badge.d.ts +34 -0
  114. package/dist/src/nostr-profile-badge/render.d.ts +11 -0
  115. package/dist/src/nostr-profile-badge/style.d.ts +1 -0
  116. package/dist/src/nostr-zap/dialog-help-style.d.ts +5 -0
  117. package/dist/src/nostr-zap/dialog-help.d.ts +2 -0
  118. package/dist/src/nostr-zap/dialog-zap-style.d.ts +6 -0
  119. package/dist/src/nostr-zap/dialog-zap.d.ts +31 -0
  120. package/dist/src/nostr-zap/dialog-zappers-style.d.ts +1 -0
  121. package/dist/src/nostr-zap/dialog-zappers.d.ts +25 -0
  122. package/dist/src/nostr-zap/nostr-zap.d.ts +45 -0
  123. package/dist/src/nostr-zap/render.d.ts +9 -0
  124. package/dist/src/nostr-zap/style.d.ts +1 -0
  125. package/dist/src/nostr-zap/zap-utils.d.ts +53 -0
  126. package/dist/themes/dark.css +10 -0
  127. package/dist/themes/light.css +10 -0
  128. package/dist/themes.css +52 -0
  129. package/dist/vite.config.d.ts +2 -0
  130. package/dist/vite.config.esm.d.ts +2 -0
  131. package/dist/vite.config.umd.d.ts +2 -0
  132. package/package.json +95 -0
@@ -0,0 +1,100 @@
1
+ import{m as v,e as s,g as m,a as d,p as b}from"../assets/base-styles-CBypR3FR.js";import{N as y}from"../assets/nostr-user-component-Q7GeeFyu.js";import{h as w}from"../assets/nostr-service-pr_crY62.js";import{r as x,a as C,b as E,c as N}from"../assets/copy-delegation-C4uvRTVM.js";import"../assets/user-resolver-C-E6KdwY.js";function A({isLoading:n,isError:r,errorMessage:o,userProfile:e,ndkUser:t,showNpub:a,showFollow:c}){if(n)return L();if(r||e==null)return S(o||"");const i=e.displayName||e.name||v((t==null?void 0:t.npub)||""),p=s(i),f=s(e.picture||w),g=(t==null?void 0:t.npub)||"",h=(e==null?void 0:e.nip05)||"",u=s((t==null?void 0:t.pubkey)||"");return l(`<img src='${f}' alt='Nostr profile image of ${p}' loading="lazy" decoding="async"/>`,`${x({name:i})}
2
+ ${e.nip05?C(h):""}
3
+ ${a===!0?E(g||""):""}
4
+ ${c===!0&&(t!=null&&t.pubkey)?`<nostr-follow-button pubkey="${u}"></nostr-follow-button>`:""}`)}function L(){return l('<div class="skeleton img-skeleton"></div>',`<div class="skeleton" style="width: 120px;"></div>
5
+ <div class="skeleton" style="width: 160px;"></div>`)}function S(n){return l('<div class="error-icon">&#9888;</div>',s(n))}function l(n,r){return`
6
+ <div class='nostr-profile-badge-container'>
7
+ <div class='nostr-profile-badge-left-container'>
8
+ ${n}
9
+ </div>
10
+ <div class='nostr-profile-badge-right-container'>
11
+ ${r}
12
+ </div>
13
+ </div>
14
+ `}function $(){return m(`
15
+ /* === PROFILE BADGE SPECIFIC CSS VARIABLES === */
16
+ :host {
17
+ --nostrc-profile-badge-bg: var(--nostrc-theme-bg, #ffffff);
18
+ --nostrc-profile-badge-text-primary: var(--nostrc-theme-text-primary, #333333);
19
+ --nostrc-profile-badge-text-secondary: var(--nostrc-theme-text-secondary, #666666);
20
+ --nostrc-profile-badge-border: var(--nostrc-theme-border, var(--nostrc-color-border));
21
+ --nostrc-profile-badge-font-family: var(--nostrc-font-family-primary);
22
+ --nostrc-profile-badge-font-size: var(--nostrc-font-size-base);
23
+
24
+ /* Hover state variables */
25
+ --nostrc-profile-badge-hover-bg: var(--nostrc-theme-hover-bg, rgba(0, 0, 0, 0.05));
26
+ --nostrc-profile-badge-hover-color: var(--nostrc-theme-text-primary, #333333);
27
+ --nostrc-profile-badge-hover-border: var(--nostrc-border-width) solid var(--nostrc-theme-border, var(--nostrc-color-border));
28
+
29
+ /* Make the host the visual profile badge surface */
30
+ display: block;
31
+ background: var(--nostrc-profile-badge-bg);
32
+ border: var(--nostrc-border-width) solid var(--nostrc-profile-badge-border);
33
+ border-radius: var(--nostrc-border-radius-md);
34
+ font-family: var(--nostrc-profile-badge-font-family);
35
+ font-size: var(--nostrc-profile-badge-font-size);
36
+ transition: background-color var(--nostrc-transition-duration) var(--nostrc-transition-timing);
37
+ }
38
+
39
+ /* === PROFILE BADGE CONTAINER PATTERN === */
40
+ .nostr-profile-badge-container {
41
+ display: flex;
42
+ gap: var(--nostrc-spacing-md);
43
+ padding: var(--nostrc-spacing-md);
44
+ }
45
+
46
+ /* Hover state */
47
+ :host(.is-clickable:hover) {
48
+ background: var(--nostrc-profile-badge-hover-bg);
49
+ color: var(--nostrc-profile-badge-hover-color);
50
+ border: var(--nostrc-profile-badge-hover-border);
51
+ }
52
+
53
+ :host(.is-error) .nostr-profile-badge-container {
54
+ justify-content: center;
55
+ align-items: center;
56
+ color: var(--nostrc-color-error-text);
57
+ border: var(--nostrc-border-width) solid var(--nostrc-color-error-text);
58
+ }
59
+
60
+ .nostr-profile-badge-left-container {
61
+ width: 48px;
62
+ height: 48px;
63
+ }
64
+
65
+ .nostr-profile-badge-left-container img {
66
+ width: 100%;
67
+ height: 100%;
68
+ border-radius: var(--nostrc-border-radius-full);
69
+ object-fit: cover;
70
+ }
71
+
72
+ .nostr-profile-badge-right-container {
73
+ display: flex;
74
+ flex-direction: column;
75
+ justify-content: center;
76
+ flex-grow: 1;
77
+ min-width: 0;
78
+ }
79
+
80
+ /* Profile badge specific styling using component variables */
81
+ .nostr-profile-badge-container .nostr-profile-name {
82
+ color: var(--nostrc-profile-badge-text-primary);
83
+ }
84
+
85
+ .nostr-profile-badge-container .text-row {
86
+ color: var(--nostrc-profile-badge-text-secondary);
87
+ }
88
+
89
+ /* Skeleton specific styles */
90
+ .img-skeleton {
91
+ width: 48px;
92
+ height: 48px;
93
+ border-radius: var(--nostrc-border-radius-full);
94
+ }
95
+
96
+ `)}const I="nc:profile_badge";class D extends y{static get observedAttributes(){return[...super.observedAttributes,"show-npub","show-follow"]}connectedCallback(){var r;(r=super.connectedCallback)==null||r.call(this),this.attachDelegatedListeners(),N({addDelegatedListener:this.addDelegatedListener.bind(this)}),this.render()}attributeChangedCallback(r,o,e){var t;o!==e&&((t=super.attributeChangedCallback)==null||t.call(this,r,o,e),(r==="show-npub"||r==="show-follow")&&this.render())}onStatusChange(r){this.render()}onUserReady(r,o){this.render()}onProfileClick(){var o,e;const r=((o=this.user)==null?void 0:o.npub)||this.getAttribute("npub")||((e=this.profile)==null?void 0:e.nip05)||this.getAttribute("nip05");r&&this.handleNjumpClick(I,this.profile,encodeURIComponent(r))}attachDelegatedListeners(){this.delegateEvent("click",".nostr-profile-badge-container",r=>{r.target.closest(".nc-copy-btn, .nostr-follow-button-container, nostr-follow-button")||this.onProfileClick()})}renderContent(){const r=this.computeOverall(),o=r===d.Loading,e=r===d.Error,t=b(this.getAttribute("show-follow")),a=b(this.getAttribute("show-npub")),c=e?super.renderError(this.errorMessage):"",i={isLoading:o,isError:e,errorMessage:c,userProfile:this.profile,ndkUser:this.user,showNpub:a,showFollow:t};this.shadowRoot.innerHTML=`
97
+ ${$()}
98
+ ${A(i)}
99
+ `}}customElements.define("nostr-profile-badge",D);
100
+ //# sourceMappingURL=nostr-profile-badge.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nostr-profile-badge.es.js","sources":["../../src/nostr-profile-badge/render.ts","../../src/nostr-profile-badge/style.ts","../../src/nostr-profile-badge/nostr-profile-badge.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';\nimport { escapeHtml, maskNPub } from '../common/utils';\nimport { DEFAULT_PROFILE_IMAGE } from '../common/constants';\nimport { renderNpub } from '../base/text-row/render-npub';\nimport { renderNip05 } from '../base/text-row/render-nip05';\nimport { renderName } from '../base/text-row/render-name';\n\nexport interface RenderProfileBadgeOptions {\n isLoading: boolean;\n isError: boolean;\n errorMessage?: string;\n userProfile: NDKUserProfile | null;\n ndkUser: NDKUser | null;\n showNpub: boolean;\n showFollow: boolean;\n}\n\nexport function renderProfileBadge({\n isLoading,\n isError,\n errorMessage,\n userProfile,\n ndkUser,\n showNpub,\n showFollow\n}: RenderProfileBadgeOptions): string {\n\n if (isLoading) {\n return renderLoading();\n }\n\n if (isError || userProfile == null) {\n return renderError(errorMessage || '');\n }\n\n const rawName = userProfile.displayName ||\n userProfile.name ||\n maskNPub(ndkUser?.npub || '')\n const escapedName = escapeHtml(rawName);\n const profileImage = escapeHtml(userProfile.picture || DEFAULT_PROFILE_IMAGE);\n const npub = ndkUser?.npub || '';\n const nip05 = userProfile?.nip05 || '';\n const pubkey = escapeHtml(ndkUser?.pubkey || '');\n\n return renderContainer(\n `<img src='${profileImage}' alt='Nostr profile image of ${escapedName}' loading=\"lazy\" decoding=\"async\"/>`,\n `${renderName({ name: rawName })}\n ${userProfile.nip05 ? renderNip05(nip05) : ''}\n ${showNpub === true ? renderNpub(npub || '') : ''}\n ${showFollow === true && ndkUser?.pubkey ? `<nostr-follow-button pubkey=\"${pubkey}\"></nostr-follow-button>` : ''}`\n );\n}\n\nfunction renderLoading(): string {\n return renderContainer(\n '<div class=\"skeleton img-skeleton\"></div>',\n `<div class=\"skeleton\" style=\"width: 120px;\"></div>\n <div class=\"skeleton\" style=\"width: 160px;\"></div>`\n );\n}\n\nfunction renderError(errorMessage: string): string {\n return renderContainer(\n '<div class=\"error-icon\">&#9888;</div>',\n escapeHtml(errorMessage)\n );\n}\n\nfunction renderContainer(leftContent: string, rightContent: string): string {\n return `\n <div class='nostr-profile-badge-container'>\n <div class='nostr-profile-badge-left-container'>\n ${leftContent}\n </div>\n <div class='nostr-profile-badge-right-container'>\n ${rightContent}\n </div>\n </div>\n `;\n}","// SPDX-License-Identifier: MIT\n\nimport { getComponentStyles } from \"../common/base-styles\";\n\nexport function getProfileBadgeStyles(): string {\n const customStyles = `\n /* === PROFILE BADGE SPECIFIC CSS VARIABLES === */\n :host {\n --nostrc-profile-badge-bg: var(--nostrc-theme-bg, #ffffff);\n --nostrc-profile-badge-text-primary: var(--nostrc-theme-text-primary, #333333);\n --nostrc-profile-badge-text-secondary: var(--nostrc-theme-text-secondary, #666666);\n --nostrc-profile-badge-border: var(--nostrc-theme-border, var(--nostrc-color-border));\n --nostrc-profile-badge-font-family: var(--nostrc-font-family-primary);\n --nostrc-profile-badge-font-size: var(--nostrc-font-size-base);\n \n /* Hover state variables */\n --nostrc-profile-badge-hover-bg: var(--nostrc-theme-hover-bg, rgba(0, 0, 0, 0.05));\n --nostrc-profile-badge-hover-color: var(--nostrc-theme-text-primary, #333333);\n --nostrc-profile-badge-hover-border: var(--nostrc-border-width) solid var(--nostrc-theme-border, var(--nostrc-color-border));\n\n /* Make the host the visual profile badge surface */\n display: block;\n background: var(--nostrc-profile-badge-bg);\n border: var(--nostrc-border-width) solid var(--nostrc-profile-badge-border);\n border-radius: var(--nostrc-border-radius-md);\n font-family: var(--nostrc-profile-badge-font-family);\n font-size: var(--nostrc-profile-badge-font-size);\n transition: background-color var(--nostrc-transition-duration) var(--nostrc-transition-timing);\n }\n \n /* === PROFILE BADGE CONTAINER PATTERN === */\n .nostr-profile-badge-container {\n display: flex;\n gap: var(--nostrc-spacing-md);\n padding: var(--nostrc-spacing-md);\n }\n\n /* Hover state */\n :host(.is-clickable:hover) {\n background: var(--nostrc-profile-badge-hover-bg);\n color: var(--nostrc-profile-badge-hover-color);\n border: var(--nostrc-profile-badge-hover-border);\n }\n\n :host(.is-error) .nostr-profile-badge-container {\n justify-content: center;\n align-items: center;\n color: var(--nostrc-color-error-text);\n border: var(--nostrc-border-width) solid var(--nostrc-color-error-text);\n }\n \n .nostr-profile-badge-left-container {\n width: 48px;\n height: 48px;\n }\n \n .nostr-profile-badge-left-container img {\n width: 100%;\n height: 100%;\n border-radius: var(--nostrc-border-radius-full);\n object-fit: cover;\n }\n \n .nostr-profile-badge-right-container {\n display: flex;\n flex-direction: column;\n justify-content: center;\n flex-grow: 1;\n min-width: 0;\n }\n \n /* Profile badge specific styling using component variables */\n .nostr-profile-badge-container .nostr-profile-name {\n color: var(--nostrc-profile-badge-text-primary);\n }\n \n .nostr-profile-badge-container .text-row {\n color: var(--nostrc-profile-badge-text-secondary);\n }\n \n /* Skeleton specific styles */\n .img-skeleton {\n width: 48px;\n height: 48px;\n border-radius: var(--nostrc-border-radius-full);\n }\n \n `;\n \n return getComponentStyles(customStyles);\n}\n","// SPDX-License-Identifier: MIT\n\nimport { NCStatus } from '../base/base-component/nostr-base-component';\nimport { NostrUserComponent } from '../base/user-component/nostr-user-component';\nimport { parseBooleanAttribute } from '../common/utils';\nimport { renderProfileBadge, RenderProfileBadgeOptions } from './render';\nimport { getProfileBadgeStyles } from './style';\nimport { attachCopyDelegation } from '../base/copy-delegation';\nimport { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';\n\nconst EVT_BADGE = 'nc:profile_badge';\n\n/**\n * NostrProfileBadge\n * =================\n * UI component (extends `NostrUserComponent`) that renders a compact user badge\n * with avatar/name/nip05 and optional npub + follow button.\n *\n * Observed attributes\n * - `show-npub` — boolean-like attribute to display the masked npub + copy\n * - `show-follow` — boolean-like attribute to display the follow button\n *\n * Events\n * - `nc:status` — (from base) status changes for connection/user\n * - `nc:user` — emitted when user & profile are ready (from parent)\n * - `nc:profile_badge` — fired on badge click (detail: `NDKUserProfile | null`);\n * default action opens `https://njump.me/<nip05|npub>`\n *\n * Note: Follow button placement to be improved in future versions\n */\nexport default class NostrProfileBadge extends NostrUserComponent {\n\n /** Lifecycle methods */\n static get observedAttributes() {\n return [\n ...super.observedAttributes,\n 'show-npub',\n 'show-follow',\n ];\n }\n\n connectedCallback() {\n super.connectedCallback?.();\n \n this.attachDelegatedListeners();\n attachCopyDelegation({\n addDelegatedListener: this.addDelegatedListener.bind(this),\n });\n this.render();\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {\n if (oldValue === newValue) return;\n super.attributeChangedCallback?.(name, oldValue, newValue);\n\n if (name === 'show-npub' || name === 'show-follow') {\n this.render();\n }\n }\n\n /** Base class functions */\n protected onStatusChange(_status: NCStatus) {\n this.render();\n }\n\n protected onUserReady(_user: NDKUser, _profile: NDKUserProfile | null) {\n this.render();\n }\n\n /** Private functions */\n private onProfileClick() {\n const key =\n this.user?.npub ||\n this.getAttribute('npub') ||\n this.profile?.nip05 ||\n this.getAttribute('nip05');\n\n if (key) {\n this.handleNjumpClick(EVT_BADGE, this.profile, encodeURIComponent(key));\n }\n }\n\n private attachDelegatedListeners() {\n\n // Click anywhere on the profile badge (except follow button, copy buttons)\n this.delegateEvent('click', '.nostr-profile-badge-container', (e: Event) => {\n const target = e.target as HTMLElement;\n if (!target.closest('.nc-copy-btn, .nostr-follow-button-container, nostr-follow-button')) {\n this.onProfileClick();\n }\n });\n\n // Copy is handled via attachCopyDelegation() using `.nc-copy-btn`\n }\n\n protected renderContent() {\n const overall = this.computeOverall();\n const isLoading = overall === NCStatus.Loading;\n const isError = overall === NCStatus.Error;\n\n // Get attribute values\n const showFollow = parseBooleanAttribute(this.getAttribute('show-follow'));\n const showNpub = parseBooleanAttribute(this.getAttribute('show-npub'));\n const errorMessage = isError ? super.renderError(this.errorMessage) : '';\n\n const renderOptions: RenderProfileBadgeOptions = {\n isLoading : isLoading,\n isError : isError,\n errorMessage: errorMessage,\n userProfile : this.profile,\n ndkUser : this.user,\n showNpub : showNpub,\n showFollow : showFollow\n };\n\n this.shadowRoot!.innerHTML = `\n ${getProfileBadgeStyles()}\n ${renderProfileBadge(renderOptions)}\n `;\n }\n}\n\ncustomElements.define('nostr-profile-badge', NostrProfileBadge);\n"],"names":["renderProfileBadge","isLoading","isError","errorMessage","userProfile","ndkUser","showNpub","showFollow","renderLoading","renderError","rawName","maskNPub","escapedName","escapeHtml","profileImage","DEFAULT_PROFILE_IMAGE","npub","nip05","pubkey","renderContainer","renderName","renderNip05","renderNpub","leftContent","rightContent","getProfileBadgeStyles","getComponentStyles","EVT_BADGE","NostrProfileBadge","NostrUserComponent","_a","attachCopyDelegation","name","oldValue","newValue","_status","_user","_profile","key","_b","e","overall","NCStatus","parseBooleanAttribute","renderOptions"],"mappings":"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"}
@@ -0,0 +1,287 @@
1
+ var S=Object.defineProperty;var L=(e,o,t)=>o in e?S(e,o,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[o]=t;var n=(e,o,t)=>L(e,typeof o!="symbol"?o+"":o,t);import{e as k,g as $,a as p}from"../assets/base-styles-CBypR3FR.js";import{N as z}from"../assets/nostr-user-component-Q7GeeFyu.js";import{r as F,a as C,b as E,d as N,c as A}from"../assets/copy-delegation-C4uvRTVM.js";import"../assets/nostr-service-pr_crY62.js";import"../assets/user-resolver-C-E6KdwY.js";function l(e,o,t){const s=k(e);return`
2
+ <div class="stat" data-orientation="horizontal" aria-busy="${t}" aria-live="polite">
3
+ <div class="stat-inner">
4
+ <div class="stat-value">
5
+ ${t?'<div style="width: 50px; height: 28px; border-radius: 5px" class="skeleton"></div>':o.toLocaleString()}
6
+ </div>
7
+ <div class="stat-name">${s}</div>
8
+ </div>
9
+ </div>
10
+ `}function R(e){const{isLoading:o,isError:t,errorMessage:s,npub:i,userProfile:r,isStatsLoading:d,isStatsFollowersLoading:c,isStatsFollowsLoading:b,isZapsLoading:w,stats:a,showFollow:v,showNpub:m}=e;if(t)return Z(s||"");const h=(r==null?void 0:r.displayName)||(r==null?void 0:r.name)||"",u=(r==null?void 0:r.nip05)||"",x=(r==null?void 0:r.picture)||"",g=(r==null?void 0:r.about)||"",f=(r==null?void 0:r.website)||"",y=()=>!v||i===""?"":`
11
+ <nostr-follow-button
12
+ npub="${i}">
13
+ </nostr-follow-button>
14
+ `;return`
15
+ <div class="nostr-profile-container">
16
+ <div class="profile-banner">
17
+ ${o?'<div style="width: 100%; height: 100%;" class="skeleton"></div>':r!=null&&r.banner?`<img src="${r.banner}" width="524px"/>`:'<div class="banner-placeholder"></div>'}
18
+
19
+ <div class="dp-container">
20
+ <div class="avatar" role="img" aria-label="${h}">
21
+ ${o?'<div style="width: 100%; height: 100%; border-radius: 50%" class="skeleton"></div>':`<img
22
+ src="${x}"
23
+ alt="${h}"
24
+ width="142" height="142"
25
+ loading="lazy" decoding="async"
26
+ onerror="this.onerror=null; this.src='data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 142 142%22%3E%3Crect width=%22142%22 height=%22142%22 fill=%22%23ccc%22/%3E%3C/svg%3E'"
27
+ />`}
28
+ </div>
29
+ </div>
30
+ </div>
31
+
32
+ <div class="profile_actions">
33
+ ${v?o?'<div style="width: 100px; height: 36px; border-radius: 18px;" class="skeleton"></div>':y():""}
34
+ </div>
35
+
36
+ <div class="profile_data">
37
+ ${o?'<div style="width: 100px; height: 24px;" class="skeleton"></div>':F({name:h})}
38
+
39
+ ${o?'<div style="width: 75px; height: 20px;" class="skeleton"></div>':C(u)}
40
+
41
+ ${m?o?'<div style="width: 75px; height: 20px;" class="skeleton"></div>':E(i):""}
42
+
43
+ <div class="margin-bottom-md"> </div>
44
+
45
+ ${o?'<div style="width: 100%; margin-bottom: 12px; height: 18px" class="skeleton"></div>':N({display:g,value:g})}
46
+
47
+ <div class="margin-bottom-md"> </div>
48
+
49
+ ${o?'<div style="width: 150px" class="skeleton"></div>':f?`<div class="website">
50
+ <a target="_blank" href="${f}">${f}</a>
51
+ </div>`:""}
52
+
53
+ <div class="stats">
54
+
55
+ ${l("Following",a.follows,b)}
56
+
57
+ ${l("Followers",a.followers,c)}
58
+
59
+ ${l("Notes",a.notes,d)}
60
+
61
+ ${l("Replies",a.replies,d)}
62
+
63
+ ${l("Zaps",a.zaps,w)}
64
+
65
+ </div>
66
+ </div>
67
+ </div>
68
+ `}function Z(e){return`
69
+ <div class='nostr-profile-container'>
70
+ <div class='nostr-profile-top-container'>
71
+ <div class="error-icon">&#9888;</div>
72
+ </div>
73
+ <div class='nostr-profile-bottom-container'>
74
+ ${e}
75
+ </div>
76
+ </div>
77
+ `}function _(){return $(`
78
+ /* === PROFILE CSS VARIABLES & CONTAINER PATTERN === */
79
+ :host {
80
+ /* Override follow button styles for profile context */
81
+ --nostrc-follow-btn-padding: 5px 8px !important;
82
+ --nostrc-follow-btn-font-size: 14px !important;
83
+ --nostrc-follow-btn-border-radius: 12px !important;
84
+ --nostrc-follow-btn-border: var(--nostrc-border-width) solid var(--nostrc-color-border) !important;
85
+ --nostrc-follow-btn-horizontal-alignment: end !important;
86
+ --nostrc-follow-btn-min-height: auto !important;
87
+ --nostrc-follow-btn-width: 280px;
88
+
89
+ /* Component theme variables (fallback to global theme tokens) */
90
+ --nostrc-profile-bg: var(--nostrc-theme-bg, #ffffff);
91
+ --nostrc-profile-text-primary: var(--nostrc-theme-text-primary, #333333);
92
+ --nostrc-profile-text-secondary: var(--nostrc-theme-text-secondary, #666666);
93
+ --nostrc-profile-border: var(--nostrc-theme-border, var(--nostrc-border-width) solid var(--nostrc-color-border));
94
+ --nostrc-profile-banner-placeholder: var(--nostrc-profile-border);
95
+ --nostrc-profile-font-family: var(--nostrc-font-family-primary);
96
+ --nostrc-profile-font-size: var(--nostrc-font-size-base);
97
+
98
+ /* Hover state variables */
99
+ --nostrc-profile-hover-bg: var(--nostrc-theme-hover-bg, rgba(0, 0, 0, 0.05));
100
+ --nostrc-profile-hover-color: var(--nostrc-theme-text-primary, #333333);
101
+ --nostrc-profile-hover-border: var(--nostrc-theme-hover-border, var(--nostrc-border-width) solid var(--nostrc-color-border));
102
+
103
+ /* Make the host the visual profile surface */
104
+ display: block;
105
+ background: var(--nostrc-profile-bg);
106
+ color: var(--nostrc-profile-text-primary);
107
+ border: var(--nostrc-profile-border);
108
+ border-radius: var(--nostrc-border-radius-md);
109
+ font-family: var(--nostrc-profile-font-family);
110
+ font-size: var(--nostrc-profile-font-size);
111
+ transition: background-color var(--nostrc-transition-duration) var(--nostrc-transition-timing);
112
+ }
113
+
114
+ .nostr-profile-container {
115
+ display: flex;
116
+ flex-direction: column;
117
+ align-items: stretch;
118
+ gap: var(--nostrc-spacing-md);
119
+ min-height: 500px;
120
+ padding: 0px;
121
+ }
122
+
123
+ :host(.is-error) .nostr-profile-container {
124
+ justify-content: center;
125
+ align-items: center;
126
+ color: var(--nostrc-color-error-text);
127
+ border: var(--nostrc-border-width) solid var(--nostrc-color-error-text);
128
+ }
129
+
130
+ /* Hover state */
131
+ :host(.is-clickable:hover) {
132
+ background: var(--nostrc-profile-hover-bg);
133
+ color: var(--nostrc-profile-hover-color);
134
+ border: var(--nostrc-profile-hover-border);
135
+ }
136
+
137
+ .nostr-profile-top-container img {
138
+ width: 100%;
139
+ height: 100%;
140
+ border-radius: 50%;
141
+ object-fit: cover;
142
+ }
143
+
144
+ .nostr-profile-bottom-container {
145
+ min-width: 0;
146
+ text-align: center;
147
+ }
148
+
149
+ .profile-banner {
150
+ position: relative;
151
+ width: 100%;
152
+ height: 214px;
153
+ cursor: pointer;
154
+ border-radius: var(--nostrc-border-radius-md) var(--nostrc-border-radius-md) 0px 0px;
155
+ }
156
+
157
+ .banner-placeholder {
158
+ width: 100%;
159
+ height: 100%;
160
+ background-color: var(--nostrc-profile-banner-placeholder);
161
+ border-radius: var(--nostrc-border-radius-md) var(--nostrc-border-radius-md) 0px 0px;
162
+ }
163
+
164
+ .profile-banner img {
165
+ width: 100%;
166
+ height: 214px;
167
+ object-fit: cover;
168
+ }
169
+
170
+ .dp-container {
171
+ position: absolute;
172
+ top: 140px;
173
+ left: var(--nostrc-spacing-md);
174
+ }
175
+
176
+ .avatar {
177
+ --avatar-size: 142px;
178
+ --avatar-ring: 4px;
179
+
180
+ inline-size: var(--avatar-size);
181
+ block-size: var(--avatar-size);
182
+ border-radius: var(--nostrc-border-radius-full);
183
+ overflow: hidden;
184
+
185
+ /* ring + backfill in one place */
186
+ background-color: var(--nostrc-profile-bg);
187
+ border: var(--avatar-ring) solid var(--nostrc-profile-bg);
188
+ }
189
+
190
+ .avatar img {
191
+ inline-size: 100%;
192
+ block-size: 100%;
193
+ border-radius: var(--nostrc-border-radius-full);
194
+ display: block;
195
+ object-fit: cover;
196
+ }
197
+
198
+ .profile_actions {
199
+ height: 56px;
200
+ align-self: flex-end;
201
+ padding: 0 var(--nostrc-spacing-lg);
202
+ }
203
+
204
+ .profile_data {
205
+ padding: var(--nostrc-spacing-md);
206
+ }
207
+
208
+ .website {
209
+ font-weight: 400;
210
+ font-size: var(--nostrc-font-size-base);
211
+ line-height: 20px;
212
+ display: flex;
213
+ align-items: center;
214
+ }
215
+
216
+ .website a {
217
+ line-height: 20px;
218
+ outline: none;
219
+ color: var(--nostrc-profile-accent);
220
+ max-width: 350px;
221
+ overflow: hidden;
222
+ text-overflow: ellipsis;
223
+ word-wrap: normal;
224
+ }
225
+
226
+ .stats {
227
+ position: relative;
228
+ display: flex;
229
+ flex-direction: row;
230
+ flex-wrap: wrap;
231
+ justify-content: space-between;
232
+ align-items: center;
233
+ border-radius: 0;
234
+ border-top: none;
235
+ margin-top: var(--nostrc-spacing-md);
236
+ }
237
+
238
+ .stat {
239
+ position: relative;
240
+ display: inline-block;
241
+ padding-inline: var(--nostrc-spacing-md);
242
+ padding-block: var(--nostrc-spacing-xs);
243
+ border: none;
244
+ background: none;
245
+ width: fit-content;
246
+ height: 40px;
247
+ margin: 0 0 var(--nostrc-spacing-md);
248
+ }
249
+
250
+ .stat-inner {
251
+ display: flex;
252
+ flex-direction: column;
253
+ justify-content: center;
254
+ align-items: center;
255
+ }
256
+
257
+ .stat-inner .stat-value {
258
+ font-weight: 100;
259
+ font-size: 1.5em;
260
+ color: var(--nostrc-profile-text-primary);
261
+ }
262
+
263
+ .stat-inner .stat-name {
264
+ font-weight: 400;
265
+ line-height: 16px;
266
+ text-transform: lowercase;
267
+ color: var(--nostrc-profile-text-secondary);
268
+ }
269
+
270
+ @media only screen and (max-width: 600px) {
271
+ .stat .stat-value {
272
+ font-size: 18px !important;
273
+ }
274
+ :host {
275
+ --nostrc-follow-btn-padding: 5px 8px !important;
276
+ --nostrc-follow-btn-font-size: 12px !important;
277
+ --nostrc-follow-btn-min-height: auto !important;
278
+ --nostrc-follow-btn-border-radius: 8px !important;
279
+ --nostrc-follow-btn-error-max-width: 150px !important;
280
+ }
281
+ }
282
+
283
+ `)}const j="nc:profile";class O extends z{constructor(){super(...arguments);n(this,"profileStatus",this.channel("profile"));n(this,"isStatsLoading",!0);n(this,"isStatsFollowsLoading",!0);n(this,"isStatsFollowersLoading",!0);n(this,"isZapsLoading",!0);n(this,"stats",{follows:0,followers:0,notes:0,replies:0,zaps:0,relays:0});n(this,"getUserStats",async()=>{try{this.isStatsLoading=!0,this.isStatsFollowsLoading=!0,this.isStatsFollowersLoading=!0,this.isZapsLoading=!0,this.nostrService.fetchFollows(this.user).then(t=>{this.stats={...this.stats,follows:t},this.isStatsFollowsLoading=!1,this.render()}).catch(t=>{console.error("Error loading follows:",t),this.isStatsFollowsLoading=!1,this.render()}),this.nostrService.fetchFollowers(this.user).then(t=>{this.stats={...this.stats,followers:t},this.isStatsFollowersLoading=!1,this.render()}).catch(t=>{console.error("Error loading followers:",t),this.isStatsFollowersLoading=!1,this.render()}),this.nostrService.fetchNotesAndReplies(this.user).then(([t,s])=>{this.stats={...this.stats,notes:t,replies:s},this.isStatsLoading=!1,this.render()}).catch(t=>{console.error("Error loading notes and replies",t),this.isStatsLoading=!1,this.render()}),this.nostrService.fetchZaps(this.user).then(t=>{this.stats={...this.stats,zaps:t},this.isZapsLoading=!1,this.render()}).catch(t=>{console.error("Error loading Zaps:",t),this.isZapsLoading=!1,this.render()})}catch(t){this.profileStatus.set(p.Error),console.error("getUserStats failed:",t)}finally{this.render()}})}static get observedAttributes(){return[...super.observedAttributes,"show-npub","show-follow"]}async connectedCallback(){var t;(t=super.connectedCallback)==null||t.call(this),this.attachDelegatedListeners(),A({addDelegatedListener:this.addDelegatedListener.bind(this)}),this.render()}onStatusChange(t){this.render()}onUserReady(t,s){this.getUserStats(),this.render()}attributeChangedCallback(t,s,i){var r;s!==i&&((r=super.attributeChangedCallback)==null||r.call(this,t,s,i),(t==="show-npub"||t==="show-follow")&&this.render())}onProfileClick(){var s,i;if(this.profileStatus.get()===p.Error)return;const t=((s=this.user)==null?void 0:s.npub)||this.getAttribute("npub")||((i=this.profile)==null?void 0:i.nip05)||this.getAttribute("nip05");t&&this.handleNjumpClick(j,this.profile,encodeURIComponent(t))}attachDelegatedListeners(){this.delegateEvent("click",".profile-banner",t=>{t.target.closest(".nc-copy-btn, .nostr-follow-button-container, nostr-follow-button")||this.onProfileClick()})}renderContent(){var c;const t=this.computeOverall()===p.Loading,s=this.computeOverall()===p.Error,i=this.getAttribute("show-npub")==="true",r=this.getAttribute("show-follow")==="true",d={isLoading:t,isError:s,errorMessage:this.errorMessage,npub:((c=this.user)==null?void 0:c.npub)||"",userProfile:this.profile,isStatsLoading:this.isStatsLoading,isStatsFollowersLoading:this.isStatsFollowersLoading,isStatsFollowsLoading:this.isStatsFollowsLoading,isZapsLoading:this.isZapsLoading,stats:{notes:this.stats.notes,replies:this.stats.replies,follows:this.stats.follows,followers:this.stats.followers,zaps:this.stats.zaps,relays:this.stats.relays},showFollow:r,showNpub:i};this.shadowRoot.innerHTML=`
284
+ ${_()}
285
+ ${R(d)}
286
+ `}}customElements.define("nostr-profile",O);
287
+ //# sourceMappingURL=nostr-profile.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nostr-profile.es.js","sources":["../../src/nostr-profile/render-stats.ts","../../src/nostr-profile/render.ts","../../src/nostr-profile/style.ts","../../src/nostr-profile/nostr-profile.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { escapeHtml } from \"../common/utils\";\n\nexport function renderStats(\n label: string,\n value: number,\n isLoading: boolean\n): string {\n const safeLabel = escapeHtml(label)\n return `\n <div class=\"stat\" data-orientation=\"horizontal\" aria-busy=\"${isLoading}\" aria-live=\"polite\">\n <div class=\"stat-inner\">\n <div class=\"stat-value\">\n ${\n isLoading\n ? '<div style=\"width: 50px; height: 28px; border-radius: 5px\" class=\"skeleton\"></div>'\n : value.toLocaleString()\n }\n </div>\n <div class=\"stat-name\">${safeLabel}</div>\n </div>\n </div>\n `;\n}\n","// SPDX-License-Identifier: MIT\n\nimport { NDKUserProfile } from '@nostr-dev-kit/ndk';\nimport { IRenderOptions } from '../base/render-options';\nimport { renderNpub } from '../base/text-row/render-npub';\nimport { renderNip05 } from '../base/text-row/render-nip05';\nimport { renderStats } from './render-stats';\nimport { renderName } from '../base/text-row/render-name';\nimport { renderTextRow } from '../base/text-row/render-text-row';\n\nexport interface Stats {\n notes: number;\n replies: number;\n follows: number;\n followers: number;\n zaps: number;\n relays: number;\n}\n\nexport interface RenderProfileOptions extends IRenderOptions {\n npub: string;\n userProfile: NDKUserProfile;\n isStatsLoading: boolean;\n isStatsFollowersLoading: boolean;\n isStatsFollowsLoading: boolean;\n isZapsLoading: boolean;\n stats: Stats;\n showFollow: boolean;\n showNpub: boolean;\n}\n\nexport function renderProfile(options: RenderProfileOptions): string {\n const {\n isLoading,\n isError,\n errorMessage,\n npub,\n userProfile,\n isStatsLoading,\n isStatsFollowersLoading,\n isStatsFollowsLoading,\n isZapsLoading,\n stats,\n showFollow,\n showNpub,\n } = options;\n\n if (isError) {\n return renderError(errorMessage || '');\n }\n\n // Extract profile data with null checks and default values\n const displayName = userProfile?.displayName || userProfile?.name || '';\n const nip05 = userProfile?.nip05 || '';\n const image = userProfile?.picture || '';\n const about = userProfile?.about || '';\n const website = userProfile?.website || '';\n\n const renderFollowButton = () => {\n if (!showFollow || npub === '') return '';\n return `\n <nostr-follow-button\n npub=\"${npub}\">\n </nostr-follow-button>\n `;\n };\n\n return `\n <div class=\"nostr-profile-container\">\n <div class=\"profile-banner\">\n ${isLoading\n ? '<div style=\"width: 100%; height: 100%;\" class=\"skeleton\"></div>'\n : userProfile?.banner\n ? `<img src=\"${userProfile.banner}\" width=\"524px\"/>`\n : '<div class=\"banner-placeholder\"></div>'\n }\n\n <div class=\"dp-container\">\n <div class=\"avatar\" role=\"img\" aria-label=\"${displayName}\">\n ${isLoading\n ? '<div style=\"width: 100%; height: 100%; border-radius: 50%\" class=\"skeleton\"></div>'\n : `<img\n src=\"${image}\"\n alt=\"${displayName}\"\n width=\"142\" height=\"142\"\n loading=\"lazy\" decoding=\"async\"\n onerror=\"this.onerror=null; this.src='data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 142 142%22%3E%3Crect width=%22142%22 height=%22142%22 fill=%22%23ccc%22/%3E%3C/svg%3E'\"\n />`\n }\n </div>\n </div>\n </div>\n\n <div class=\"profile_actions\">\n ${showFollow ?\n isLoading? '<div style=\"width: 100px; height: 36px; border-radius: 18px;\" class=\"skeleton\"></div>'\n : renderFollowButton()\n : ''\n }\n </div>\n \n <div class=\"profile_data\">\n ${isLoading\n ? '<div style=\"width: 100px; height: 24px;\" class=\"skeleton\"></div>'\n : renderName({ name: displayName })\n }\n \n ${isLoading\n ? '<div style=\"width: 75px; height: 20px;\" class=\"skeleton\"></div>'\n : renderNip05(nip05)\n }\n\n ${showNpub ?\n isLoading\n ? '<div style=\"width: 75px; height: 20px;\" class=\"skeleton\"></div>'\n : renderNpub(npub)\n : ''\n }\n\n <div class=\"margin-bottom-md\"> </div>\n \n ${isLoading\n ? `<div style=\"width: 100%; margin-bottom: 12px; height: 18px\" class=\"skeleton\"></div>`\n : renderTextRow({ display: about, value: about })\n }\n\n <div class=\"margin-bottom-md\"> </div>\n \n ${isLoading\n ? '<div style=\"width: 150px\" class=\"skeleton\"></div>'\n : website\n ? `<div class=\"website\">\n <a target=\"_blank\" href=\"${website}\">${website}</a>\n </div>`\n : ''\n }\n \n <div class=\"stats\">\n\n ${renderStats('Following', stats.follows, isStatsFollowsLoading)}\n \n ${renderStats('Followers', stats.followers, isStatsFollowersLoading)}\n\n ${renderStats('Notes', stats.notes, isStatsLoading)}\n \n ${renderStats('Replies', stats.replies, isStatsLoading)}\n \n ${renderStats('Zaps', stats.zaps, isZapsLoading)}\n \n </div>\n </div>\n </div>\n `;\n}\n\nfunction renderError(errorMessage: string): string {\n return `\n <div class='nostr-profile-container'>\n <div class='nostr-profile-top-container'>\n <div class=\"error-icon\">&#9888;</div>\n </div>\n <div class='nostr-profile-bottom-container'>\n ${errorMessage}\n </div>\n </div>\n `;\n}","// SPDX-License-Identifier: MIT\n\nimport { getComponentStyles } from \"../common/base-styles\";\n\nexport function getProfileStyles(): string {\n const customStyles = `\n /* === PROFILE CSS VARIABLES & CONTAINER PATTERN === */\n :host {\n /* Override follow button styles for profile context */\n --nostrc-follow-btn-padding: 5px 8px !important;\n --nostrc-follow-btn-font-size: 14px !important;\n --nostrc-follow-btn-border-radius: 12px !important;\n --nostrc-follow-btn-border: var(--nostrc-border-width) solid var(--nostrc-color-border) !important;\n --nostrc-follow-btn-horizontal-alignment: end !important;\n --nostrc-follow-btn-min-height: auto !important;\n --nostrc-follow-btn-width: 280px;\n\n /* Component theme variables (fallback to global theme tokens) */\n --nostrc-profile-bg: var(--nostrc-theme-bg, #ffffff);\n --nostrc-profile-text-primary: var(--nostrc-theme-text-primary, #333333);\n --nostrc-profile-text-secondary: var(--nostrc-theme-text-secondary, #666666);\n --nostrc-profile-border: var(--nostrc-theme-border, var(--nostrc-border-width) solid var(--nostrc-color-border));\n --nostrc-profile-banner-placeholder: var(--nostrc-profile-border);\n --nostrc-profile-font-family: var(--nostrc-font-family-primary);\n --nostrc-profile-font-size: var(--nostrc-font-size-base);\n \n /* Hover state variables */\n --nostrc-profile-hover-bg: var(--nostrc-theme-hover-bg, rgba(0, 0, 0, 0.05));\n --nostrc-profile-hover-color: var(--nostrc-theme-text-primary, #333333);\n --nostrc-profile-hover-border: var(--nostrc-theme-hover-border, var(--nostrc-border-width) solid var(--nostrc-color-border));\n\n /* Make the host the visual profile surface */\n display: block;\n background: var(--nostrc-profile-bg);\n color: var(--nostrc-profile-text-primary);\n border: var(--nostrc-profile-border);\n border-radius: var(--nostrc-border-radius-md);\n font-family: var(--nostrc-profile-font-family);\n font-size: var(--nostrc-profile-font-size);\n transition: background-color var(--nostrc-transition-duration) var(--nostrc-transition-timing);\n }\n\n .nostr-profile-container {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--nostrc-spacing-md);\n min-height: 500px;\n padding: 0px;\n }\n\n :host(.is-error) .nostr-profile-container {\n justify-content: center;\n align-items: center;\n color: var(--nostrc-color-error-text);\n border: var(--nostrc-border-width) solid var(--nostrc-color-error-text);\n }\n\n /* Hover state */\n :host(.is-clickable:hover) {\n background: var(--nostrc-profile-hover-bg);\n color: var(--nostrc-profile-hover-color);\n border: var(--nostrc-profile-hover-border);\n }\n\n .nostr-profile-top-container img {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n object-fit: cover;\n }\n\n .nostr-profile-bottom-container {\n min-width: 0;\n text-align: center;\n }\n\n .profile-banner {\n position: relative;\n width: 100%;\n height: 214px;\n cursor: pointer;\n border-radius: var(--nostrc-border-radius-md) var(--nostrc-border-radius-md) 0px 0px;\n }\n\n .banner-placeholder {\n width: 100%;\n height: 100%;\n background-color: var(--nostrc-profile-banner-placeholder);\n border-radius: var(--nostrc-border-radius-md) var(--nostrc-border-radius-md) 0px 0px;\n }\n\n .profile-banner img {\n width: 100%;\n height: 214px;\n object-fit: cover;\n }\n\n .dp-container {\n position: absolute;\n top: 140px;\n left: var(--nostrc-spacing-md);\n }\n\n .avatar {\n --avatar-size: 142px;\n --avatar-ring: 4px;\n\n inline-size: var(--avatar-size);\n block-size: var(--avatar-size);\n border-radius: var(--nostrc-border-radius-full);\n overflow: hidden;\n\n /* ring + backfill in one place */\n background-color: var(--nostrc-profile-bg);\n border: var(--avatar-ring) solid var(--nostrc-profile-bg);\n }\n\n .avatar img {\n inline-size: 100%;\n block-size: 100%;\n border-radius: var(--nostrc-border-radius-full);\n display: block;\n object-fit: cover;\n }\n\n .profile_actions {\n height: 56px;\n align-self: flex-end;\n padding: 0 var(--nostrc-spacing-lg);\n }\n\n .profile_data {\n padding: var(--nostrc-spacing-md);\n }\n\n .website {\n font-weight: 400;\n font-size: var(--nostrc-font-size-base);\n line-height: 20px;\n display: flex;\n align-items: center;\n }\n\n .website a {\n line-height: 20px;\n outline: none;\n color: var(--nostrc-profile-accent);\n max-width: 350px;\n overflow: hidden;\n text-overflow: ellipsis;\n word-wrap: normal;\n }\n\n .stats {\n position: relative;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: space-between;\n align-items: center;\n border-radius: 0;\n border-top: none;\n margin-top: var(--nostrc-spacing-md);\n }\n\n .stat {\n position: relative;\n display: inline-block;\n padding-inline: var(--nostrc-spacing-md);\n padding-block: var(--nostrc-spacing-xs);\n border: none;\n background: none;\n width: fit-content;\n height: 40px;\n margin: 0 0 var(--nostrc-spacing-md);\n }\n\n .stat-inner {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n }\n\n .stat-inner .stat-value {\n font-weight: 100;\n font-size: 1.5em;\n color: var(--nostrc-profile-text-primary);\n }\n\n .stat-inner .stat-name {\n font-weight: 400;\n line-height: 16px;\n text-transform: lowercase;\n color: var(--nostrc-profile-text-secondary);\n }\n\n @media only screen and (max-width: 600px) {\n .stat .stat-value {\n font-size: 18px !important;\n }\n :host {\n --nostrc-follow-btn-padding: 5px 8px !important;\n --nostrc-follow-btn-font-size: 12px !important;\n --nostrc-follow-btn-min-height: auto !important;\n --nostrc-follow-btn-border-radius: 8px !important;\n --nostrc-follow-btn-error-max-width: 150px !important;\n }\n }\n\n `;\n \n // Use component styles - includes design tokens + utilities + custom styles\n return getComponentStyles(customStyles);\n}\n","// SPDX-License-Identifier: MIT\n\nimport { NCStatus } from '../base/base-component/nostr-base-component';\nimport { NostrUserComponent } from '../base/user-component/nostr-user-component';\nimport { renderProfile, RenderProfileOptions } from './render';\nimport { getProfileStyles } from './style';\nimport { attachCopyDelegation } from '../base/copy-delegation';\n\nconst EVT_PROFILE = 'nc:profile';\n\nexport default class NostrProfile extends NostrUserComponent {\n\n protected profileStatus = this.channel('profile');\n\n // Stats loading states\n private isStatsLoading: boolean = true;\n private isStatsFollowsLoading: boolean = true;\n private isStatsFollowersLoading: boolean = true;\n private isZapsLoading: boolean = true;\n\n private stats = {\n follows: 0,\n followers: 0,\n notes: 0,\n replies: 0,\n zaps: 0,\n relays: 0,\n };\n\n static get observedAttributes() {\n return [\n ...super.observedAttributes,\n 'show-npub',\n 'show-follow',\n ];\n }\n\n async connectedCallback() {\n super.connectedCallback?.();\n this.attachDelegatedListeners();\n attachCopyDelegation({\n addDelegatedListener: this.addDelegatedListener.bind(this),\n });\n this.render();\n }\n\n /** Base class functions */\n protected onStatusChange(_status: NCStatus) {\n this.render();\n }\n\n protected onUserReady(_user: any, _profile: any) {\n this.getUserStats();\n this.render();\n }\n\n getUserStats = async () => {\n try {\n this.isStatsLoading = true;\n this.isStatsFollowsLoading = true;\n this.isStatsFollowersLoading = true;\n this.isZapsLoading = true;\n\n // Fetch follows\n this.nostrService\n .fetchFollows(this.user!)\n .then((follows) => {\n this.stats = { ...this.stats, follows };\n this.isStatsFollowsLoading = false;\n this.render();\n })\n .catch(err => {\n console.error('Error loading follows:', err);\n this.isStatsFollowsLoading = false;\n this.render();\n });\n\n // Fetch followers\n this.nostrService\n .fetchFollowers(this.user!)\n .then((followers) => {\n this.stats = { ...this.stats, followers };\n this.isStatsFollowersLoading = false;\n this.render();\n })\n .catch(err => {\n console.error('Error loading followers:', err);\n this.isStatsFollowersLoading = false;\n this.render();\n });\n\n // Fetch notes and replies\n this.nostrService\n .fetchNotesAndReplies(this.user!)\n .then(([ notes, replies ]) => {\n this.stats = { ...this.stats, notes, replies };\n this.isStatsLoading = false;\n this.render();\n })\n .catch(err => {\n console.error('Error loading notes and replies', err);\n this.isStatsLoading = false;\n this.render();\n });\n\n // Fetch zaps\n this.nostrService\n .fetchZaps(this.user!)\n .then((zaps) => {\n this.stats = { ...this.stats, zaps };\n this.isZapsLoading = false;\n this.render();\n })\n .catch(err => {\n console.error('Error loading Zaps:', err);\n this.isZapsLoading = false;\n this.render();\n });\n\n\n } catch (err) {\n this.profileStatus.set(NCStatus.Error);\n console.error('getUserStats failed:', err);\n } finally {\n this.render();\n }\n };\n\n attributeChangedCallback(\n name: string,\n oldValue: string | null,\n newValue: string | null\n ) {\n if (oldValue === newValue) return;\n super.attributeChangedCallback?.(name, oldValue, newValue);\n\n if (name === 'show-npub' || name === 'show-follow') {\n this.render();\n }\n }\n\n /** Private functions */\n private onProfileClick() {\n if (this.profileStatus.get() === NCStatus.Error) return;\n\n const key =\n this.user?.npub ||\n this.getAttribute('npub') ||\n this.profile?.nip05 ||\n this.getAttribute('nip05');\n\n if (key) {\n this.handleNjumpClick(EVT_PROFILE, this.profile, encodeURIComponent(key));\n }\n }\n\n private attachDelegatedListeners() {\n\n // Click anywhere on the profile badge (except follow button, copy buttons)\n this.delegateEvent('click', '.profile-banner', (e: Event) => {\n const target = e.target as HTMLElement;\n if (!target.closest('.nc-copy-btn, .nostr-follow-button-container, nostr-follow-button')) {\n this.onProfileClick();\n }\n });\n\n }\n\n protected renderContent() {\n const isLoading = this.computeOverall() === NCStatus.Loading;\n const isError = this.computeOverall() === NCStatus.Error;\n const showNpub = this.getAttribute('show-npub') === 'true';\n const showFollow = this.getAttribute('show-follow') === 'true';\n\n const renderOptions: RenderProfileOptions = {\n isLoading: isLoading,\n isError: isError,\n errorMessage: this.errorMessage,\n npub: this.user?.npub || '',\n userProfile: this.profile!,\n isStatsLoading: this.isStatsLoading,\n isStatsFollowersLoading: this.isStatsFollowersLoading,\n isStatsFollowsLoading: this.isStatsFollowsLoading,\n isZapsLoading: this.isZapsLoading,\n stats: {\n notes: this.stats.notes,\n replies: this.stats.replies,\n follows: this.stats.follows,\n followers: this.stats.followers,\n zaps: this.stats.zaps,\n relays: this.stats.relays,\n },\n showFollow: showFollow,\n showNpub: showNpub,\n };\n\n this.shadowRoot!.innerHTML = `\n ${getProfileStyles()}\n ${renderProfile(renderOptions)}\n `;\n\n }\n}\n\ncustomElements.define('nostr-profile', NostrProfile);\n"],"names":["renderStats","label","value","isLoading","safeLabel","escapeHtml","renderProfile","options","isError","errorMessage","npub","userProfile","isStatsLoading","isStatsFollowersLoading","isStatsFollowsLoading","isZapsLoading","stats","showFollow","showNpub","renderError","displayName","nip05","image","about","website","renderFollowButton","renderName","renderNip05","renderNpub","renderTextRow","getProfileStyles","getComponentStyles","EVT_PROFILE","NostrProfile","NostrUserComponent","__publicField","follows","err","followers","notes","replies","zaps","NCStatus","_a","attachCopyDelegation","_status","_user","_profile","name","oldValue","newValue","key","_b","e","renderOptions"],"mappings":"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"}