@zenithbuild/core 0.4.1 → 0.4.4

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.
@@ -506,6 +506,120 @@ export function generateBundleJS(): string {
506
506
  return new ZenCollection(data);
507
507
  }
508
508
 
509
+ // ============================================
510
+ // useZenOrder - Documentation ordering & navigation
511
+ // ============================================
512
+
513
+ function slugify(text) {
514
+ return String(text || '')
515
+ .toLowerCase()
516
+ .replace(/[^\\w\\s-]/g, '')
517
+ .replace(/\\s+/g, '-')
518
+ .replace(/-+/g, '-')
519
+ .trim();
520
+ }
521
+
522
+ function getDocSlug(doc) {
523
+ const slugOrId = String(doc.slug || doc.id || '');
524
+ const parts = slugOrId.split('/');
525
+ const filename = parts[parts.length - 1];
526
+ return filename ? slugify(filename) : slugify(doc.title || 'untitled');
527
+ }
528
+
529
+ function processRawSections(rawSections) {
530
+ const sections = (rawSections || []).map(function(rawSection) {
531
+ const sectionSlug = slugify(rawSection.title || rawSection.id || 'section');
532
+ const items = (rawSection.items || []).map(function(item) {
533
+ return Object.assign({}, item, {
534
+ slug: getDocSlug(item),
535
+ sectionSlug: sectionSlug,
536
+ isIntro: item.intro === true || (item.tags && item.tags.includes && item.tags.includes('intro'))
537
+ });
538
+ });
539
+
540
+ // Sort items: intro first, then order, then alphabetical
541
+ items.sort(function(a, b) {
542
+ if (a.isIntro && !b.isIntro) return -1;
543
+ if (!a.isIntro && b.isIntro) return 1;
544
+ if (a.order !== undefined && b.order !== undefined) return a.order - b.order;
545
+ if (a.order !== undefined) return -1;
546
+ if (b.order !== undefined) return 1;
547
+ return (a.title || '').localeCompare(b.title || '');
548
+ });
549
+
550
+ return {
551
+ id: rawSection.id || sectionSlug,
552
+ title: rawSection.title || 'Untitled',
553
+ slug: sectionSlug,
554
+ order: rawSection.order !== undefined ? rawSection.order : (rawSection.meta && rawSection.meta.order),
555
+ hasIntro: items.some(function(i) { return i.isIntro; }),
556
+ items: items
557
+ };
558
+ });
559
+
560
+ // Sort sections: order → hasIntro → alphabetical
561
+ sections.sort(function(a, b) {
562
+ if (a.order !== undefined && b.order !== undefined) return a.order - b.order;
563
+ if (a.order !== undefined) return -1;
564
+ if (b.order !== undefined) return 1;
565
+ if (a.hasIntro && !b.hasIntro) return -1;
566
+ if (!a.hasIntro && b.hasIntro) return 1;
567
+ return a.title.localeCompare(b.title);
568
+ });
569
+
570
+ return sections;
571
+ }
572
+
573
+ function createZenOrder(rawSections) {
574
+ const sections = processRawSections(rawSections);
575
+
576
+ return {
577
+ sections: sections,
578
+ selectedSection: sections[0] || null,
579
+ selectedDoc: sections[0] && sections[0].items[0] || null,
580
+
581
+ getSectionBySlug: function(sectionSlug) {
582
+ return sections.find(function(s) { return s.slug === sectionSlug; }) || null;
583
+ },
584
+
585
+ getDocBySlug: function(sectionSlug, docSlug) {
586
+ var section = sections.find(function(s) { return s.slug === sectionSlug; });
587
+ if (!section) return null;
588
+ return section.items.find(function(d) { return d.slug === docSlug; }) || null;
589
+ },
590
+
591
+ getNextDoc: function(currentDoc) {
592
+ if (!currentDoc) return null;
593
+ var currentSection = sections.find(function(s) { return s.slug === currentDoc.sectionSlug; });
594
+ if (!currentSection) return null;
595
+ var idx = currentSection.items.findIndex(function(d) { return d.slug === currentDoc.slug; });
596
+ if (idx < currentSection.items.length - 1) return currentSection.items[idx + 1];
597
+ var secIdx = sections.findIndex(function(s) { return s.slug === currentSection.slug; });
598
+ if (secIdx < sections.length - 1) return sections[secIdx + 1].items[0] || null;
599
+ return null;
600
+ },
601
+
602
+ getPrevDoc: function(currentDoc) {
603
+ if (!currentDoc) return null;
604
+ var currentSection = sections.find(function(s) { return s.slug === currentDoc.sectionSlug; });
605
+ if (!currentSection) return null;
606
+ var idx = currentSection.items.findIndex(function(d) { return d.slug === currentDoc.slug; });
607
+ if (idx > 0) return currentSection.items[idx - 1];
608
+ var secIdx = sections.findIndex(function(s) { return s.slug === currentSection.slug; });
609
+ if (secIdx > 0) {
610
+ var prev = sections[secIdx - 1];
611
+ return prev.items[prev.items.length - 1] || null;
612
+ }
613
+ return null;
614
+ },
615
+
616
+ buildDocUrl: function(sectionSlug, docSlug) {
617
+ if (!docSlug || docSlug === 'index') return '/documentation/' + sectionSlug;
618
+ return '/documentation/' + sectionSlug + '/' + docSlug;
619
+ }
620
+ };
621
+ }
622
+
509
623
  // Virtual DOM Helper for JSX-style expressions
510
624
  function h(tag, props, children) {
511
625
  const el = document.createElement(tag);
@@ -573,6 +687,10 @@ export function generateBundleJS(): string {
573
687
  // zenith:content
574
688
  defineSchema: defineSchema,
575
689
  zenCollection: zenCollection,
690
+ // useZenOrder hook
691
+ createZenOrder: createZenOrder,
692
+ processRawSections: processRawSections,
693
+ slugify: slugify,
576
694
  // Virtual DOM helper for JSX
577
695
  h: h,
578
696
  // Lifecycle
@@ -610,6 +728,11 @@ export function generateBundleJS(): string {
610
728
  global.onMount = zenOnMount;
611
729
  global.onUnmount = zenOnUnmount;
612
730
 
731
+ // useZenOrder hook exports
732
+ global.createZenOrder = createZenOrder;
733
+ global.processRawSections = processRawSections;
734
+ global.slugify = slugify;
735
+
613
736
  // ============================================
614
737
  // HMR Client (Development Only)
615
738
  // ============================================