npm package: @hajtech/markup-filter
Description: A flexible markup-based filter component with dynamic filtering and view switching
Author: Pascal Riedel
Latest version: 0.0.3

# 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

```bash
npm install markup-filter
```

## Usage

### Basic Setup

Import the module in your JavaScript/TypeScript file:

```javascript
import 'markup-filter';
```

Or if you want to manually initialize:

```typescript
import { Filter } from 'markup-filter';

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

### HTML Markup

```html
<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

```html
<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

```html
<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

```html
<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:

```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:

```typescript
import { Filter } from 'markup-filter';

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

## Development

```bash
# 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.