rizzo-css 0.0.29 → 0.0.31

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 (34) hide show
  1. package/README.md +1 -1
  2. package/bin/rizzo-css.js +6 -6
  3. package/package.json +1 -1
  4. package/scaffold/astro/Navbar.astro +38 -2
  5. package/scaffold/astro/Search.astro +42 -0
  6. package/scaffold/svelte/Navbar.svelte +9 -0
  7. package/scaffold/vanilla/README-RIZZO.md +7 -3
  8. package/scaffold/vanilla/components/accordion.html +28 -0
  9. package/scaffold/vanilla/components/alert.html +28 -0
  10. package/scaffold/vanilla/components/avatar.html +28 -0
  11. package/scaffold/vanilla/components/badge.html +28 -0
  12. package/scaffold/vanilla/components/breadcrumb.html +28 -0
  13. package/scaffold/vanilla/components/button.html +28 -0
  14. package/scaffold/vanilla/components/cards.html +28 -0
  15. package/scaffold/vanilla/components/copy-to-clipboard.html +28 -0
  16. package/scaffold/vanilla/components/divider.html +28 -0
  17. package/scaffold/vanilla/components/dropdown.html +28 -0
  18. package/scaffold/vanilla/components/forms.html +28 -0
  19. package/scaffold/vanilla/components/icons.html +28 -0
  20. package/scaffold/vanilla/components/index.html +28 -0
  21. package/scaffold/vanilla/components/modal.html +28 -0
  22. package/scaffold/vanilla/components/navbar.html +28 -0
  23. package/scaffold/vanilla/components/pagination.html +28 -0
  24. package/scaffold/vanilla/components/progress-bar.html +28 -0
  25. package/scaffold/vanilla/components/search.html +28 -0
  26. package/scaffold/vanilla/components/settings.html +28 -0
  27. package/scaffold/vanilla/components/spinner.html +28 -0
  28. package/scaffold/vanilla/components/table.html +28 -0
  29. package/scaffold/vanilla/components/tabs.html +28 -0
  30. package/scaffold/vanilla/components/theme-switcher.html +28 -0
  31. package/scaffold/vanilla/components/toast.html +28 -0
  32. package/scaffold/vanilla/components/tooltip.html +28 -0
  33. package/scaffold/vanilla/index.html +28 -0
  34. package/scaffold/vanilla/js/main.js +114 -1
@@ -51,6 +51,18 @@
51
51
  <header class="container flex flex-wrap items-center justify-between gap-4" style="padding-top: var(--spacing-4); padding-bottom: var(--spacing-4); border-bottom: 1px solid var(--border);">
52
52
  <a href="#" class="font-semibold" style="font-size: var(--font-size-lg); color: var(--text); text-decoration: none;">{{TITLE}}</a>
53
53
  <div class="flex items-center gap-3 flex-wrap">
54
+ <div class="search" data-search>
55
+ <div class="search__trigger-wrapper">
56
+ <button type="button" class="search__trigger" aria-label="Open search" aria-expanded="false" aria-controls="search-header-panel">
57
+ <span class="search__trigger-text">Search</span>
58
+ </button>
59
+ </div>
60
+ <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" />
63
+ </div>
64
+ </div>
65
+ </div>
54
66
  <label for="theme-select" class="sr-only">Theme</label>
55
67
  <select id="theme-select" class="form-control" style="width: auto; min-width: 12rem;" aria-label="Theme">
56
68
  <option value="system">System</option>
@@ -224,6 +236,14 @@
224
236
 
225
237
 
226
238
 
239
+
240
+
241
+
242
+
243
+
244
+
245
+
246
+
227
247
 
228
248
 
229
249
 
@@ -299,6 +319,14 @@
299
319
 
300
320
 
301
321
 
322
+
323
+
324
+
325
+
326
+
327
+
328
+
329
+
302
330
 
303
331
 
304
332
 
@@ -51,6 +51,18 @@
51
51
  <header class="container flex flex-wrap items-center justify-between gap-4" style="padding-top: var(--spacing-4); padding-bottom: var(--spacing-4); border-bottom: 1px solid var(--border);">
52
52
  <a href="#" class="font-semibold" style="font-size: var(--font-size-lg); color: var(--text); text-decoration: none;">{{TITLE}}</a>
53
53
  <div class="flex items-center gap-3 flex-wrap">
54
+ <div class="search" data-search>
55
+ <div class="search__trigger-wrapper">
56
+ <button type="button" class="search__trigger" aria-label="Open search" aria-expanded="false" aria-controls="search-header-panel">
57
+ <span class="search__trigger-text">Search</span>
58
+ </button>
59
+ </div>
60
+ <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" />
63
+ </div>
64
+ </div>
65
+ </div>
54
66
  <label for="theme-select" class="sr-only">Theme</label>
55
67
  <select id="theme-select" class="form-control" style="width: auto; min-width: 12rem;" aria-label="Theme">
56
68
  <option value="system">System</option>
@@ -224,6 +236,14 @@
224
236
 
225
237
 
226
238
 
239
+
240
+
241
+
242
+
243
+
244
+
245
+
246
+
227
247
 
228
248
 
229
249
 
@@ -299,6 +319,14 @@
299
319
 
300
320
 
301
321
 
322
+
323
+
324
+
325
+
326
+
327
+
328
+
329
+
302
330
 
303
331
 
304
332
 
@@ -51,6 +51,18 @@
51
51
  <header class="container flex flex-wrap items-center justify-between gap-4" style="padding-top: var(--spacing-4); padding-bottom: var(--spacing-4); border-bottom: 1px solid var(--border);">
52
52
  <a href="#" class="font-semibold" style="font-size: var(--font-size-lg); color: var(--text); text-decoration: none;">{{TITLE}}</a>
53
53
  <div class="flex items-center gap-3 flex-wrap">
54
+ <div class="search" data-search>
55
+ <div class="search__trigger-wrapper">
56
+ <button type="button" class="search__trigger" aria-label="Open search" aria-expanded="false" aria-controls="search-header-panel">
57
+ <span class="search__trigger-text">Search</span>
58
+ </button>
59
+ </div>
60
+ <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" />
63
+ </div>
64
+ </div>
65
+ </div>
54
66
  <label for="theme-select" class="sr-only">Theme</label>
55
67
  <select id="theme-select" class="form-control" style="width: auto; min-width: 12rem;" aria-label="Theme">
56
68
  <option value="system">System</option>
@@ -224,6 +236,14 @@
224
236
 
225
237
 
226
238
 
239
+
240
+
241
+
242
+
243
+
244
+
245
+
246
+
227
247
 
228
248
 
229
249
 
@@ -299,6 +319,14 @@
299
319
 
300
320
 
301
321
 
322
+
323
+
324
+
325
+
326
+
327
+
328
+
329
+
302
330
 
303
331
 
304
332
 
@@ -51,6 +51,18 @@
51
51
  <header class="container flex flex-wrap items-center justify-between gap-4" style="padding-top: var(--spacing-4); padding-bottom: var(--spacing-4); border-bottom: 1px solid var(--border);">
52
52
  <a href="#" class="font-semibold" style="font-size: var(--font-size-lg); color: var(--text); text-decoration: none;">{{TITLE}}</a>
53
53
  <div class="flex items-center gap-3 flex-wrap">
54
+ <div class="search" data-search>
55
+ <div class="search__trigger-wrapper">
56
+ <button type="button" class="search__trigger" aria-label="Open search" aria-expanded="false" aria-controls="search-header-panel">
57
+ <span class="search__trigger-text">Search</span>
58
+ </button>
59
+ </div>
60
+ <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" />
63
+ </div>
64
+ </div>
65
+ </div>
54
66
  <label for="theme-select" class="sr-only">Theme</label>
55
67
  <select id="theme-select" class="form-control" style="width: auto; min-width: 12rem;" aria-label="Theme">
56
68
  <option value="system">System</option>
@@ -224,6 +236,14 @@
224
236
 
225
237
 
226
238
 
239
+
240
+
241
+
242
+
243
+
244
+
245
+
246
+
227
247
 
228
248
 
229
249
 
@@ -311,6 +331,14 @@
311
331
 
312
332
 
313
333
 
334
+
335
+
336
+
337
+
338
+
339
+
340
+
341
+
314
342
 
315
343
 
316
344
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Rizzo CSS — Vanilla JS component bundle
3
- * Theme, toast, settings, tabs, modal, dropdown, accordion.
3
+ * Theme, toast, settings, tabs, modal, dropdown, accordion, search, navbar (mobile), copy-to-clipboard.
4
4
  * Load this script after the DOM (e.g. before </body>).
5
5
  */
6
6
  (function () {
@@ -284,6 +284,82 @@
284
284
  window.openSettings = openSettings;
285
285
  }
286
286
 
287
+ // --- Copy to clipboard: .copy-to-clipboard [data-copy-value] or [data-copy] with value ---
288
+ function initCopyToClipboard() {
289
+ function setupButton(btn) {
290
+ if (btn.getAttribute('data-copy-inited') === 'true') return;
291
+ btn.setAttribute('data-copy-inited', 'true');
292
+ var host = btn.closest('.tooltip-host');
293
+ var defaultTooltip = (host && host.getAttribute('data-tooltip')) || 'Copy to clipboard';
294
+ if (host) host.setAttribute('data-copy-default-tooltip', defaultTooltip);
295
+ var defaultAria = btn.getAttribute('aria-label') || 'Copy to clipboard';
296
+ var getValue = function () { return btn.getAttribute('data-copy-value') || btn.getAttribute('value') || ''; };
297
+ var getFormat = function () { return btn.getAttribute('data-copy-format') || ''; };
298
+ var copyIcon = btn.querySelector('.copy-to-clipboard__icon--copy');
299
+ var checkIcon = btn.querySelector('.copy-to-clipboard__icon--check');
300
+ var feedback = btn.querySelector('.copy-to-clipboard__feedback');
301
+ var textSpan = btn.querySelector('.copy-to-clipboard__text');
302
+ function doCopy() {
303
+ var value = getValue();
304
+ if (!value && textSpan) value = textSpan.textContent || '';
305
+ if (!value) return;
306
+ function showSuccess() {
307
+ if (copyIcon) copyIcon.classList.add('copy-to-clipboard__icon--hidden');
308
+ if (checkIcon) checkIcon.classList.remove('copy-to-clipboard__icon--hidden');
309
+ if (feedback) feedback.textContent = getFormat() ? 'Copied ' + getFormat() + '!' : 'Copied!';
310
+ if (host) host.setAttribute('data-tooltip', getFormat() ? 'Copied ' + getFormat() + '!' : 'Copied!');
311
+ btn.setAttribute('aria-label', getFormat() ? 'Copied ' + getFormat() + '!' : 'Copied!');
312
+ var labelEl = btn.querySelector('.copy-trigger__text');
313
+ var previousLabel = labelEl ? labelEl.textContent : '';
314
+ if (labelEl) labelEl.textContent = 'Copied!';
315
+ setTimeout(function () {
316
+ if (copyIcon) copyIcon.classList.remove('copy-to-clipboard__icon--hidden');
317
+ if (checkIcon) checkIcon.classList.add('copy-to-clipboard__icon--hidden');
318
+ if (feedback) feedback.textContent = '';
319
+ if (host) host.setAttribute('data-tooltip', host.getAttribute('data-copy-default-tooltip') || defaultTooltip);
320
+ btn.setAttribute('aria-label', defaultAria);
321
+ if (labelEl) labelEl.textContent = previousLabel || 'Copy';
322
+ }, 2000);
323
+ }
324
+ if (typeof navigator.clipboard !== 'undefined' && navigator.clipboard.writeText) {
325
+ navigator.clipboard.writeText(value).then(showSuccess).catch(function () {
326
+ try {
327
+ var ta = document.createElement('textarea');
328
+ ta.value = value;
329
+ ta.style.position = 'fixed';
330
+ ta.style.left = '-9999px';
331
+ document.body.appendChild(ta);
332
+ ta.focus();
333
+ ta.select();
334
+ document.execCommand('copy');
335
+ document.body.removeChild(ta);
336
+ showSuccess();
337
+ } catch (e) {
338
+ if (window.showToast) window.showToast('Failed to copy', { variant: 'warning' });
339
+ }
340
+ });
341
+ } else {
342
+ try {
343
+ var ta = document.createElement('textarea');
344
+ ta.value = value;
345
+ ta.style.position = 'fixed';
346
+ ta.style.left = '-9999px';
347
+ document.body.appendChild(ta);
348
+ ta.focus();
349
+ ta.select();
350
+ document.execCommand('copy');
351
+ document.body.removeChild(ta);
352
+ showSuccess();
353
+ } catch (e) {
354
+ if (window.showToast) window.showToast('Failed to copy', { variant: 'warning' });
355
+ }
356
+ }
357
+ }
358
+ btn.addEventListener('click', doCopy);
359
+ }
360
+ document.querySelectorAll('.copy-to-clipboard[data-copy-value], .copy-to-clipboard[data-copy], [data-copy]').forEach(setupButton);
361
+ }
362
+
287
363
  // --- Tabs: init all [data-tabs] ---
288
364
  function initTabs() {
289
365
  document.querySelectorAll('[data-tabs]').forEach(function (tabsContainer) {
@@ -731,6 +807,41 @@
731
807
  document.querySelectorAll('[data-accordion]').forEach(initOne);
732
808
  }
733
809
 
810
+ // --- Search: [data-search] — trigger opens overlay, overlay click or Escape closes
811
+ function initSearch() {
812
+ document.querySelectorAll('[data-search]').forEach(function (search) {
813
+ if (search.getAttribute('data-search-inited') === 'true') return;
814
+ search.setAttribute('data-search-inited', 'true');
815
+ var trigger = search.querySelector('.search__trigger');
816
+ var overlay = search.querySelector('[data-search-overlay]');
817
+ var panel = search.querySelector('.search__panel');
818
+ var input = search.querySelector('.search__input');
819
+ if (!trigger || !overlay || !panel || !input) return;
820
+ var previousActive = null;
821
+ function openSearch() {
822
+ previousActive = document.activeElement;
823
+ overlay.setAttribute('aria-hidden', 'false');
824
+ trigger.setAttribute('aria-expanded', 'true');
825
+ input.focus();
826
+ }
827
+ function closeSearch() {
828
+ overlay.setAttribute('aria-hidden', 'true');
829
+ trigger.setAttribute('aria-expanded', 'false');
830
+ if (previousActive && typeof previousActive.focus === 'function') previousActive.focus();
831
+ previousActive = null;
832
+ }
833
+ trigger.addEventListener('click', function () {
834
+ if (overlay.getAttribute('aria-hidden') === 'true') openSearch(); else closeSearch();
835
+ });
836
+ overlay.addEventListener('click', function (e) {
837
+ if (e.target === overlay) closeSearch();
838
+ });
839
+ input.addEventListener('keydown', function (e) {
840
+ if (e.key === 'Escape') { e.preventDefault(); closeSearch(); }
841
+ });
842
+ });
843
+ }
844
+
734
845
  function initNavbarMobile() {
735
846
  document.querySelectorAll('.navbar').forEach(function (navbar) {
736
847
  var toggle = navbar.querySelector('.navbar__toggle');
@@ -766,10 +877,12 @@
766
877
  function run() {
767
878
  initTheme();
768
879
  initSettings();
880
+ initCopyToClipboard();
769
881
  initTabs();
770
882
  initModals();
771
883
  initDropdowns();
772
884
  initAccordions();
885
+ initSearch();
773
886
  initNavbarMobile();
774
887
  }
775
888