@commonpub/layer 0.21.15 → 0.21.16

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.
@@ -73,6 +73,20 @@ const authorUrl = computed(() =>
73
73
  : `/u/${props.content.author?.username}`,
74
74
  );
75
75
 
76
+ /**
77
+ * Whether the right sidebar has any content to render. When false we
78
+ * suppress the sidebar `<aside>` AND the grid's 260px column so the
79
+ * content column gets the full width. Without this guard, projects
80
+ * with no BOM/parts AND no community hub get a squished content
81
+ * column with empty whitespace on the right (heatsynclabs.io
82
+ * report, 2026-05-19).
83
+ */
84
+ const hasSidebar = computed(() => {
85
+ const bom = (props.content?.parts?.length ?? 0) > 0 || (bomProducts.value?.length ?? 0) > 0;
86
+ const community = hubsEnabled.value && !!props.content?.community;
87
+ return bom || community;
88
+ });
89
+
76
90
  const formattedDate = computed(() => {
77
91
  const date = props.content?.publishedAt || props.content?.createdAt;
78
92
  if (!date) return '';
@@ -418,7 +432,7 @@ async function handleBuild(): Promise<void> {
418
432
 
419
433
  <!-- MAIN CONTENT GRID -->
420
434
  <div class="cpub-page-outer">
421
- <div class="cpub-content-grid" :class="{ 'cpub-has-toc': tocEntries.length > 0 && activeTab === 'overview' }">
435
+ <div class="cpub-content-grid" :class="{ 'cpub-has-toc': tocEntries.length > 0 && activeTab === 'overview', 'cpub-has-sidebar': hasSidebar }">
422
436
  <!-- LEFT: TABLE OF CONTENTS -->
423
437
  <nav v-if="tocEntries.length > 0 && activeTab === 'overview'" class="cpub-toc-col">
424
438
  <div class="cpub-toc">
@@ -561,8 +575,9 @@ async function handleBuild(): Promise<void> {
561
575
  </template>
562
576
  </div>
563
577
 
564
- <!-- RIGHT: SIDEBAR -->
565
- <aside class="cpub-sidebar">
578
+ <!-- RIGHT: SIDEBAR (rendered only when there's BOM/community content;
579
+ the cpub-has-sidebar grid-class reserves the 260px column to match) -->
580
+ <aside v-if="hasSidebar" class="cpub-sidebar">
566
581
  <!-- BOM Summary -->
567
582
  <div v-if="content.parts?.length || bomProducts?.length" class="cpub-sb-card">
568
583
  <div class="cpub-sb-title">BOM Summary</div>
@@ -940,15 +955,29 @@ async function handleBuild(): Promise<void> {
940
955
  border-bottom-color: var(--border);
941
956
  }
942
957
 
943
- /* ── CONTENT GRID ── */
958
+ /* ── CONTENT GRID ──
959
+ 4 layouts via 2 boolean modifier classes:
960
+ base → content only
961
+ .cpub-has-toc → TOC + content
962
+ .cpub-has-sidebar → content + sidebar
963
+ .cpub-has-toc.cpub-has-sidebar → TOC + content + sidebar
964
+ The sidebar 260px column is reserved ONLY when there's sidebar
965
+ content to put in it (BOM/parts OR community hub) — otherwise the
966
+ content column gets the freed width. */
944
967
  .cpub-content-grid {
945
968
  display: grid;
946
- grid-template-columns: minmax(0, 1fr) 260px;
969
+ grid-template-columns: minmax(0, 1fr);
947
970
  gap: clamp(16px, 3vw, 32px);
948
971
  align-items: start;
949
972
  padding-bottom: 64px;
950
973
  }
951
974
  .cpub-content-grid.cpub-has-toc {
975
+ grid-template-columns: 200px minmax(0, 1fr);
976
+ }
977
+ .cpub-content-grid.cpub-has-sidebar {
978
+ grid-template-columns: minmax(0, 1fr) 260px;
979
+ }
980
+ .cpub-content-grid.cpub-has-toc.cpub-has-sidebar {
952
981
  grid-template-columns: 200px minmax(0, 1fr) 260px;
953
982
  }
954
983
 
@@ -1561,9 +1590,12 @@ async function handleBuild(): Promise<void> {
1561
1590
 
1562
1591
  /* ── RESPONSIVE ── */
1563
1592
 
1564
- /* 1200px: Drop left TOC column, keep sidebar */
1593
+ /* 1200px: Drop left TOC column, keep sidebar if it exists */
1565
1594
  @media (max-width: 1200px) {
1566
1595
  .cpub-content-grid.cpub-has-toc {
1596
+ grid-template-columns: minmax(0, 1fr);
1597
+ }
1598
+ .cpub-content-grid.cpub-has-toc.cpub-has-sidebar {
1567
1599
  grid-template-columns: minmax(0, 1fr) 260px;
1568
1600
  }
1569
1601
  .cpub-toc-col { display: none; }
@@ -1572,7 +1604,9 @@ async function handleBuild(): Promise<void> {
1572
1604
  /* 1024px: Single column — sidebar stacks below content */
1573
1605
  @media (max-width: 1024px) {
1574
1606
  .cpub-content-grid,
1575
- .cpub-content-grid.cpub-has-toc {
1607
+ .cpub-content-grid.cpub-has-toc,
1608
+ .cpub-content-grid.cpub-has-sidebar,
1609
+ .cpub-content-grid.cpub-has-toc.cpub-has-sidebar {
1576
1610
  grid-template-columns: minmax(0, 1fr);
1577
1611
  }
1578
1612
  .cpub-sidebar { position: static; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commonpub/layer",
3
- "version": "0.21.15",
3
+ "version": "0.21.16",
4
4
  "type": "module",
5
5
  "main": "./nuxt.config.ts",
6
6
  "files": [
@@ -51,15 +51,15 @@
51
51
  "vue-router": "^4.3.0",
52
52
  "zod": "^4.3.6",
53
53
  "@commonpub/auth": "0.6.0",
54
- "@commonpub/config": "0.13.0",
55
54
  "@commonpub/docs": "0.6.3",
56
- "@commonpub/server": "2.55.0",
57
- "@commonpub/schema": "0.16.0",
58
55
  "@commonpub/editor": "0.7.10",
56
+ "@commonpub/explainer": "0.7.15",
59
57
  "@commonpub/learning": "0.5.2",
60
58
  "@commonpub/protocol": "0.12.0",
61
- "@commonpub/explainer": "0.7.15",
62
- "@commonpub/ui": "0.8.5"
59
+ "@commonpub/server": "2.55.0",
60
+ "@commonpub/ui": "0.8.5",
61
+ "@commonpub/schema": "0.16.0",
62
+ "@commonpub/config": "0.13.0"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@testing-library/jest-dom": "^6.9.1",