lowkey-doc 1.1.2 → 1.1.3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lowkey-doc",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "Render a folder of Markdown into one self-contained documentation dashboard, with flowcharts and ER diagrams that stay readable when they get dense.",
5
5
  "repository": {
6
6
  "type": "git",
package/src/build.mjs CHANGED
@@ -81,8 +81,8 @@ export function collectDocs(cfg, memo = null) {
81
81
  return { docs, changed, memo: { layout, files } };
82
82
  }
83
83
 
84
- // ELK travels even when the default engine is mermaid: the reader can switch
85
- // any single diagram over from the page, and that has to work offline too.
84
+ // ELK travels even when the default engine is mermaid, so a config edit under
85
+ // --watch can turn the clean layout on without fetching anything.
86
86
  export async function vendorAssets(cfg, refresh = false) {
87
87
  fs.mkdirSync(cfg.outDir, { recursive: true });
88
88
  // The default output folder keeps itself out of git, so no project has to
@@ -469,7 +469,7 @@ export const APP_JS = String.raw`
469
469
  // left alone here.
470
470
  var fig = e.target.closest('.diagram');
471
471
  if (fig && !e.target.closest('svg.dg') && !e.target.closest('.diagram-head')){
472
- var svg = fig.querySelector('svg');
472
+ var svg = fig.querySelector('.diagram-out > svg');
473
473
  if (svg) openBox(svg);
474
474
  return;
475
475
  }
@@ -1189,13 +1189,12 @@ export const APP_JS = String.raw`
1189
1189
 
1190
1190
  // Edited diagrams, when they line up one for one with the ones they
1191
1191
  // replace: the old drawing stays up, faded, until the new one is ready -
1192
- // no collapse and regrow under the reader - and a layout switched, or an
1193
- // entity opened, from the page stays that way.
1192
+ // no collapse and regrow under the reader - and an entity opened from the
1193
+ // page stays open.
1194
1194
  var stale = olds.filter(function(f){ return !used.has(f); });
1195
1195
  if (stale.length !== fresh.length) return;
1196
1196
  fresh.forEach(function(f, i){
1197
1197
  var o = stale[i];
1198
- if (o.dataset.engine) f.dataset.engine = o.dataset.engine;
1199
1198
  if (o._open) f._open = o._open;
1200
1199
  var out = f.querySelector('.diagram-out'), prev = o.querySelector('.diagram-out');
1201
1200
  if (!out || !prev || !prev.firstChild) return;
@@ -614,18 +614,24 @@ export const CSS_DIAGRAM = `
614
614
  .diagram-name{flex:1;min-width:0;display:flex;align-items:baseline;gap:9px;overflow:hidden;white-space:nowrap}
615
615
  .diagram-kind{flex:none;font-size:10px;font-weight:var(--bold);letter-spacing:.09em;text-transform:uppercase;color:var(--faint)}
616
616
  .diagram-title{min-width:0;overflow:hidden;text-overflow:ellipsis;font-size:12.5px;font-weight:var(--semi);color:var(--ink)}
617
- .diagram-bar{flex:none;display:flex;gap:5px}
618
- .diagram-btn{padding:3px 11px;font:inherit;font-size:11px;color:var(--muted);
619
- background:transparent;border:1px solid var(--line-2);border-radius:999px;cursor:pointer;
620
- transition:color .12s,border-color .12s}
621
- .diagram-btn:hover{color:var(--ink);border-color:rgba(255,255,255,.32)}
622
- .diagram-btn:empty{display:none}
623
- .diagram:has(svg):hover{border-color:var(--line-2)}
617
+ .diagram-head{cursor:pointer;transition:background .12s}
618
+ .diagram-head:hover{background:var(--surface-2)}
619
+ .diagram-bar{flex:none;display:flex;gap:2px}
620
+ .diagram-btn{width:26px;height:26px;padding:0;display:grid;place-items:center;
621
+ background:none;border:1px solid transparent;border-radius:999px;color:var(--faint);cursor:pointer;
622
+ transition:background .15s,color .15s,border-color .15s}
623
+ .diagram-btn svg{width:14px;height:14px}
624
+ .diagram-btn[data-act=fold] svg{transition:transform .18s ease}
625
+ .diagram-head:hover .diagram-btn[data-act=fold],.diagram-btn:hover{color:var(--ink)}
626
+ .diagram-btn:hover{background:var(--hover);border-color:var(--line)}
627
+ .diagram:has(.diagram-out > svg):hover{border-color:var(--line-2)}
624
628
  .diagram .fail{font-family:var(--mono);font-size:12px;color:var(--muted);text-align:left;white-space:pre-wrap}
625
629
  .diagram-note{margin-top:10px;font-size:11px;color:var(--faint);text-align:center}
626
630
  /* A collapsed diagram is its header and nothing else: a plain white box the
627
- height of a line, which a click opens again. */
631
+ height of a line, which a click opens again. Its chevron turns to point at
632
+ the header, as a closed dropdown's does. */
628
633
  .diagram.is-folded{padding-bottom:0;overflow:hidden;cursor:pointer}
634
+ .diagram.is-folded .diagram-btn[data-act=fold] svg{transform:rotate(-90deg)}
629
635
  .diagram.is-folded .diagram-head{margin-bottom:0;border-bottom-color:transparent}
630
636
  .diagram.is-folded:hover{border-color:var(--line-2)}
631
637
  .diagram.is-folded .diagram-out,.diagram.is-folded .diagram-note,
@@ -2180,19 +2180,11 @@ export const DIAGRAMS_JS = String.raw`
2180
2180
  });
2181
2181
  }
2182
2182
 
2183
- // The button is for comparing one diagram, not for changing the project's
2184
- // mind: a switch lasts as long as the page is open and no longer. The
2185
- // project-wide default is a config setting, where it can be reviewed.
2186
- function engineFor(fig, code){
2183
+ // The engine is the project's choice, made in the config: the page does not
2184
+ // offer the reader another one.
2185
+ function engineFor(code){
2187
2186
  if (!cleanKind(code)) return 'mermaid';
2188
- return fig.dataset.engine || CFG.engine || 'clean';
2189
- }
2190
-
2191
- function paintButton(fig, code, used){
2192
- var btn = fig.querySelector('[data-act="engine"]');
2193
- if (!btn) return;
2194
- btn.textContent = (cleanKind(code) && canClean(cleanKind(code)))
2195
- ? (used === 'clean' ? 'Mermaid layout' : 'Clean layout') : '';
2187
+ return CFG.engine || 'clean';
2196
2188
  }
2197
2189
 
2198
2190
  /* ------------------------------------------------------------- folding
@@ -2224,8 +2216,9 @@ export const DIAGRAMS_JS = String.raw`
2224
2216
  fig.classList.toggle('is-folded', on);
2225
2217
  var btn = fig.querySelector('[data-act="fold"]');
2226
2218
  if (btn){
2227
- btn.textContent = on ? 'Show' : 'Collapse';
2228
- btn.title = on ? 'Show the diagram' : 'Fold the diagram away';
2219
+ btn.title = on ? 'Show' : 'Collapse';
2220
+ btn.setAttribute('aria-label', btn.title);
2221
+ btn.setAttribute('aria-expanded', on ? 'false' : 'true');
2229
2222
  }
2230
2223
  }
2231
2224
 
@@ -2233,7 +2226,7 @@ export const DIAGRAMS_JS = String.raw`
2233
2226
  var code = fig.querySelector('.diagram-src').textContent;
2234
2227
  if (!fig._foldSeen){ fig._foldSeen = true; paintFold(fig, folded(fig)); }
2235
2228
  if (fig.classList.contains('is-folded')) return Promise.resolve();
2236
- var want = force || engineFor(fig, code);
2229
+ var want = force || engineFor(code);
2237
2230
  if (fig.dataset.drawn === want) return Promise.resolve();
2238
2231
  fig.dataset.drawn = want;
2239
2232
  var kind = cleanKind(code);
@@ -2251,7 +2244,7 @@ export const DIAGRAMS_JS = String.raw`
2251
2244
  if (note) note.remove();
2252
2245
  done = renderMermaid(fig, code);
2253
2246
  }
2254
- return done.then(function(){ paintButton(fig, code, fig.dataset.drawn); });
2247
+ return done;
2255
2248
  }
2256
2249
 
2257
2250
  function drawAll(scope){
@@ -2545,6 +2538,14 @@ export const DIAGRAMS_JS = String.raw`
2545
2538
  var shut = e.target.closest && e.target.closest('.diagram.is-folded');
2546
2539
  // anywhere on a collapsed diagram opens it
2547
2540
  if (shut && (!btn || btn.dataset.act === 'fold')){ e.stopPropagation(); setFold(shut, false); return; }
2541
+ // the header bar folds the diagram as its chevron does - unless the click
2542
+ // was really the end of a drag that selected some of the title
2543
+ var head = !btn && e.target.closest && e.target.closest('.diagram-head');
2544
+ if (head){
2545
+ var s = window.getSelection();
2546
+ if (s && !s.isCollapsed && String(s).trim()) return;
2547
+ btn = head.querySelector('[data-act="fold"]');
2548
+ }
2548
2549
  if (!btn) return;
2549
2550
  var fig = btn.closest('.diagram');
2550
2551
  if (!fig) return;
@@ -2555,14 +2556,8 @@ export const DIAGRAMS_JS = String.raw`
2555
2556
  setFold(fig, true);
2556
2557
  return;
2557
2558
  }
2558
- if (btn.dataset.act === 'engine'){
2559
- var next = fig.dataset.drawn === 'clean' ? 'mermaid' : 'clean';
2560
- fig.dataset.engine = next;
2561
- draw(fig, next);
2562
- return;
2563
- }
2564
2559
  if (btn.dataset.act === 'zoom'){
2565
- var svg = fig.querySelector('svg');
2560
+ var svg = fig.querySelector('.diagram-out > svg');
2566
2561
  if (svg && window.__lightbox) window.__lightbox(svg);
2567
2562
  }
2568
2563
  }, true);
package/src/markdown.mjs CHANGED
@@ -25,6 +25,11 @@ const DIAGRAM_KINDS = {
25
25
  gantt: 'Gantt chart', pie: 'Pie chart', journey: 'User journey', mindmap: 'Mind map',
26
26
  timeline: 'Timeline', gitgraph: 'Git graph', quadrantchart: 'Quadrant chart',
27
27
  };
28
+ const SVG_OPEN = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" ' +
29
+ 'stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">';
30
+ const FULL_SVG = SVG_OPEN + '<path d="M3 6.5V3h3.5M9.5 3H13v3.5M13 9.5V13H9.5M6.5 13H3V9.5"/></svg>';
31
+ const FOLD_SVG = SVG_OPEN + '<path d="M3.5 6L8 10.5 12.5 6"/></svg>';
32
+
28
33
  function diagramName(code) {
29
34
  let title = '';
30
35
  const body = String(code).replace(/^\s*---\r?\n([\s\S]*?)\r?\n---[ \t]*(\r?\n|$)/, (_, fm) => {
@@ -521,9 +526,8 @@ export function parkFences(md, ctx) {
521
526
  ? '<figure class="diagram" data-diagram><pre class="diagram-src">' + esc(code) + '</pre>' +
522
527
  '<div class="diagram-head">' + diagramName(code) +
523
528
  '<div class="diagram-bar">' +
524
- '<button class="diagram-btn" data-act="fold" type="button" title="Fold the diagram away">Collapse</button>' +
525
- '<button class="diagram-btn" data-act="zoom" type="button" title="Open full size">Expand</button>' +
526
- '<button class="diagram-btn" data-act="engine" type="button" title="Switch layout engine"></button>' +
529
+ '<button class="diagram-btn" data-act="zoom" type="button" title="Open full size" aria-label="Open full size">' + FULL_SVG + '</button>' +
530
+ '<button class="diagram-btn" data-act="fold" type="button" title="Collapse" aria-label="Collapse" aria-expanded="true">' + FOLD_SVG + '</button>' +
527
531
  '</div>' +
528
532
  '</div>' +
529
533
  '<div class="diagram-out"></div></figure>'