This is an automated email from the ASF dual-hosted git repository.

xushiyan pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/hudi.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new d49ba986af27 chore(site): add selected tags and improve blog filtering 
UI (#17927)
d49ba986af27 is described below

commit d49ba986af27373ef222ea4af5cb09d92ac4e1cc
Author: Shiyan Xu <[email protected]>
AuthorDate: Sat Jan 17 12:36:16 2026 -0600

    chore(site): add selected tags and improve blog filtering UI (#17927)
---
 website/src/components/BlogList/index.js           |  34 ++++++-
 .../src/components/ContentList/styles.module.css   | 102 ++++++++++++++++++++-
 2 files changed, 128 insertions(+), 8 deletions(-)

diff --git a/website/src/components/BlogList/index.js 
b/website/src/components/BlogList/index.js
index 3e27bed593a5..3d88756396e2 100644
--- a/website/src/components/BlogList/index.js
+++ b/website/src/components/BlogList/index.js
@@ -102,12 +102,14 @@ export default function BlogList() {
       filtered = filtered.filter((elem) => elem.frontMatter.category === 
category);
     }
 
-    // Filter by search query - only search by title (case-insensitive)
+    // Filter by search query - search title, tags, and description 
(case-insensitive)
     if(searchQuery.trim()) {
       const query = searchQuery.toLowerCase().trim();
       filtered = filtered.filter((post) => {
         const title = post.metadata?.title?.toLowerCase() || '';
-        return title.includes(query);
+        const description = post.metadata?.description?.toLowerCase() || '';
+        const tags = (post.frontMatter?.tags || []).map(t => 
t.toLowerCase()).join(' ');
+        return title.includes(query) || description.includes(query) || 
tags.includes(query);
       });
     }
 
@@ -218,7 +220,7 @@ export default function BlogList() {
     };
 
     // Sort categories alphabetically, with known ones first in preferred order
-    const preferredOrder = ['community', 'deep-dive', 'how-to', 'case-study'];
+    const preferredOrder = ['deep-dive', 'how-to', 'case-study', 'community'];
     const sortedCategories = Array.from(categorySet).sort((a, b) => {
       const aIndex = preferredOrder.indexOf(a);
       const bIndex = preferredOrder.indexOf(b);
@@ -335,6 +337,32 @@ export default function BlogList() {
             </button>
           ))}
         </div>
+        {selectedTags.length > 0 && (
+          <div className={styles.selectedTagsRow}>
+            {selectedTags.map(tag => (
+              <span key={tag} className={styles.selectedTag}>
+                {tag}
+                <button
+                  className={styles.removeTagButton}
+                  onClick={() => handleTagClick(tag)}
+                  type="button"
+                  aria-label={`Remove ${tag} filter`}
+                >
+                  <svg viewBox="0 0 12 12" fill="none" 
xmlns="http://www.w3.org/2000/svg";>
+                    <path d="M9 3L3 9M3 3L9 9" stroke="currentColor" 
strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
+                  </svg>
+                </button>
+              </span>
+            ))}
+            <button
+              className={styles.clearAllButton}
+              onClick={handleClearTags}
+              type="button"
+            >
+              Clear All
+            </button>
+          </div>
+        )}
       </div>
       <div 
key={`${category}-${searchQuery}-${selectedTags.join(',')}-${currentPage}`} 
className={styles.gridWrapper}>
         <div className={styles.grid}>
diff --git a/website/src/components/ContentList/styles.module.css 
b/website/src/components/ContentList/styles.module.css
index 7840587383a1..8bf6d6790bee 100644
--- a/website/src/components/ContentList/styles.module.css
+++ b/website/src/components/ContentList/styles.module.css
@@ -158,7 +158,7 @@
   line-clamp: 3;
   -webkit-box-orient: vertical;
   overflow: hidden;
-  font-family: var(--ifm-heading-font-family);
+  font-family: var(--ifm-font-family-base);
 }
 
 /* Pagination styles */
@@ -320,7 +320,7 @@
   display: flex;
   flex-direction: column;
   gap: 20px;
-  margin-bottom: 60px;
+  margin-bottom: 25px;
   width: 100%;
 }
 
@@ -376,7 +376,8 @@
   background: transparent;
   border: 0;
   color: var(--ifm-blue-900);
-  font-weight: 600;
+  font-family: var(--ifm-font-family-base);
+  font-weight: 700;
   font-size: 16px;
   padding: 10px 14px;
   border-radius: 20px;
@@ -447,6 +448,7 @@
   background: transparent;
   border: 1px solid rgba(10, 37, 64, 0.15);
   color: var(--ifm-blue-900);
+  font-family: var(--ifm-font-family-base);
   font-weight: 400;
   font-size: 14px;
   padding: 6px 12px;
@@ -509,7 +511,9 @@
   border: 0;
   background: transparent;
   outline: none;
+  font-family: var(--ifm-font-family-base);
   font-size: 16px;
+  font-weight: 400;
   color: var(--ifm-blue-900);
   width: 100%;
   min-width: 250px;
@@ -518,8 +522,6 @@
 .searchInput::placeholder {
   color: var(--ifm-blue-900);
   opacity: 0.4;
-  font-size: 14px;
-  font-weight: 400;
 }
 
 .searchInput:focus {
@@ -534,6 +536,9 @@
   .categoryBar {
     gap: 14px;
     padding: 8px 12px;
+    flex-wrap: wrap;
+    white-space: normal;
+    overflow-x: visible;
   }
 
   .category, .categoryActive {
@@ -565,5 +570,92 @@
   .searchInput {
     font-size: 15px;
   }
+
+  .selectedTagsRow {
+    gap: 6px;
+  }
+
+  .selectedTag {
+    padding: 4px 8px;
+    font-size: 13px;
+    gap: 4px;
+  }
+
+  .removeTagButton {
+    width: 14px;
+    height: 14px;
+  }
+
+  .clearAllButton {
+    font-size: 13px;
+  }
+}
+
+/* Selected Tags Row */
+.selectedTagsRow {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  gap: 8px;
+  align-items: center;
+}
+
+.selectedTag {
+  display: inline-flex;
+  align-items: center;
+  gap: 6px;
+  padding: 5px 10px;
+  background: var(--ifm-gray-100);
+  border: 1px solid rgba(10, 37, 64, 0.15);
+  border-radius: 16px;
+  font-family: var(--ifm-font-family-base);
+  font-size: 14px;
+  font-weight: 400;
+  color: var(--ifm-blue-900);
+}
+
+.removeTagButton {
+  appearance: none;
+  background: transparent;
+  border: 0;
+  padding: 0;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 16px;
+  height: 16px;
+  border-radius: 50%;
+  color: var(--ifm-blue-900);
+  opacity: 0.6;
+  transition: opacity 150ms ease, background 150ms ease;
+}
+
+.removeTagButton:hover {
+  opacity: 1;
+  background: rgba(10, 37, 64, 0.1);
+}
+
+.removeTagButton svg {
+  width: 10px;
+  height: 10px;
+}
+
+.clearAllButton {
+  appearance: none;
+  background: transparent;
+  border: 0;
+  padding: 5px 10px;
+  font-family: var(--ifm-font-family-base);
+  font-size: 14px;
+  font-weight: 400;
+  color: var(--ifm-blue-900);
+  cursor: pointer;
+  opacity: 0.6;
+  transition: opacity 150ms ease;
+}
+
+.clearAllButton:hover {
+  opacity: 1;
 }
 

Reply via email to