@docmd/ui 0.6.6 → 0.6.7

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.
@@ -2626,4 +2626,174 @@ ul.contains-task-list > li::marker {
2626
2626
 
2627
2627
  .task-list-item-checkbox {
2628
2628
  margin-top: .25em;
2629
- }
2629
+ }
2630
+ /**
2631
+ * Hero Container (2.0)
2632
+ * Handles basic, split, and slider layouts.
2633
+ */
2634
+ .docmd-hero {
2635
+ position: relative;
2636
+ width: 100%;
2637
+ margin: var(--space-12) 0;
2638
+ padding: var(--space-12) 0;
2639
+ display: flex;
2640
+ flex-direction: column;
2641
+ }
2642
+
2643
+ .docmd-hero.hero-glow::before {
2644
+ content: '';
2645
+ position: absolute;
2646
+ top: 50%;
2647
+ left: 50%;
2648
+ transform: translate(-50%, -50%);
2649
+ width: 80%;
2650
+ height: 80%;
2651
+ background: radial-gradient(circle, var(--link-color) 0%, transparent 70%);
2652
+ opacity: 0.08;
2653
+ filter: blur(100px);
2654
+ z-index: -1;
2655
+ pointer-events: none;
2656
+ }
2657
+
2658
+ /* Default / Banner Layout */
2659
+ .docmd-hero.hero-banner {
2660
+ text-align: center;
2661
+ align-items: center;
2662
+ }
2663
+
2664
+ .docmd-hero.hero-banner .hero-content {
2665
+ max-width: 800px;
2666
+ }
2667
+
2668
+ /* Split Layout */
2669
+ .docmd-hero.hero-split {
2670
+ display: flex;
2671
+ flex-direction: row;
2672
+ align-items: center;
2673
+ gap: var(--space-12);
2674
+ text-align: left;
2675
+ }
2676
+
2677
+ .docmd-hero.hero-split .hero-content {
2678
+ flex: 1 1 0;
2679
+ min-width: 0;
2680
+ }
2681
+
2682
+ .docmd-hero.hero-split .hero-side {
2683
+ flex: 1 1 0;
2684
+ min-width: 0;
2685
+ display: flex;
2686
+ justify-content: center;
2687
+ align-items: center;
2688
+ }
2689
+
2690
+ /* Slider Layout */
2691
+ .docmd-hero.hero-slider {
2692
+ overflow: hidden;
2693
+ position: relative;
2694
+ }
2695
+
2696
+ .hero-slider-track {
2697
+ display: flex;
2698
+ scroll-snap-type: x mandatory;
2699
+ overflow-x: auto;
2700
+ scrollbar-width: none;
2701
+ -ms-overflow-style: none;
2702
+ scroll-behavior: smooth;
2703
+ }
2704
+
2705
+ .hero-slider-track::-webkit-scrollbar {
2706
+ display: none;
2707
+ }
2708
+
2709
+ .hero-slide {
2710
+ flex: 0 0 100%;
2711
+ scroll-snap-align: start;
2712
+ padding: var(--space-8) var(--space-4);
2713
+ box-sizing: border-box;
2714
+ text-align: center;
2715
+ }
2716
+
2717
+ .hero-slider-controls {
2718
+ display: flex;
2719
+ justify-content: center;
2720
+ align-items: center;
2721
+ gap: var(--space-3);
2722
+ margin-top: var(--space-6);
2723
+ }
2724
+
2725
+ .hero-slider-btn {
2726
+ background: var(--bg-secondary);
2727
+ border: 1px solid var(--border-color);
2728
+ color: var(--text-primary);
2729
+ width: 36px;
2730
+ height: 36px;
2731
+ border-radius: 50%;
2732
+ cursor: pointer;
2733
+ display: flex;
2734
+ align-items: center;
2735
+ justify-content: center;
2736
+ transition: background 0.2s, border-color 0.2s;
2737
+ flex-shrink: 0;
2738
+ }
2739
+
2740
+ .hero-slider-btn:hover {
2741
+ background: var(--link-color);
2742
+ border-color: var(--link-color);
2743
+ color: #fff;
2744
+ }
2745
+
2746
+ .hero-slider-dots {
2747
+ display: flex;
2748
+ gap: var(--space-2);
2749
+ align-items: center;
2750
+ }
2751
+
2752
+ .hero-slider-dot {
2753
+ width: 8px;
2754
+ height: 8px;
2755
+ border-radius: 50%;
2756
+ background: var(--border-color);
2757
+ cursor: pointer;
2758
+ transition: background 0.2s, transform 0.2s;
2759
+ border: none;
2760
+ padding: 0;
2761
+ }
2762
+
2763
+ .hero-slider-dot.active {
2764
+ background: var(--link-color);
2765
+ transform: scale(1.3);
2766
+ }
2767
+
2768
+ /* Typography & Elements */
2769
+ .hero-content h1 {
2770
+ font-size: clamp(2.5rem, 8vw, 4.5rem);
2771
+ font-weight: 900;
2772
+ line-height: .95;
2773
+ letter-spacing: -0.05em;
2774
+ margin-bottom: var(--space-4);
2775
+ }
2776
+
2777
+ .hero-content p {
2778
+ font-size: clamp(1.1rem, 2.5vw, 1.4rem);
2779
+ color: var(--text-muted);
2780
+ line-height: 1.4;
2781
+ margin-bottom: var(--space-6);
2782
+ }
2783
+
2784
+ .hero-side img, .hero-side video, .hero-side .docmd-embed {
2785
+ width: 100%;
2786
+ border-radius: var(--radius-xl);
2787
+ box-shadow: var(--shadow-lg);
2788
+ }
2789
+
2790
+ @media (max-width: 960px) {
2791
+ .docmd-hero.hero-split {
2792
+ flex-direction: column;
2793
+ text-align: center;
2794
+ gap: var(--space-8);
2795
+ }
2796
+ .hero-content h1 {
2797
+ font-size: 3rem;
2798
+ }
2799
+ }
@@ -132,6 +132,32 @@
132
132
  });
133
133
  }
134
134
  }
135
+ // Hero Slider
136
+ const sliderBtn = e.target.closest('.hero-slider-btn, .hero-slider-dot');
137
+ if (sliderBtn) {
138
+ const hero = sliderBtn.closest('.docmd-hero.hero-slider');
139
+ if (!hero) return;
140
+ const track = hero.querySelector('.hero-slider-track');
141
+ const slides = hero.querySelectorAll('.hero-slide');
142
+ const dots = hero.querySelectorAll('.hero-slider-dot');
143
+ if (!track || !slides.length) return;
144
+
145
+ const slideWidth = slides[0].offsetWidth;
146
+ const currentIndex = Math.round(track.scrollLeft / slideWidth);
147
+ let targetIndex = currentIndex;
148
+
149
+ if (sliderBtn.classList.contains('hero-slider-prev')) {
150
+ targetIndex = (currentIndex - 1 + slides.length) % slides.length;
151
+ } else if (sliderBtn.classList.contains('hero-slider-next')) {
152
+ targetIndex = (currentIndex + 1) % slides.length;
153
+ } else if (sliderBtn.classList.contains('hero-slider-dot')) {
154
+ targetIndex = parseInt(sliderBtn.dataset.slide, 10);
155
+ }
156
+
157
+ track.scrollTo({ left: targetIndex * slideWidth, behavior: 'smooth' });
158
+ dots.forEach((d, i) => d.classList.toggle('active', i === targetIndex));
159
+ }
160
+
135
161
  });
136
162
 
137
163
  // 2. COMPONENT INITIALIZERS
@@ -154,6 +180,22 @@
154
180
  });
155
181
  }
156
182
 
183
+ function initializeHeroSliders() {
184
+ document.querySelectorAll('.docmd-hero.hero-slider').forEach(hero => {
185
+ const track = hero.querySelector('.hero-slider-track');
186
+ const dots = hero.querySelectorAll('.hero-slider-dot');
187
+ if (!track || !dots.length) return;
188
+
189
+ // Sync dots on scroll (handles touch/swipe)
190
+ track.addEventListener('scroll', () => {
191
+ const slides = hero.querySelectorAll('.hero-slide');
192
+ if (!slides.length) return;
193
+ const idx = Math.round(track.scrollLeft / slides[0].offsetWidth);
194
+ dots.forEach((d, i) => d.classList.toggle('active', i === idx));
195
+ }, { passive: true });
196
+ });
197
+ }
198
+
157
199
  let scrollObserver = null;
158
200
  function initializeScrollSpy() {
159
201
  if (scrollObserver) scrollObserver.disconnect();
@@ -342,6 +384,7 @@
342
384
 
343
385
  injectCopyButtons();
344
386
  initializeScrollSpy();
387
+ initializeHeroSliders();
345
388
  const newMainContent = document.querySelector('.main-content');
346
389
  if (newMainContent) executeScripts(newMainContent);
347
390
 
@@ -384,6 +427,7 @@
384
427
 
385
428
  injectCopyButtons();
386
429
  initializeScrollSpy();
430
+ initializeHeroSliders();
387
431
  initializeSPA();
388
432
 
389
433
  setTimeout(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docmd/ui",
3
- "version": "0.6.6",
3
+ "version": "0.6.7",
4
4
  "description": "Base UI templates and assets for docmd.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -92,7 +92,11 @@
92
92
  </head>
93
93
  <body<% if (frontmatter.components?.theme !==false) { %> data-theme="<%= defaultMode %>"<% } %>
94
94
  <% if (frontmatter.bodyClass) { %> class="<%= frontmatter.bodyClass %>"<% } %> data-copy-code-enabled="<%=
95
- config.copyCode===true %>">
95
+ config.copyCode===true %>" data-spa-enabled="<%= frontmatter.components?.spa === true %>">
96
+ <% if (frontmatter.components?.menubar === true && (locals.menubarConfig && menubarConfig?.enabled !== false)) { %>
97
+ <%- await include('partials/menubar', { menubarConfig, relativePathToRoot, renderIcon, optionsMenu: locals.optionsMenu }) %>
98
+ <% } %>
99
+
96
100
  <% if (frontmatter.components?.layout===true || frontmatter.components?.layout==='full' ) { %>
97
101
  <div class="main-content-wrapper">
98
102
  <% if (frontmatter.components?.header !==false) { %>