npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@hajtech/markup-filter

v0.0.3

Published

A flexible markup-based filter component with dynamic filtering and view switching

Downloads

179

Readme

markup-filter

A flexible, lightweight TypeScript-based filter component for dynamic content filtering with view switching capabilities. Filter your content using data attributes with support for AND/OR logic.

Features

  • 🎯 Flexible Filtering: Support for both AND and OR logic per filter category
  • 🔄 Dynamic View Switching: Toggle between different content views
  • 🏷️ Filter Chips: Visual representation of active filters
  • 📱 Responsive: Works seamlessly across all device sizes
  • 🎨 Customizable: Style it to match your design system
  • 📦 Zero Dependencies: Pure TypeScript implementation
  • 🚀 TypeScript Support: Full type definitions included
  • Lightweight: Minimal footprint

Installation

npm install markup-filter

Usage

Basic Setup

Import the module in your JavaScript/TypeScript file:

import 'markup-filter';

Or if you want to manually initialize:

import { Filter } from 'markup-filter';

const container = document.querySelector('[data-filter-container]');
if (container) {
  new Filter(container as HTMLElement);
}

HTML Markup

<div data-filter-container='{"country": "or", "type": "and"}'>
  <!-- Filter buttons -->
  <button data-filter-property="country">Filter by Country</button>
  <button data-filter-property="type">Filter by Type</button>
  
  <!-- Filter options dropdown containers -->
  <div data-filter-property-option="country"></div>
  <div data-filter-property-option="type"></div>
  
  <!-- Chip area for selected filters -->
  <div data-filter-chip-area class="hidden">
    <div data-filter-chips></div>
  </div>
  
  <!-- Chip template (hidden, will be cloned) -->
  <div data-filter-chip-template class="hidden">
    <span></span>
    <button>×</button>
  </div>
  
  <!-- Filterable items -->
  <div data-filter-item 
       data-filter-country='{"de": "Germany", "ch": "Switzerland"}' 
       data-filter-type='{"hotel": "Hotel", "resort": "Resort"}'>
    <h3>Item Title</h3>
    <p>Item content...</p>
  </div>
  
  <div data-filter-item 
       data-filter-country='{"de": "Germany"}' 
       data-filter-type='{"hotel": "Hotel"}'>
    <h3>Another Item</h3>
    <p>More content...</p>
  </div>
</div>

Data Attributes

Container

  • data-filter-container: Defines filter properties and their logic
    • Value: JSON object with property names as keys and "or" or "and" as values
    • Example: {"country": "or", "type": "and"}

Filter Controls

  • data-filter-property: Button that toggles filter dropdown
    • Value: Property name matching a key in data-filter-container
  • data-filter-property-option: Container for filter checkboxes
    • Value: Property name matching a key in data-filter-container

Display Elements

  • data-filter-chip-area: Container for the chip area (hidden when no filters active)
  • data-filter-chips: Container where filter chips are rendered
  • data-filter-chip-template: Template for filter chips (will be cloned)

Filterable Items

  • data-filter-item: Marks an element as filterable
  • data-filter-{property}: Contains filter values for this property
    • Value: JSON object with IDs as keys and display names as values
    • Example: data-filter-country='{"de": "Germany", "ch": "Switzerland"}'

Advanced Features

  • data-filter-display-condition: Show/hide element based on active filters

    • Value: Property name that must have active filters
    • Example: data-filter-display-condition="country"
  • data-country-headline: Special marker for grouping headlines (e.g., country sections)

  • data-cluster-mapping: Group filter options into categories

    • Value: JSON array of cluster definitions
    • Example: [{"Title": "Europe", "Items": {"de": true, "ch": true}}]

View Switcher

  • data-view-switcher-button: Button to switch views
    • Value: View identifier
  • data-view-switcher-area: Content area for specific view
    • Value: View identifier matching button

Examples

Simple Country Filter

<div data-filter-container='{"country": "or"}'>
  <button data-filter-property="country">Countries</button>
  <div data-filter-property-option="country"></div>
  
  <div data-filter-item data-filter-country='{"de": "Germany"}'>
    German Item
  </div>
  
  <div data-filter-item data-filter-country='{"ch": "Switzerland"}'>
    Swiss Item
  </div>
</div>

Multiple Filters with AND/OR Logic

<div data-filter-container='{"country": "or", "category": "and"}'>
  <button data-filter-property="country">Country</button>
  <button data-filter-property="category">Category</button>
  
  <div data-filter-property-option="country"></div>
  <div data-filter-property-option="category"></div>
  
  <div data-filter-chip-area class="hidden">
    <div data-filter-chips></div>
  </div>
  
  <div data-filter-chip-template class="hidden">
    <span></span>
    <button>×</button>
  </div>
  
  <div data-filter-item 
       data-filter-country='{"de": "Germany"}' 
       data-filter-category='{"premium": "Premium", "budget": "Budget"}'>
    Premium & Budget options in Germany
  </div>
</div>

With View Switcher

<div data-filter-container='{"type": "or"}'>
  <!-- View switcher buttons -->
  <button data-view-switcher-button="list">List View</button>
  <button data-view-switcher-button="grid">Grid View</button>
  
  <!-- View areas -->
  <div data-view-switcher-area="list">
    <!-- List view content -->
  </div>
  
  <div data-view-switcher-area="grid">
    <!-- Grid view content -->
  </div>
  
  <!-- Filters -->
  <button data-filter-property="type">Type</button>
  <div data-filter-property-option="type"></div>
  
  <div data-filter-item data-filter-type='{"a": "Type A"}'>
    Item
  </div>
</div>

Filter Logic

OR Logic

When a property uses "or" logic, items are shown if they match any of the selected filter values.

Example: Country filter with "Germany" and "Switzerland" selected will show items that have either Germany OR Switzerland.

AND Logic

When a property uses "and" logic, items are shown only if they match all selected filter values.

Example: Category filter with "Premium" and "Pool" selected will show only items that have both Premium AND Pool.

Styling

The library adds/removes the hidden class to show/hide elements. You can style this in your CSS:

.hidden {
  display: none !important;
}

.filter__checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px;
}

/* View switcher active/inactive states */
.active__btn {
  background-color: #007bff;
  color: white;
}

.inactive__btn {
  background-color: #f0f0f0;
  color: #333;
}

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

The library uses modern JavaScript features (ES2020) and requires a browser with DOM support.

TypeScript

Full TypeScript support is included. The main export is the Filter class:

import { Filter } from 'markup-filter';

const container = document.querySelector<HTMLElement>('[data-filter-container]');
if (container) {
  const filterInstance = new Filter(container);
}

Development

# Install dependencies
npm install

# Build the package
npm run build

# Watch mode for development
npm run dev

# Type checking
npm run type-check

License

MIT License - see LICENSE file for details

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.