rizzo-css 0.0.31 → 0.0.33

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.
Files changed (36) hide show
  1. package/README.md +1 -1
  2. package/bin/rizzo-css.js +6 -5
  3. package/package.json +1 -1
  4. package/scaffold/astro/Navbar.astro +12 -5
  5. package/scaffold/astro/Search.astro +57 -5
  6. package/scaffold/svelte/Navbar.svelte +19 -0
  7. package/scaffold/svelte/Search.svelte +80 -8
  8. package/scaffold/svelte/Settings.svelte +31 -4
  9. package/scaffold/vanilla/README-RIZZO.md +1 -1
  10. package/scaffold/vanilla/components/accordion.html +34 -2
  11. package/scaffold/vanilla/components/alert.html +34 -2
  12. package/scaffold/vanilla/components/avatar.html +34 -2
  13. package/scaffold/vanilla/components/badge.html +34 -2
  14. package/scaffold/vanilla/components/breadcrumb.html +34 -2
  15. package/scaffold/vanilla/components/button.html +34 -2
  16. package/scaffold/vanilla/components/cards.html +34 -2
  17. package/scaffold/vanilla/components/copy-to-clipboard.html +34 -2
  18. package/scaffold/vanilla/components/divider.html +34 -2
  19. package/scaffold/vanilla/components/dropdown.html +34 -2
  20. package/scaffold/vanilla/components/forms.html +34 -2
  21. package/scaffold/vanilla/components/icons.html +34 -2
  22. package/scaffold/vanilla/components/index.html +34 -2
  23. package/scaffold/vanilla/components/modal.html +34 -2
  24. package/scaffold/vanilla/components/navbar.html +34 -2
  25. package/scaffold/vanilla/components/pagination.html +34 -2
  26. package/scaffold/vanilla/components/progress-bar.html +34 -2
  27. package/scaffold/vanilla/components/search.html +34 -2
  28. package/scaffold/vanilla/components/settings.html +34 -2
  29. package/scaffold/vanilla/components/spinner.html +34 -2
  30. package/scaffold/vanilla/components/table.html +34 -2
  31. package/scaffold/vanilla/components/tabs.html +34 -2
  32. package/scaffold/vanilla/components/theme-switcher.html +34 -2
  33. package/scaffold/vanilla/components/toast.html +34 -2
  34. package/scaffold/vanilla/components/tooltip.html +34 -2
  35. package/scaffold/vanilla/index.html +34 -2
  36. package/scaffold/vanilla/js/main.js +47 -14
@@ -54,12 +54,32 @@
54
54
  <div class="search" data-search>
55
55
  <div class="search__trigger-wrapper">
56
56
  <button type="button" class="search__trigger" aria-label="Open search" aria-expanded="false" aria-controls="search-header-panel">
57
+ <svg class="search__icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
57
58
  <span class="search__trigger-text">Search</span>
58
59
  </button>
59
60
  </div>
60
61
  <div class="search__overlay" id="search-header-panel" aria-hidden="true" role="dialog" aria-modal="true" data-search-overlay>
61
- <div class="search__panel">
62
- <input type="search" class="search__input" placeholder="Search…" aria-label="Search" />
62
+ <div class="search__panel" role="dialog" aria-modal="true" aria-labelledby="search-header-title" aria-hidden="true" tabindex="-1">
63
+ <h2 id="search-header-title" class="sr-only">Search</h2>
64
+ <div class="search__header">
65
+ <div class="search__input-wrapper">
66
+ <svg class="search__input-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
67
+ <input type="search" class="search__input" placeholder="Search…" aria-label="Search" />
68
+ </div>
69
+ <button type="button" class="search__close-btn" aria-label="Close search" data-search-close>
70
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M18 6L6 18"/><path d="M6 6l12 12"/></svg>
71
+ </button>
72
+ </div>
73
+ <div class="search__results" role="listbox" aria-label="Search results">
74
+ <div class="search__empty">
75
+ <p class="search__empty-text">Start typing to search…</p>
76
+ </div>
77
+ <div class="search__results-list" role="group" aria-label="Sample results">
78
+ <a href="#" class="search__result-item" tabindex="-1"><div class="search__result-category">Docs</div><div class="search__result-title">Getting started</div></a>
79
+ <a href="#" class="search__result-item" tabindex="-1"><div class="search__result-category">Docs</div><div class="search__result-title">Components</div></a>
80
+ <a href="#" class="search__result-item" tabindex="-1"><div class="search__result-category">Docs</div><div class="search__result-title">Theming</div></a>
81
+ </div>
82
+ </div>
63
83
  </div>
64
84
  </div>
65
85
  </div>
@@ -246,6 +266,12 @@
246
266
 
247
267
 
248
268
 
269
+
270
+
271
+
272
+
273
+
274
+
249
275
 
250
276
 
251
277
 
@@ -329,6 +355,12 @@
329
355
 
330
356
 
331
357
 
358
+
359
+
360
+
361
+
362
+
363
+
332
364
 
333
365
 
334
366
 
@@ -54,12 +54,32 @@
54
54
  <div class="search" data-search>
55
55
  <div class="search__trigger-wrapper">
56
56
  <button type="button" class="search__trigger" aria-label="Open search" aria-expanded="false" aria-controls="search-header-panel">
57
+ <svg class="search__icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
57
58
  <span class="search__trigger-text">Search</span>
58
59
  </button>
59
60
  </div>
60
61
  <div class="search__overlay" id="search-header-panel" aria-hidden="true" role="dialog" aria-modal="true" data-search-overlay>
61
- <div class="search__panel">
62
- <input type="search" class="search__input" placeholder="Search…" aria-label="Search" />
62
+ <div class="search__panel" role="dialog" aria-modal="true" aria-labelledby="search-header-title" aria-hidden="true" tabindex="-1">
63
+ <h2 id="search-header-title" class="sr-only">Search</h2>
64
+ <div class="search__header">
65
+ <div class="search__input-wrapper">
66
+ <svg class="search__input-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
67
+ <input type="search" class="search__input" placeholder="Search…" aria-label="Search" />
68
+ </div>
69
+ <button type="button" class="search__close-btn" aria-label="Close search" data-search-close>
70
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M18 6L6 18"/><path d="M6 6l12 12"/></svg>
71
+ </button>
72
+ </div>
73
+ <div class="search__results" role="listbox" aria-label="Search results">
74
+ <div class="search__empty">
75
+ <p class="search__empty-text">Start typing to search…</p>
76
+ </div>
77
+ <div class="search__results-list" role="group" aria-label="Sample results">
78
+ <a href="#" class="search__result-item" tabindex="-1"><div class="search__result-category">Docs</div><div class="search__result-title">Getting started</div></a>
79
+ <a href="#" class="search__result-item" tabindex="-1"><div class="search__result-category">Docs</div><div class="search__result-title">Components</div></a>
80
+ <a href="#" class="search__result-item" tabindex="-1"><div class="search__result-category">Docs</div><div class="search__result-title">Theming</div></a>
81
+ </div>
82
+ </div>
63
83
  </div>
64
84
  </div>
65
85
  </div>
@@ -246,6 +266,12 @@
246
266
 
247
267
 
248
268
 
269
+
270
+
271
+
272
+
273
+
274
+
249
275
 
250
276
 
251
277
 
@@ -329,6 +355,12 @@
329
355
 
330
356
 
331
357
 
358
+
359
+
360
+
361
+
362
+
363
+
332
364
 
333
365
 
334
366
 
@@ -54,12 +54,32 @@
54
54
  <div class="search" data-search>
55
55
  <div class="search__trigger-wrapper">
56
56
  <button type="button" class="search__trigger" aria-label="Open search" aria-expanded="false" aria-controls="search-header-panel">
57
+ <svg class="search__icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
57
58
  <span class="search__trigger-text">Search</span>
58
59
  </button>
59
60
  </div>
60
61
  <div class="search__overlay" id="search-header-panel" aria-hidden="true" role="dialog" aria-modal="true" data-search-overlay>
61
- <div class="search__panel">
62
- <input type="search" class="search__input" placeholder="Search…" aria-label="Search" />
62
+ <div class="search__panel" role="dialog" aria-modal="true" aria-labelledby="search-header-title" aria-hidden="true" tabindex="-1">
63
+ <h2 id="search-header-title" class="sr-only">Search</h2>
64
+ <div class="search__header">
65
+ <div class="search__input-wrapper">
66
+ <svg class="search__input-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
67
+ <input type="search" class="search__input" placeholder="Search…" aria-label="Search" />
68
+ </div>
69
+ <button type="button" class="search__close-btn" aria-label="Close search" data-search-close>
70
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M18 6L6 18"/><path d="M6 6l12 12"/></svg>
71
+ </button>
72
+ </div>
73
+ <div class="search__results" role="listbox" aria-label="Search results">
74
+ <div class="search__empty">
75
+ <p class="search__empty-text">Start typing to search…</p>
76
+ </div>
77
+ <div class="search__results-list" role="group" aria-label="Sample results">
78
+ <a href="#" class="search__result-item" tabindex="-1"><div class="search__result-category">Docs</div><div class="search__result-title">Getting started</div></a>
79
+ <a href="#" class="search__result-item" tabindex="-1"><div class="search__result-category">Docs</div><div class="search__result-title">Components</div></a>
80
+ <a href="#" class="search__result-item" tabindex="-1"><div class="search__result-category">Docs</div><div class="search__result-title">Theming</div></a>
81
+ </div>
82
+ </div>
63
83
  </div>
64
84
  </div>
65
85
  </div>
@@ -246,6 +266,12 @@
246
266
 
247
267
 
248
268
 
269
+
270
+
271
+
272
+
273
+
274
+
249
275
 
250
276
 
251
277
 
@@ -341,6 +367,12 @@
341
367
 
342
368
 
343
369
 
370
+
371
+
372
+
373
+
374
+
375
+
344
376
 
345
377
 
346
378
 
@@ -807,8 +807,12 @@
807
807
  document.querySelectorAll('[data-accordion]').forEach(initOne);
808
808
  }
809
809
 
810
- // --- Search: [data-search] — trigger opens overlay, overlay click or Escape closes
810
+ // --- Search: [data-search] — trigger opens overlay, panel has header (input + close), focus trap, overlay/close/Escape close
811
811
  function initSearch() {
812
+ var focusableSel = 'button:not([disabled]),a[href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
813
+ function getFocusable(container) {
814
+ return Array.prototype.slice.call(container.querySelectorAll(focusableSel));
815
+ }
812
816
  document.querySelectorAll('[data-search]').forEach(function (search) {
813
817
  if (search.getAttribute('data-search-inited') === 'true') return;
814
818
  search.setAttribute('data-search-inited', 'true');
@@ -816,23 +820,50 @@
816
820
  var overlay = search.querySelector('[data-search-overlay]');
817
821
  var panel = search.querySelector('.search__panel');
818
822
  var input = search.querySelector('.search__input');
823
+ var closeBtn = search.querySelector('[data-search-close]');
824
+ var resultItems = search.querySelectorAll('.search__result-item');
819
825
  if (!trigger || !overlay || !panel || !input) return;
820
826
  var previousActive = null;
827
+ var focusTrapHandler = null;
821
828
  function openSearch() {
822
829
  previousActive = document.activeElement;
823
830
  overlay.setAttribute('aria-hidden', 'false');
831
+ panel.setAttribute('aria-hidden', 'false');
832
+ panel.setAttribute('data-open', 'true');
824
833
  trigger.setAttribute('aria-expanded', 'true');
834
+ for (var i = 0; i < resultItems.length; i++) resultItems[i].setAttribute('tabindex', '0');
825
835
  input.focus();
836
+ focusTrapHandler = function (e) {
837
+ if (panel.getAttribute('data-open') !== 'true') return;
838
+ if (e.key === 'Escape') { e.preventDefault(); closeSearch(); return; }
839
+ if (e.key === 'Tab') {
840
+ var els = getFocusable(panel);
841
+ if (els.length === 0) return;
842
+ var first = els[0], last = els[els.length - 1], active = document.activeElement;
843
+ if (e.shiftKey) {
844
+ if (active === first || !panel.contains(active)) { e.preventDefault(); last.focus(); }
845
+ } else {
846
+ if (active === last || !panel.contains(active)) { e.preventDefault(); first.focus(); }
847
+ }
848
+ }
849
+ };
850
+ document.addEventListener('keydown', focusTrapHandler);
826
851
  }
827
852
  function closeSearch() {
853
+ document.removeEventListener('keydown', focusTrapHandler);
854
+ focusTrapHandler = null;
855
+ panel.removeAttribute('data-open');
856
+ panel.setAttribute('aria-hidden', 'true');
828
857
  overlay.setAttribute('aria-hidden', 'true');
829
858
  trigger.setAttribute('aria-expanded', 'false');
859
+ for (var i = 0; i < resultItems.length; i++) resultItems[i].setAttribute('tabindex', '-1');
830
860
  if (previousActive && typeof previousActive.focus === 'function') previousActive.focus();
831
861
  previousActive = null;
832
862
  }
833
863
  trigger.addEventListener('click', function () {
834
- if (overlay.getAttribute('aria-hidden') === 'true') openSearch(); else closeSearch();
864
+ if (panel.getAttribute('data-open') === 'true') closeSearch(); else openSearch();
835
865
  });
866
+ if (closeBtn) closeBtn.addEventListener('click', closeSearch);
836
867
  overlay.addEventListener('click', function (e) {
837
868
  if (e.target === overlay) closeSearch();
838
869
  });
@@ -847,11 +878,22 @@
847
878
  var toggle = navbar.querySelector('.navbar__toggle');
848
879
  var menu = navbar.querySelector('.navbar__menu');
849
880
  if (!toggle || !menu) return;
881
+ var outsideClickHandler = null;
850
882
  function setMenuOpen(open) {
851
883
  menu.classList.toggle('navbar__menu--open', open);
852
884
  navbar.classList.toggle('navbar--menu-open', open);
853
885
  toggle.setAttribute('aria-expanded', open ? 'true' : 'false');
854
886
  menu.setAttribute('aria-hidden', open ? 'false' : 'true');
887
+ if (outsideClickHandler) {
888
+ document.removeEventListener('click', outsideClickHandler);
889
+ outsideClickHandler = null;
890
+ }
891
+ if (open) {
892
+ outsideClickHandler = function (e) {
893
+ if (e.target && !navbar.contains(e.target)) setMenuOpen(false);
894
+ };
895
+ setTimeout(function () { document.addEventListener('click', outsideClickHandler); }, 0);
896
+ }
855
897
  }
856
898
  toggle.addEventListener('click', function () {
857
899
  setMenuOpen(!menu.classList.contains('navbar__menu--open'));
@@ -859,18 +901,9 @@
859
901
  menu.querySelectorAll('.navbar__link').forEach(function (link) {
860
902
  link.addEventListener('click', function () { setMenuOpen(false); });
861
903
  });
862
- });
863
- document.addEventListener('keydown', function (e) {
864
- if (e.key === 'Escape') {
865
- document.querySelectorAll('.navbar__menu.navbar__menu--open').forEach(function (menu) {
866
- var navbar = menu.closest('.navbar');
867
- var toggle = navbar && navbar.querySelector('.navbar__toggle');
868
- menu.classList.remove('navbar__menu--open');
869
- navbar.classList.remove('navbar--menu-open');
870
- if (toggle) toggle.setAttribute('aria-expanded', 'false');
871
- menu.setAttribute('aria-hidden', 'true');
872
- });
873
- }
904
+ document.addEventListener('keydown', function (e) {
905
+ if (e.key === 'Escape' && menu.classList.contains('navbar__menu--open')) setMenuOpen(false);
906
+ });
874
907
  });
875
908
  }
876
909