add slot to overwrite buttons, but needs post-uri a0ddd6f9
Pascal Hertleif · 2026-04-22 14:18 1 file(s) · +28 −16
packages/cli/src/components/sequoia-comments.js +28 −16
11 11
 *   1. The `document-uri` attribute on the element
12 12
 *   2. A <link rel="site.standard.document" href="at://..."> tag in the document head
13 13
 *
14 +
 * Custom reply button:
15 +
 *   Place any element with slot="reply-button" to replace the default Bluesky/Blacksky buttons.
16 +
 *   It stays in the light DOM, so your page CSS applies to it normally.
17 +
 *   Only practical with post-uri, since that's the only time the URL is known at authoring time:
18 +
 *     <sequoia-comments post-uri="https://bsky.app/profile/.../post/...">
19 +
 *       <a slot="reply-button" href="https://bsky.app/profile/.../post/...">Reply</a>
20 +
 *     </sequoia-comments>
21 +
 *
14 22
 * Attributes:
15 23
 *   - post-uri: Bluesky post as AT-URI (at://...) or bsky.app URL — skips PDS document lookup
16 24
 *   - document-uri: AT Protocol URI for the document (optional if link tag exists)
853 861
				this.commentsContainer.innerHTML = `
854 862
					<div class="sequoia-comments-header">
855 863
						<h3 class="sequoia-comments-title">Comments</h3>
856 -
						<div>
857 -
							<a href="${this.state.postUrl}" target="_blank" rel="noopener noreferrer" class="sequoia-reply-button sequoia-reply-bluesky">
858 -
								${BLUESKY_ICON}
859 -
							</a>
860 -
							<a href="${this.state.blackskyPostUrl}" target="_blank" rel="noopener noreferrer" class="sequoia-reply-button sequoia-reply-blacksky">
861 -
								${BLACKSKY_ICON}
862 -
							</a>
863 -
						</div>
864 +
						<div>${this.renderReplyButtons(this.state.postUrl, this.state.blackskyPostUrl)}</div>
864 865
					</div>
865 866
					<div class="sequoia-empty">
866 867
						No comments yet. Be the first to reply on Bluesky!
893 894
				this.commentsContainer.innerHTML = `
894 895
					<div class="sequoia-comments-header">
895 896
						<h3 class="sequoia-comments-title">${titleText}</h3>
896 -
						<div>
897 -
							<a href="${this.state.postUrl}" target="_blank" rel="noopener noreferrer" class="sequoia-reply-button sequoia-reply-bluesky">
898 -
								${BLUESKY_ICON}
899 -
							</a>
900 -
							<a href="${this.state.blackskyPostUrl}" target="_blank" rel="noopener noreferrer" class="sequoia-reply-button sequoia-reply-blacksky">
901 -
								${BLACKSKY_ICON}
902 -
							</a>
903 -
						</div>
897 +
						<div>${this.renderReplyButtons(this.state.postUrl, this.state.blackskyPostUrl)}</div>
904 898
					</div>
905 899
					<div class="sequoia-comments-list">
906 900
						${threadsHtml}
932 926
		}
933 927
934 928
		return result;
929 +
	}
930 +
931 +
	/**
932 +
	 * Render the reply-button slot. Any element with slot="reply-button" in the
933 +
	 * light DOM is projected here and remains styleable by external CSS.
934 +
	 * The default Bluesky/Blacksky buttons are used as fallback content.
935 +
	 */
936 +
	renderReplyButtons(postUrl, blackskyPostUrl) {
937 +
		return `
938 +
			<slot name="reply-button">
939 +
				<a href="${escapeHtml(postUrl)}" target="_blank" rel="noopener noreferrer" class="sequoia-reply-button sequoia-reply-bluesky">
940 +
					${BLUESKY_ICON}
941 +
				</a>
942 +
				<a href="${escapeHtml(blackskyPostUrl)}" target="_blank" rel="noopener noreferrer" class="sequoia-reply-button sequoia-reply-blacksky">
943 +
					${BLACKSKY_ICON}
944 +
				</a>
945 +
			</slot>
946 +
		`;
935 947
	}
936 948
937 949
	/**