@fasl-work/caos-app-shell 0.9.0 → 0.9.1

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/gate/inpage.mjs CHANGED
@@ -531,20 +531,27 @@ export function installLib() {
531
531
  // ---- 0.8.0 measures ----------------------------------------------------------------------------------------
532
532
 
533
533
  /** The part of the page the ancestors of an element let it show when they CUT their content (overflow hidden or
534
- * clip). A scroll container does not cut (a reader scrolls it), and neither does the viewport. */
534
+ * clip). A scroll container does not cut (a reader scrolls it), and neither does the viewport; and what lies beyond
535
+ * the first scroll container on an axis is a matter of scroll position, so the walk stops there on that axis (0.9.1:
536
+ * the contained `.app-shell`, viewport-high with its overflow hidden, read every documentation figure below the fold
537
+ * as "outside the drawing"). */
535
538
  const cutArea = (el) => {
536
539
  const area = { left: -Infinity, top: -Infinity, right: Infinity, bottom: Infinity };
537
- for (let a = el.parentElement; a && a !== document.body && a !== document.documentElement; a = a.parentElement) {
540
+ let x = true;
541
+ let y = true;
542
+ for (let a = el.parentElement; a && a !== document.body && a !== document.documentElement && (x || y); a = a.parentElement) {
538
543
  const s = getComputedStyle(a);
539
544
  const ar = a.getBoundingClientRect();
540
- if (s.overflowX === 'hidden' || s.overflowX === 'clip') {
545
+ if (x && (s.overflowX === 'hidden' || s.overflowX === 'clip')) {
541
546
  area.left = Math.max(area.left, ar.left);
542
547
  area.right = Math.min(area.right, ar.right);
543
548
  }
544
- if (s.overflowY === 'hidden' || s.overflowY === 'clip') {
549
+ if (y && (s.overflowY === 'hidden' || s.overflowY === 'clip')) {
545
550
  area.top = Math.max(area.top, ar.top);
546
551
  area.bottom = Math.min(area.bottom, ar.bottom);
547
552
  }
553
+ if (s.overflowX === 'auto' || s.overflowX === 'scroll') x = false;
554
+ if (s.overflowY === 'auto' || s.overflowY === 'scroll') y = false;
548
555
  }
549
556
  return area;
550
557
  };
@@ -719,6 +726,29 @@ export function installLib() {
719
726
  for (let i = layers.length - 1; i >= 0; i -= 1) base = over(layers[i], base);
720
727
  return base;
721
728
  };
729
+ /** The colour an SVG text element is painted on: the last filled shape painted before it whose box holds its centre. */
730
+ const svgBackdrop = (text, page) => {
731
+ const svg = text.closest('svg');
732
+ if (!svg) return page;
733
+ const r = text.getBoundingClientRect();
734
+ const cx = r.left + r.width / 2;
735
+ const cy = r.top + r.height / 2;
736
+ let found = null;
737
+ for (const shape of svg.querySelectorAll('rect, circle, ellipse, polygon, path')) {
738
+ if (!(shape.compareDocumentPosition(text) & Node.DOCUMENT_POSITION_FOLLOWING)) continue;
739
+ const ss = getComputedStyle(shape);
740
+ if (ss.display === 'none' || ss.visibility === 'hidden') continue;
741
+ const fill = parseColor(ss.fill);
742
+ if (!fill || fill.a === 0) continue;
743
+ const b = shape.getBoundingClientRect();
744
+ if (cx < b.left || cx > b.right || cy < b.top || cy > b.bottom) continue;
745
+ const a = fill.a * Number(ss.fillOpacity || 1) * opacityOf(shape);
746
+ if (a <= 0.05) continue;
747
+ found = { ...fill, a };
748
+ }
749
+ return found ? over(found, page) : page;
750
+ };
751
+
722
752
  const opacityOf = (el) => {
723
753
  let o = 1;
724
754
  for (let a = el; a; a = a.parentElement) o *= Number(getComputedStyle(a).opacity || 1);
@@ -753,8 +783,12 @@ export function installLib() {
753
783
  const fg = parseColor(isSvg ? s.fill : s.color);
754
784
  if (!fg) continue;
755
785
  const host = isSvg ? el.closest('svg')?.parentElement ?? el : el;
756
- const bg = backdrop(host);
757
- if (!bg) continue;
786
+ const page = backdrop(host);
787
+ if (!page) continue;
788
+ // SVG text sits on what the drawing painted under it (a label on a bar): the last filled shape before it whose
789
+ // box holds the text's centre, composited over the page (0.9.1: a marker in the page colour on a red bar read
790
+ // 1.06:1 against the page)
791
+ const bg = isSvg ? svgBackdrop(el, page) : page;
758
792
  const alpha = fg.a * opacityOf(el);
759
793
  const shownColor = over({ ...fg, a: alpha }, bg);
760
794
  const l1 = lum(shownColor);
@@ -763,7 +797,7 @@ export function installLib() {
763
797
  const px = parseFloat(s.fontSize) || 16;
764
798
  const bold = Number(s.fontWeight) >= 700;
765
799
  const need = px >= 24 || (bold && px >= 18.66) ? 3 : 4.5;
766
- if (ratio + 1e-6 < need) out.push(`${describe(el)}: contrast ${ratio.toFixed(2)}:1, below ${need}:1 (${s.color || s.fill} on rgb(${Math.round(bg.r)}, ${Math.round(bg.g)}, ${Math.round(bg.b)}))`);
800
+ if (ratio + 1e-6 < need) out.push(`${describe(el)}: contrast ${ratio.toFixed(2)}:1, below ${need}:1 (${isSvg ? s.fill : s.color} on rgb(${Math.round(bg.r)}, ${Math.round(bg.g)}, ${Math.round(bg.b)}))`);
767
801
  }
768
802
  return out.slice(0, 10);
769
803
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fasl-work/caos-app-shell",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "Shared web-app shell, workbench primitives, content primitives, design system and measured gate for the CAOS / Faena public apps (ADR-0016, ADR-0017, ADR-0071).",
5
5
  "license": "MIT",
6
6
  "author": "Felipe Santibáñez-Leal",
package/styles.css CHANGED
@@ -56,8 +56,8 @@
56
56
  --color-accent-fg: #ffffff;
57
57
  --color-accent-soft: #ddf4ff;
58
58
  --color-accent-2: #0a7886;
59
- --color-magenta: #bf3989;
60
- --color-good: #1a7f37;
59
+ --color-magenta: #b93785;
60
+ --color-good: #197c36;
61
61
  --color-warn: #946300;
62
62
  --color-bad: #cf222e;
63
63
  --color-shadow: 0 1px 2px rgba(31, 35, 40, 0.06), 0 4px 10px rgba(31, 35, 40, 0.04);