Add hide attribute to sequoia-comments component
9ef18c3f
Resolves #1
4 file(s) · +114 −124
Resolves #1
| 24 | 24 | }, |
|
| 25 | 25 | "packages/cli": { |
|
| 26 | 26 | "name": "sequoia-cli", |
|
| 27 | - | "version": "0.3.2", |
|
| 27 | + | "version": "0.4.0", |
|
| 28 | 28 | "bin": { |
|
| 29 | 29 | "sequoia": "dist/index.js", |
|
| 30 | 30 | }, |
|
| 41 | 41 | "devDependencies": { |
|
| 42 | 42 | "@biomejs/biome": "^2.3.13", |
|
| 43 | 43 | "@types/mime-types": "^3.0.1", |
|
| 44 | - | "@types/node": "^20", |
|
| 45 | - | }, |
|
| 46 | - | "peerDependencies": { |
|
| 47 | - | "typescript": "^5", |
|
| 48 | - | }, |
|
| 49 | - | }, |
|
| 50 | - | "packages/ui": { |
|
| 51 | - | "name": "sequoia-ui", |
|
| 52 | - | "version": "0.1.0", |
|
| 53 | - | "devDependencies": { |
|
| 54 | - | "@biomejs/biome": "^2.3.13", |
|
| 55 | 44 | "@types/node": "^20", |
|
| 56 | 45 | }, |
|
| 57 | 46 | "peerDependencies": { |
|
| 1369 | 1358 | "send": ["send@0.19.2", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "~0.5.2", "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "~2.4.1", "range-parser": "~1.2.1", "statuses": "~2.0.2" } }, "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg=="], |
|
| 1370 | 1359 | ||
| 1371 | 1360 | "sequoia-cli": ["sequoia-cli@workspace:packages/cli"], |
|
| 1372 | - | ||
| 1373 | - | "sequoia-ui": ["sequoia-ui@workspace:packages/ui"], |
|
| 1374 | 1361 | ||
| 1375 | 1362 | "serve-static": ["serve-static@1.16.3", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "~0.19.1" } }, "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA=="], |
|
| 1376 | 1363 | ||
| 143 | 143 | |-----------|------|---------|-------------| |
|
| 144 | 144 | | `document-uri` | `string` | - | AT Protocol URI for the document. Optional if a `<link rel="site.standard.document">` tag exists in the page head. | |
|
| 145 | 145 | | `depth` | `number` | `6` | Maximum depth of nested replies to fetch. | |
|
| 146 | + | | `hide` | `string` | - | Set to "auto" to hide if no document link is detected | |
|
| 146 | 147 | ||
| 147 | 148 | ```html |
|
| 148 | 149 | <!-- Use attributes for explicit control --> |
| 14 | 14 | * Attributes: |
|
| 15 | 15 | * - document-uri: AT Protocol URI for the document (optional if link tag exists) |
|
| 16 | 16 | * - depth: Maximum depth of nested replies to fetch (default: 6) |
|
| 17 | + | * - hide: Set to "auto" to hide if no document link is detected |
|
| 17 | 18 | * |
|
| 18 | 19 | * CSS Custom Properties: |
|
| 19 | 20 | * - --sequoia-fg-color: Text color (default: #1f2937) |
|
| 573 | 574 | class SequoiaComments extends BaseElement { |
|
| 574 | 575 | constructor() { |
|
| 575 | 576 | super(); |
|
| 576 | - | this.shadow = this.attachShadow({ mode: "open" }); |
|
| 577 | + | const shadow = this.attachShadow({ mode: "open" }); |
|
| 578 | + | ||
| 579 | + | const styleTag = document.createElement("style"); |
|
| 580 | + | shadow.appendChild(styleTag); |
|
| 581 | + | styleTag.innerText = styles; |
|
| 582 | + | ||
| 583 | + | const container = document.createElement("div"); |
|
| 584 | + | shadow.appendChild(container); |
|
| 585 | + | container.className = "sequoia-comments-container"; |
|
| 586 | + | container.part = "container"; |
|
| 587 | + | ||
| 588 | + | this.commentsContainer = container; |
|
| 577 | 589 | this.state = { type: "loading" }; |
|
| 578 | 590 | this.abortController = null; |
|
| 591 | + | ||
| 579 | 592 | } |
|
| 580 | 593 | ||
| 581 | 594 | static get observedAttributes() { |
|
| 582 | - | return ["document-uri", "depth"]; |
|
| 595 | + | return ["document-uri", "depth", "hide"]; |
|
| 583 | 596 | } |
|
| 584 | 597 | ||
| 585 | 598 | connectedCallback() { |
|
| 614 | 627 | get depth() { |
|
| 615 | 628 | const depthAttr = this.getAttribute("depth"); |
|
| 616 | 629 | return depthAttr ? parseInt(depthAttr, 10) : 6; |
|
| 630 | + | } |
|
| 631 | + | ||
| 632 | + | get hide() { |
|
| 633 | + | const hideAttr = this.getAttribute("hide"); |
|
| 634 | + | return hideAttr === "auto"; |
|
| 617 | 635 | } |
|
| 618 | 636 | ||
| 619 | 637 | async loadComments() { |
|
| 666 | 684 | } |
|
| 667 | 685 | ||
| 668 | 686 | render() { |
|
| 669 | - | const styleTag = `<style>${styles}</style>`; |
|
| 670 | - | ||
| 671 | 687 | switch (this.state.type) { |
|
| 672 | 688 | case "loading": |
|
| 673 | - | this.shadow.innerHTML = ` |
|
| 674 | - | ${styleTag} |
|
| 675 | - | <div class="sequoia-comments-container"> |
|
| 676 | - | <div class="sequoia-loading"> |
|
| 677 | - | <span class="sequoia-loading-spinner"></span> |
|
| 678 | - | Loading comments... |
|
| 679 | - | </div> |
|
| 689 | + | this.commentsContainer.innerHTML = ` |
|
| 690 | + | <div class="sequoia-loading"> |
|
| 691 | + | <span class="sequoia-loading-spinner"></span> |
|
| 692 | + | Loading comments... |
|
| 680 | 693 | </div> |
|
| 681 | 694 | `; |
|
| 682 | 695 | break; |
|
| 683 | 696 | ||
| 684 | 697 | case "no-document": |
|
| 685 | - | this.shadow.innerHTML = ` |
|
| 686 | - | ${styleTag} |
|
| 687 | - | <div class="sequoia-comments-container"> |
|
| 688 | - | <div class="sequoia-warning"> |
|
| 689 | - | No document found. Add a <code><link rel="site.standard.document" href="at://..."></code> tag to your page. |
|
| 690 | - | </div> |
|
| 698 | + | this.commentsContainer.innerHTML = ` |
|
| 699 | + | <div class="sequoia-warning"> |
|
| 700 | + | No document found. Add a <code><link rel="site.standard.document" href="at://..."></code> tag to your page. |
|
| 691 | 701 | </div> |
|
| 692 | 702 | `; |
|
| 703 | + | if (this.hide) { |
|
| 704 | + | this.commentsContainer.style.display = 'none'; |
|
| 705 | + | } |
|
| 693 | 706 | break; |
|
| 694 | 707 | ||
| 695 | 708 | case "no-comments-enabled": |
|
| 696 | - | this.shadow.innerHTML = ` |
|
| 697 | - | ${styleTag} |
|
| 698 | - | <div class="sequoia-comments-container"> |
|
| 699 | - | <div class="sequoia-empty"> |
|
| 700 | - | Comments are not enabled for this post. |
|
| 701 | - | </div> |
|
| 709 | + | this.commentsContainer.innerHTML = ` |
|
| 710 | + | <div class="sequoia-empty"> |
|
| 711 | + | Comments are not enabled for this post. |
|
| 702 | 712 | </div> |
|
| 703 | 713 | `; |
|
| 704 | 714 | break; |
|
| 705 | 715 | ||
| 706 | 716 | case "empty": |
|
| 707 | - | this.shadow.innerHTML = ` |
|
| 708 | - | ${styleTag} |
|
| 709 | - | <div class="sequoia-comments-container"> |
|
| 710 | - | <div class="sequoia-comments-header"> |
|
| 711 | - | <h3 class="sequoia-comments-title">Comments</h3> |
|
| 712 | - | <a href="${this.state.postUrl}" target="_blank" rel="noopener noreferrer" class="sequoia-reply-button"> |
|
| 713 | - | ${BLUESKY_ICON} |
|
| 714 | - | Reply on Bluesky |
|
| 715 | - | </a> |
|
| 716 | - | </div> |
|
| 717 | - | <div class="sequoia-empty"> |
|
| 718 | - | No comments yet. Be the first to reply on Bluesky! |
|
| 719 | - | </div> |
|
| 717 | + | this.commentsContainer.innerHTML = ` |
|
| 718 | + | <div class="sequoia-comments-header"> |
|
| 719 | + | <h3 class="sequoia-comments-title">Comments</h3> |
|
| 720 | + | <a href="${this.state.postUrl}" target="_blank" rel="noopener noreferrer" class="sequoia-reply-button"> |
|
| 721 | + | ${BLUESKY_ICON} |
|
| 722 | + | Reply on Bluesky |
|
| 723 | + | </a> |
|
| 724 | + | </div> |
|
| 725 | + | <div class="sequoia-empty"> |
|
| 726 | + | No comments yet. Be the first to reply on Bluesky! |
|
| 720 | 727 | </div> |
|
| 721 | 728 | `; |
|
| 722 | 729 | break; |
|
| 723 | 730 | ||
| 724 | 731 | case "error": |
|
| 725 | - | this.shadow.innerHTML = ` |
|
| 726 | - | ${styleTag} |
|
| 727 | - | <div class="sequoia-comments-container"> |
|
| 728 | - | <div class="sequoia-error"> |
|
| 729 | - | Failed to load comments: ${escapeHtml(this.state.message)} |
|
| 730 | - | </div> |
|
| 732 | + | this.commentsContainer.innerHTML = ` |
|
| 733 | + | <div class="sequoia-error"> |
|
| 734 | + | Failed to load comments: ${escapeHtml(this.state.message)} |
|
| 731 | 735 | </div> |
|
| 732 | 736 | `; |
|
| 733 | 737 | break; |
|
| 740 | 744 | .join(""); |
|
| 741 | 745 | const commentCount = this.countComments(replies); |
|
| 742 | 746 | ||
| 743 | - | this.shadow.innerHTML = ` |
|
| 744 | - | ${styleTag} |
|
| 745 | - | <div class="sequoia-comments-container"> |
|
| 746 | - | <div class="sequoia-comments-header"> |
|
| 747 | - | <h3 class="sequoia-comments-title">${commentCount} Comment${commentCount !== 1 ? "s" : ""}</h3> |
|
| 748 | - | <a href="${this.state.postUrl}" target="_blank" rel="noopener noreferrer" class="sequoia-reply-button"> |
|
| 749 | - | ${BLUESKY_ICON} |
|
| 750 | - | Reply on Bluesky |
|
| 751 | - | </a> |
|
| 752 | - | </div> |
|
| 753 | - | <div class="sequoia-comments-list"> |
|
| 754 | - | ${threadsHtml} |
|
| 755 | - | </div> |
|
| 747 | + | this.commentsContainer.innerHTML = ` |
|
| 748 | + | <div class="sequoia-comments-header"> |
|
| 749 | + | <h3 class="sequoia-comments-title">${commentCount} Comment${commentCount !== 1 ? "s" : ""}</h3> |
|
| 750 | + | <a href="${this.state.postUrl}" target="_blank" rel="noopener noreferrer" class="sequoia-reply-button"> |
|
| 751 | + | ${BLUESKY_ICON} |
|
| 752 | + | Reply on Bluesky |
|
| 753 | + | </a> |
|
| 754 | + | </div> |
|
| 755 | + | <div class="sequoia-comments-list"> |
|
| 756 | + | ${threadsHtml} |
|
| 756 | 757 | </div> |
|
| 757 | 758 | `; |
|
| 758 | 759 | break; |
|
| 14 | 14 | * Attributes: |
|
| 15 | 15 | * - document-uri: AT Protocol URI for the document (optional if link tag exists) |
|
| 16 | 16 | * - depth: Maximum depth of nested replies to fetch (default: 6) |
|
| 17 | + | * - hide: Set to "auto" to hide if no document link is detected |
|
| 17 | 18 | * |
|
| 18 | 19 | * CSS Custom Properties: |
|
| 19 | 20 | * - --sequoia-fg-color: Text color (default: #1f2937) |
|
| 573 | 574 | class SequoiaComments extends BaseElement { |
|
| 574 | 575 | constructor() { |
|
| 575 | 576 | super(); |
|
| 576 | - | this.shadow = this.attachShadow({ mode: "open" }); |
|
| 577 | + | const shadow = this.attachShadow({ mode: "open" }); |
|
| 578 | + | ||
| 579 | + | const styleTag = document.createElement("style"); |
|
| 580 | + | shadow.appendChild(styleTag); |
|
| 581 | + | styleTag.innerText = styles; |
|
| 582 | + | ||
| 583 | + | const container = document.createElement("div"); |
|
| 584 | + | shadow.appendChild(container); |
|
| 585 | + | container.className = "sequoia-comments-container"; |
|
| 586 | + | container.part = "container"; |
|
| 587 | + | ||
| 588 | + | this.commentsContainer = container; |
|
| 577 | 589 | this.state = { type: "loading" }; |
|
| 578 | 590 | this.abortController = null; |
|
| 591 | + | ||
| 579 | 592 | } |
|
| 580 | 593 | ||
| 581 | 594 | static get observedAttributes() { |
|
| 582 | - | return ["document-uri", "depth"]; |
|
| 595 | + | return ["document-uri", "depth", "hide"]; |
|
| 583 | 596 | } |
|
| 584 | 597 | ||
| 585 | 598 | connectedCallback() { |
|
| 614 | 627 | get depth() { |
|
| 615 | 628 | const depthAttr = this.getAttribute("depth"); |
|
| 616 | 629 | return depthAttr ? parseInt(depthAttr, 10) : 6; |
|
| 630 | + | } |
|
| 631 | + | ||
| 632 | + | get hide() { |
|
| 633 | + | const hideAttr = this.getAttribute("hide"); |
|
| 634 | + | return hideAttr === "auto"; |
|
| 617 | 635 | } |
|
| 618 | 636 | ||
| 619 | 637 | async loadComments() { |
|
| 666 | 684 | } |
|
| 667 | 685 | ||
| 668 | 686 | render() { |
|
| 669 | - | const styleTag = `<style>${styles}</style>`; |
|
| 670 | - | ||
| 671 | 687 | switch (this.state.type) { |
|
| 672 | 688 | case "loading": |
|
| 673 | - | this.shadow.innerHTML = ` |
|
| 674 | - | ${styleTag} |
|
| 675 | - | <div class="sequoia-comments-container"> |
|
| 676 | - | <div class="sequoia-loading"> |
|
| 677 | - | <span class="sequoia-loading-spinner"></span> |
|
| 678 | - | Loading comments... |
|
| 679 | - | </div> |
|
| 689 | + | this.commentsContainer.innerHTML = ` |
|
| 690 | + | <div class="sequoia-loading"> |
|
| 691 | + | <span class="sequoia-loading-spinner"></span> |
|
| 692 | + | Loading comments... |
|
| 680 | 693 | </div> |
|
| 681 | 694 | `; |
|
| 682 | 695 | break; |
|
| 683 | 696 | ||
| 684 | 697 | case "no-document": |
|
| 685 | - | this.shadow.innerHTML = ` |
|
| 686 | - | ${styleTag} |
|
| 687 | - | <div class="sequoia-comments-container"> |
|
| 688 | - | <div class="sequoia-warning"> |
|
| 689 | - | No document found. Add a <code><link rel="site.standard.document" href="at://..."></code> tag to your page. |
|
| 690 | - | </div> |
|
| 698 | + | this.commentsContainer.innerHTML = ` |
|
| 699 | + | <div class="sequoia-warning"> |
|
| 700 | + | No document found. Add a <code><link rel="site.standard.document" href="at://..."></code> tag to your page. |
|
| 691 | 701 | </div> |
|
| 692 | 702 | `; |
|
| 703 | + | if (this.hide) { |
|
| 704 | + | this.commentsContainer.style.display = 'none'; |
|
| 705 | + | } |
|
| 693 | 706 | break; |
|
| 694 | 707 | ||
| 695 | 708 | case "no-comments-enabled": |
|
| 696 | - | this.shadow.innerHTML = ` |
|
| 697 | - | ${styleTag} |
|
| 698 | - | <div class="sequoia-comments-container"> |
|
| 699 | - | <div class="sequoia-empty"> |
|
| 700 | - | Comments are not enabled for this post. |
|
| 701 | - | </div> |
|
| 709 | + | this.commentsContainer.innerHTML = ` |
|
| 710 | + | <div class="sequoia-empty"> |
|
| 711 | + | Comments are not enabled for this post. |
|
| 702 | 712 | </div> |
|
| 703 | 713 | `; |
|
| 704 | 714 | break; |
|
| 705 | 715 | ||
| 706 | 716 | case "empty": |
|
| 707 | - | this.shadow.innerHTML = ` |
|
| 708 | - | ${styleTag} |
|
| 709 | - | <div class="sequoia-comments-container"> |
|
| 710 | - | <div class="sequoia-comments-header"> |
|
| 711 | - | <h3 class="sequoia-comments-title">Comments</h3> |
|
| 712 | - | <a href="${this.state.postUrl}" target="_blank" rel="noopener noreferrer" class="sequoia-reply-button"> |
|
| 713 | - | ${BLUESKY_ICON} |
|
| 714 | - | Reply on Bluesky |
|
| 715 | - | </a> |
|
| 716 | - | </div> |
|
| 717 | - | <div class="sequoia-empty"> |
|
| 718 | - | No comments yet. Be the first to reply on Bluesky! |
|
| 719 | - | </div> |
|
| 717 | + | this.commentsContainer.innerHTML = ` |
|
| 718 | + | <div class="sequoia-comments-header"> |
|
| 719 | + | <h3 class="sequoia-comments-title">Comments</h3> |
|
| 720 | + | <a href="${this.state.postUrl}" target="_blank" rel="noopener noreferrer" class="sequoia-reply-button"> |
|
| 721 | + | ${BLUESKY_ICON} |
|
| 722 | + | Reply on Bluesky |
|
| 723 | + | </a> |
|
| 724 | + | </div> |
|
| 725 | + | <div class="sequoia-empty"> |
|
| 726 | + | No comments yet. Be the first to reply on Bluesky! |
|
| 720 | 727 | </div> |
|
| 721 | 728 | `; |
|
| 722 | 729 | break; |
|
| 723 | 730 | ||
| 724 | 731 | case "error": |
|
| 725 | - | this.shadow.innerHTML = ` |
|
| 726 | - | ${styleTag} |
|
| 727 | - | <div class="sequoia-comments-container"> |
|
| 728 | - | <div class="sequoia-error"> |
|
| 729 | - | Failed to load comments: ${escapeHtml(this.state.message)} |
|
| 730 | - | </div> |
|
| 732 | + | this.commentsContainer.innerHTML = ` |
|
| 733 | + | <div class="sequoia-error"> |
|
| 734 | + | Failed to load comments: ${escapeHtml(this.state.message)} |
|
| 731 | 735 | </div> |
|
| 732 | 736 | `; |
|
| 733 | 737 | break; |
|
| 740 | 744 | .join(""); |
|
| 741 | 745 | const commentCount = this.countComments(replies); |
|
| 742 | 746 | ||
| 743 | - | this.shadow.innerHTML = ` |
|
| 744 | - | ${styleTag} |
|
| 745 | - | <div class="sequoia-comments-container"> |
|
| 746 | - | <div class="sequoia-comments-header"> |
|
| 747 | - | <h3 class="sequoia-comments-title">${commentCount} Comment${commentCount !== 1 ? "s" : ""}</h3> |
|
| 748 | - | <a href="${this.state.postUrl}" target="_blank" rel="noopener noreferrer" class="sequoia-reply-button"> |
|
| 749 | - | ${BLUESKY_ICON} |
|
| 750 | - | Reply on Bluesky |
|
| 751 | - | </a> |
|
| 752 | - | </div> |
|
| 753 | - | <div class="sequoia-comments-list"> |
|
| 754 | - | ${threadsHtml} |
|
| 755 | - | </div> |
|
| 747 | + | this.commentsContainer.innerHTML = ` |
|
| 748 | + | <div class="sequoia-comments-header"> |
|
| 749 | + | <h3 class="sequoia-comments-title">${commentCount} Comment${commentCount !== 1 ? "s" : ""}</h3> |
|
| 750 | + | <a href="${this.state.postUrl}" target="_blank" rel="noopener noreferrer" class="sequoia-reply-button"> |
|
| 751 | + | ${BLUESKY_ICON} |
|
| 752 | + | Reply on Bluesky |
|
| 753 | + | </a> |
|
| 754 | + | </div> |
|
| 755 | + | <div class="sequoia-comments-list"> |
|
| 756 | + | ${threadsHtml} |
|
| 756 | 757 | </div> |
|
| 757 | 758 | `; |
|
| 758 | 759 | break; |
|