executable-stories-formatters 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -812,37 +812,56 @@ function initSearch() {
812
812
 
813
813
  // Tag filter
814
814
  function initTagFilter() {
815
+ var toggleBtn = document.querySelector('.tag-bar-toggle');
816
+ var tagBar = document.querySelector('.tag-bar');
817
+ if (toggleBtn && tagBar) {
818
+ toggleBtn.addEventListener('click', function() {
819
+ var isCollapsed = tagBar.classList.toggle('tag-bar-collapsed');
820
+ toggleBtn.setAttribute('aria-expanded', String(!isCollapsed));
821
+ });
822
+ }
823
+
815
824
  document.querySelectorAll('.tag-pill').forEach(function(pill) {
816
825
  pill.addEventListener('click', function() {
817
826
  var tag = pill.dataset.tag;
818
827
  if (activeTags.has(tag)) {
819
828
  activeTags.delete(tag);
820
829
  pill.classList.remove('active');
830
+ pill.setAttribute('aria-pressed', 'false');
821
831
  } else {
822
832
  activeTags.add(tag);
823
833
  pill.classList.add('active');
834
+ pill.setAttribute('aria-pressed', 'true');
824
835
  }
825
- updateClearButton();
836
+ updateTagBarState();
826
837
  applyAllFilters();
827
838
  });
828
839
  });
829
840
 
830
841
  var clearBtn = document.querySelector('.tag-bar-clear');
831
842
  if (clearBtn) {
832
- clearBtn.addEventListener('click', function() {
843
+ clearBtn.addEventListener('click', function(e) {
844
+ e.stopPropagation();
833
845
  activeTags.clear();
834
- document.querySelectorAll('.tag-pill.active').forEach(function(p) { p.classList.remove('active'); });
835
- updateClearButton();
846
+ document.querySelectorAll('.tag-pill.active').forEach(function(p) {
847
+ p.classList.remove('active');
848
+ p.setAttribute('aria-pressed', 'false');
849
+ });
850
+ updateTagBarState();
836
851
  applyAllFilters();
837
852
  });
838
853
  }
839
854
  }
840
855
 
841
- function updateClearButton() {
856
+ function updateTagBarState() {
842
857
  var clearBtn = document.querySelector('.tag-bar-clear');
858
+ var countBadge = document.querySelector('.tag-bar-count');
843
859
  if (clearBtn) {
844
860
  clearBtn.style.display = activeTags.size > 0 ? '' : 'none';
845
861
  }
862
+ if (countBadge) {
863
+ countBadge.textContent = activeTags.size > 0 ? activeTags.size + ' selected' : '';
864
+ }
846
865
  }
847
866
 
848
867
  // Status filter (clickable summary cards)
@@ -1543,7 +1562,24 @@ body {
1543
1562
  display: flex;
1544
1563
  justify-content: space-between;
1545
1564
  align-items: center;
1546
- margin-bottom: 0.5rem;
1565
+ }
1566
+
1567
+ .tag-bar-toggle {
1568
+ display: flex;
1569
+ align-items: center;
1570
+ gap: 0.5rem;
1571
+ background: none;
1572
+ border: none;
1573
+ cursor: pointer;
1574
+ padding: 0;
1575
+ color: inherit;
1576
+ font: inherit;
1577
+ }
1578
+
1579
+ .tag-bar-toggle:focus-visible {
1580
+ outline: 2px solid var(--ring);
1581
+ outline-offset: 2px;
1582
+ border-radius: var(--radius);
1547
1583
  }
1548
1584
 
1549
1585
  .tag-bar-label {
@@ -1554,26 +1590,58 @@ body {
1554
1590
  font-weight: 500;
1555
1591
  }
1556
1592
 
1593
+ .tag-bar-count {
1594
+ font-size: 0.6875rem;
1595
+ font-weight: 600;
1596
+ color: var(--primary);
1597
+ }
1598
+
1599
+ .tag-bar-chevron {
1600
+ color: var(--muted-foreground);
1601
+ transition: transform 0.2s ease;
1602
+ flex-shrink: 0;
1603
+ }
1604
+
1605
+ .tag-bar-collapsed .tag-bar-chevron {
1606
+ transform: rotate(0deg);
1607
+ }
1608
+
1609
+ .tag-bar:not(.tag-bar-collapsed) .tag-bar-chevron {
1610
+ transform: rotate(180deg);
1611
+ }
1612
+
1557
1613
  .tag-bar-clear {
1558
1614
  font-size: 0.75rem;
1559
1615
  font-weight: 500;
1560
- color: var(--primary);
1561
- background: none;
1562
- border: none;
1616
+ color: var(--destructive, #dc2626);
1617
+ background: var(--destructive-light, #fef2f2);
1618
+ border: 1px solid var(--destructive-border, #fecaca);
1563
1619
  cursor: pointer;
1564
- padding: 0.125rem 0.5rem;
1620
+ padding: 0.25rem 0.75rem;
1565
1621
  border-radius: var(--radius);
1566
1622
  transition: all 0.15s ease;
1567
1623
  }
1568
1624
 
1569
1625
  .tag-bar-clear:hover {
1570
- background: var(--muted);
1626
+ background: var(--destructive-border, #fecaca);
1627
+ }
1628
+
1629
+ .tag-bar-clear:focus-visible {
1630
+ outline: 2px solid var(--ring);
1631
+ outline-offset: 2px;
1571
1632
  }
1572
1633
 
1573
1634
  .tag-bar-pills {
1574
1635
  display: flex;
1575
1636
  flex-wrap: wrap;
1576
1637
  gap: 0.375rem;
1638
+ max-height: 200px;
1639
+ overflow-y: auto;
1640
+ margin-top: 0.5rem;
1641
+ }
1642
+
1643
+ .tag-bar-collapsed .tag-bar-pills {
1644
+ display: none;
1577
1645
  }
1578
1646
 
1579
1647
  .tag-pill {
@@ -1593,6 +1661,11 @@ body {
1593
1661
  background: var(--success-border);
1594
1662
  }
1595
1663
 
1664
+ .tag-pill:focus-visible {
1665
+ outline: 2px solid var(--ring);
1666
+ outline-offset: 2px;
1667
+ }
1668
+
1596
1669
  .tag-pill.active {
1597
1670
  background: var(--primary);
1598
1671
  color: var(--primary-foreground);
@@ -2749,19 +2822,25 @@ function renderTagBar(args, deps) {
2749
2822
  const { tags, totalScenarios } = args;
2750
2823
  if (tags.length === 0) return "";
2751
2824
  const pills = tags.map(
2752
- (tag) => `<button type="button" class="tag-pill" data-tag="${deps.escapeHtml(tag)}">${deps.escapeHtml(tag)}</button>`
2753
- ).join("\n ");
2825
+ (tag) => `<button type="button" class="tag-pill" data-tag="${deps.escapeHtml(tag)}" aria-pressed="false">${deps.escapeHtml(tag)}</button>`
2826
+ ).join("\n ");
2754
2827
  return `
2755
- <div class="tag-bar">
2828
+ <div class="tag-bar tag-bar-collapsed">
2756
2829
  <div class="tag-bar-header">
2757
- <span class="tag-bar-label">Filter by tag</span>
2758
- <button type="button" class="tag-bar-clear" style="display:none">Clear</button>
2830
+ <button type="button" class="tag-bar-toggle" aria-expanded="false" aria-controls="tag-pills-region">
2831
+ <span class="tag-bar-label">Filter by tag</span>
2832
+ <span class="tag-bar-count" aria-live="polite"></span>
2833
+ <svg class="tag-bar-chevron" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
2834
+ <path d="M4 6l4 4 4-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
2835
+ </svg>
2836
+ </button>
2837
+ <button type="button" class="tag-bar-clear" aria-label="Clear all tag filters" style="display:none">Clear all</button>
2759
2838
  </div>
2760
- <div class="tag-bar-pills">
2839
+ <div id="tag-pills-region" class="tag-bar-pills" role="group" aria-label="Tag filters">
2761
2840
  ${pills}
2762
2841
  </div>
2763
2842
  </div>
2764
- <div class="filter-results" style="display:none">
2843
+ <div class="filter-results" style="display:none" aria-live="polite">
2765
2844
  Showing <span class="visible-count">0</span> of <span class="total-count">${totalScenarios}</span> scenarios
2766
2845
  </div>`;
2767
2846
  }