@@ -17,6 +17,10 @@ const sortedTypes = [...new Set(extensions.map(ext => ext.type))]
1717const sortedCategories = [... new Set (extensions .flatMap (ext => ext .categories ))]
1818 .sort ((a , b ) => a .localeCompare (b ));
1919
20+ // Collect unique filterTypes from extensions and sort alphabetically
21+ const sortedFilterTypes = [... new Set (extensions .flatMap (ext => ext .filterType ))]
22+ .sort ((a , b ) => a .localeCompare (b ));
23+
2024// Helper function to format type names (snake_case to Title Case)
2125function formatTypeName(type : string ): string {
2226 return type
@@ -69,6 +73,14 @@ function formatTypeName(type: string): string {
6973 ))}
7074 </select >
7175 </div >
76+ <div class =" filter-type-filter" >
77+ <select id =" filter-type-filter" aria-label =" Filter by filter type" >
78+ <option value =" " >All Filter Types</option >
79+ { sortedFilterTypes .map (filterType => (
80+ <option value = { filterType } >{ formatTypeName (filterType )} </option >
81+ ))}
82+ </select >
83+ </div >
7284 </div >
7385 </div >
7486 </section >
@@ -87,6 +99,7 @@ function formatTypeName(type: string): string {
8799 description = { ext .description }
88100 href = { ` /extensions/${ext .name } ` }
89101 tags = { ext .tags }
102+ filterTypes = { ext .filterType }
90103 />
91104 </div >
92105 ))}
@@ -114,13 +127,15 @@ function formatTypeName(type: string): string {
114127 const searchInput = document.getElementById('search-input') as HTMLInputElement;
115128 const typeFilter = document.getElementById('type-filter') as HTMLSelectElement;
116129 const categoryFilter = document.getElementById('category-filter') as HTMLSelectElement;
130+ const filterTypeFilter = document.getElementById('filter-type-filter') as HTMLSelectElement;
117131 const extensionsGrid = document.getElementById('extensions-grid');
118132 const noResults = document.getElementById('no-results');
119133
120134 function filterExtensions() {
121135 const searchTerm = searchInput?.value.toLowerCase() || '';
122136 const selectedType = typeFilter?.value || '';
123137 const selectedCategory = categoryFilter?.value || '';
138+ const selectedFilterType = filterTypeFilter?.value || '';
124139
125140 const cardWrappers = extensionsGrid?.querySelectorAll('[data-categories]');
126141 let visibleCount = 0;
@@ -132,15 +147,17 @@ function formatTypeName(type: string): string {
132147 const type = (card as HTMLElement)?.dataset.type || '';
133148 const tags = (card as HTMLElement)?.dataset.tags?.toLowerCase() || '';
134149 const categories = (wrapper as HTMLElement).dataset.categories?.split(',') || [];
150+ const filterTypes = (card as HTMLElement)?.dataset.filterTypes?.split(',') || [];
135151
136152 const matchesSearch = searchTerm === '' ||
137153 name.includes(searchTerm) ||
138154 description.includes(searchTerm) ||
139155 tags.includes(searchTerm);
140156 const matchesType = selectedType === '' || type === selectedType;
141157 const matchesCategory = selectedCategory === '' || categories.includes(selectedCategory);
158+ const matchesFilterType = selectedFilterType === '' || filterTypes.includes(selectedFilterType);
142159
143- if (matchesSearch && matchesType && matchesCategory) {
160+ if (matchesSearch && matchesType && matchesCategory && matchesFilterType ) {
144161 (wrapper as HTMLElement).style.display = '';
145162 visibleCount++;
146163 } else {
@@ -164,6 +181,7 @@ function formatTypeName(type: string): string {
164181 searchInput?.addEventListener('input', filterExtensions);
165182 typeFilter?.addEventListener('change', filterExtensions);
166183 categoryFilter?.addEventListener('change', filterExtensions);
184+ filterTypeFilter?.addEventListener('change', filterExtensions);
167185 </script >
168186 </body >
169187</html >
0 commit comments