executable-stories-formatters 0.5.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/cli.js CHANGED
@@ -924,37 +924,56 @@ function initSearch() {
924
924
 
925
925
  // Tag filter
926
926
  function initTagFilter() {
927
+ var toggleBtn = document.querySelector('.tag-bar-toggle');
928
+ var tagBar = document.querySelector('.tag-bar');
929
+ if (toggleBtn && tagBar) {
930
+ toggleBtn.addEventListener('click', function() {
931
+ var isCollapsed = tagBar.classList.toggle('tag-bar-collapsed');
932
+ toggleBtn.setAttribute('aria-expanded', String(!isCollapsed));
933
+ });
934
+ }
935
+
927
936
  document.querySelectorAll('.tag-pill').forEach(function(pill) {
928
937
  pill.addEventListener('click', function() {
929
938
  var tag = pill.dataset.tag;
930
939
  if (activeTags.has(tag)) {
931
940
  activeTags.delete(tag);
932
941
  pill.classList.remove('active');
942
+ pill.setAttribute('aria-pressed', 'false');
933
943
  } else {
934
944
  activeTags.add(tag);
935
945
  pill.classList.add('active');
946
+ pill.setAttribute('aria-pressed', 'true');
936
947
  }
937
- updateClearButton();
948
+ updateTagBarState();
938
949
  applyAllFilters();
939
950
  });
940
951
  });
941
952
 
942
953
  var clearBtn = document.querySelector('.tag-bar-clear');
943
954
  if (clearBtn) {
944
- clearBtn.addEventListener('click', function() {
955
+ clearBtn.addEventListener('click', function(e) {
956
+ e.stopPropagation();
945
957
  activeTags.clear();
946
- document.querySelectorAll('.tag-pill.active').forEach(function(p) { p.classList.remove('active'); });
947
- updateClearButton();
958
+ document.querySelectorAll('.tag-pill.active').forEach(function(p) {
959
+ p.classList.remove('active');
960
+ p.setAttribute('aria-pressed', 'false');
961
+ });
962
+ updateTagBarState();
948
963
  applyAllFilters();
949
964
  });
950
965
  }
951
966
  }
952
967
 
953
- function updateClearButton() {
968
+ function updateTagBarState() {
954
969
  var clearBtn = document.querySelector('.tag-bar-clear');
970
+ var countBadge = document.querySelector('.tag-bar-count');
955
971
  if (clearBtn) {
956
972
  clearBtn.style.display = activeTags.size > 0 ? '' : 'none';
957
973
  }
974
+ if (countBadge) {
975
+ countBadge.textContent = activeTags.size > 0 ? activeTags.size + ' selected' : '';
976
+ }
958
977
  }
959
978
 
960
979
  // Status filter (clickable summary cards)
@@ -1655,7 +1674,24 @@ body {
1655
1674
  display: flex;
1656
1675
  justify-content: space-between;
1657
1676
  align-items: center;
1658
- margin-bottom: 0.5rem;
1677
+ }
1678
+
1679
+ .tag-bar-toggle {
1680
+ display: flex;
1681
+ align-items: center;
1682
+ gap: 0.5rem;
1683
+ background: none;
1684
+ border: none;
1685
+ cursor: pointer;
1686
+ padding: 0;
1687
+ color: inherit;
1688
+ font: inherit;
1689
+ }
1690
+
1691
+ .tag-bar-toggle:focus-visible {
1692
+ outline: 2px solid var(--ring);
1693
+ outline-offset: 2px;
1694
+ border-radius: var(--radius);
1659
1695
  }
1660
1696
 
1661
1697
  .tag-bar-label {
@@ -1666,26 +1702,58 @@ body {
1666
1702
  font-weight: 500;
1667
1703
  }
1668
1704
 
1705
+ .tag-bar-count {
1706
+ font-size: 0.6875rem;
1707
+ font-weight: 600;
1708
+ color: var(--primary);
1709
+ }
1710
+
1711
+ .tag-bar-chevron {
1712
+ color: var(--muted-foreground);
1713
+ transition: transform 0.2s ease;
1714
+ flex-shrink: 0;
1715
+ }
1716
+
1717
+ .tag-bar-collapsed .tag-bar-chevron {
1718
+ transform: rotate(0deg);
1719
+ }
1720
+
1721
+ .tag-bar:not(.tag-bar-collapsed) .tag-bar-chevron {
1722
+ transform: rotate(180deg);
1723
+ }
1724
+
1669
1725
  .tag-bar-clear {
1670
1726
  font-size: 0.75rem;
1671
1727
  font-weight: 500;
1672
- color: var(--primary);
1673
- background: none;
1674
- border: none;
1728
+ color: var(--destructive, #dc2626);
1729
+ background: var(--destructive-light, #fef2f2);
1730
+ border: 1px solid var(--destructive-border, #fecaca);
1675
1731
  cursor: pointer;
1676
- padding: 0.125rem 0.5rem;
1732
+ padding: 0.25rem 0.75rem;
1677
1733
  border-radius: var(--radius);
1678
1734
  transition: all 0.15s ease;
1679
1735
  }
1680
1736
 
1681
1737
  .tag-bar-clear:hover {
1682
- background: var(--muted);
1738
+ background: var(--destructive-border, #fecaca);
1739
+ }
1740
+
1741
+ .tag-bar-clear:focus-visible {
1742
+ outline: 2px solid var(--ring);
1743
+ outline-offset: 2px;
1683
1744
  }
1684
1745
 
1685
1746
  .tag-bar-pills {
1686
1747
  display: flex;
1687
1748
  flex-wrap: wrap;
1688
1749
  gap: 0.375rem;
1750
+ max-height: 200px;
1751
+ overflow-y: auto;
1752
+ margin-top: 0.5rem;
1753
+ }
1754
+
1755
+ .tag-bar-collapsed .tag-bar-pills {
1756
+ display: none;
1689
1757
  }
1690
1758
 
1691
1759
  .tag-pill {
@@ -1705,6 +1773,11 @@ body {
1705
1773
  background: var(--success-border);
1706
1774
  }
1707
1775
 
1776
+ .tag-pill:focus-visible {
1777
+ outline: 2px solid var(--ring);
1778
+ outline-offset: 2px;
1779
+ }
1780
+
1708
1781
  .tag-pill.active {
1709
1782
  background: var(--primary);
1710
1783
  color: var(--primary-foreground);
@@ -2861,19 +2934,25 @@ function renderTagBar(args, deps) {
2861
2934
  const { tags, totalScenarios } = args;
2862
2935
  if (tags.length === 0) return "";
2863
2936
  const pills = tags.map(
2864
- (tag) => `<button type="button" class="tag-pill" data-tag="${deps.escapeHtml(tag)}">${deps.escapeHtml(tag)}</button>`
2865
- ).join("\n ");
2937
+ (tag) => `<button type="button" class="tag-pill" data-tag="${deps.escapeHtml(tag)}" aria-pressed="false">${deps.escapeHtml(tag)}</button>`
2938
+ ).join("\n ");
2866
2939
  return `
2867
- <div class="tag-bar">
2940
+ <div class="tag-bar tag-bar-collapsed">
2868
2941
  <div class="tag-bar-header">
2869
- <span class="tag-bar-label">Filter by tag</span>
2870
- <button type="button" class="tag-bar-clear" style="display:none">Clear</button>
2942
+ <button type="button" class="tag-bar-toggle" aria-expanded="false" aria-controls="tag-pills-region">
2943
+ <span class="tag-bar-label">Filter by tag</span>
2944
+ <span class="tag-bar-count" aria-live="polite"></span>
2945
+ <svg class="tag-bar-chevron" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
2946
+ <path d="M4 6l4 4 4-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
2947
+ </svg>
2948
+ </button>
2949
+ <button type="button" class="tag-bar-clear" aria-label="Clear all tag filters" style="display:none">Clear all</button>
2871
2950
  </div>
2872
- <div class="tag-bar-pills">
2951
+ <div id="tag-pills-region" class="tag-bar-pills" role="group" aria-label="Tag filters">
2873
2952
  ${pills}
2874
2953
  </div>
2875
2954
  </div>
2876
- <div class="filter-results" style="display:none">
2955
+ <div class="filter-results" style="display:none" aria-live="polite">
2877
2956
  Showing <span class="visible-count">0</span> of <span class="total-count">${totalScenarios}</span> scenarios
2878
2957
  </div>`;
2879
2958
  }