Skip to main content

max / goingson

3.1 KB · 68 lines History Blame Raw
1 #!/bin/bash
2 # Frontend design-system lint guards.
3 # See docs/design-system.md "Inline-style rules" and docs/ux-audit/remediation-plan.md Step 10.
4 # Exit 0 = clean. Exit non-zero = violations found (printed with file:line).
5
6 set -u
7 ROOT="$(cd "$(dirname "$0")/.." && pwd)"
8 FRONTEND="$ROOT/src-tauri/frontend"
9 SRC_JS="$FRONTEND/js"
10 SRC_HTML="$FRONTEND/index.html $FRONTEND/compose.html"
11 SRC_CSS="$FRONTEND/css/styles.css"
12
13 violations=0
14
15 report() {
16 local rule="$1"; shift
17 local msg="$1"; shift
18 if [ -n "$*" ]; then
19 echo
20 echo "[$rule] $msg"
21 echo "$*"
22 violations=$((violations + 1))
23 fi
24 }
25
26 # 1. No raw hex literals in JS or source HTML (HTML entities &#NNNN; are OK;
27 # <meta name="theme-color"> is a documented exception — value is set
28 # programmatically by js/themes.js to track the active theme).
29 hits=$(grep -rnE '#[0-9a-fA-F]{3,8}\b' "$SRC_JS" $SRC_HTML 2>/dev/null \
30 | grep -vE '&#[0-9]+;' \
31 | grep -vE 'meta name="theme-color"' \
32 || true)
33 report "no-raw-hex" "Raw hex literal in JS/HTML — use a CSS class or token instead." "$hits"
34
35 # 2. No style.cssText anywhere in JS.
36 hits=$(grep -rn 'cssText' "$SRC_JS" 2>/dev/null || true)
37 report "no-csstext" "style.cssText injection — move styles into a CSS class." "$hits"
38
39 # 3. No var(--token, #fallback). Fallback hex defeats theme switching.
40 hits=$(grep -rnE 'var\(--[a-z-]+,\s*#' "$FRONTEND" --include='*.js' --include='*.html' --include='styles.css' 2>/dev/null | grep -v styles.min.css || true)
41 report "no-var-fallback-hex" "var(--token, #fallback) — drop the fallback; it bypasses themes." "$hits"
42
43 # 4. No window.confirm / bare confirm() — route through GoingsOn.ui.showConfirmDialog.
44 hits=$(grep -rnE '\b(window\.)?confirm\(' "$SRC_JS" 2>/dev/null | grep -vE 'showConfirmDialog|confirmDelete|//\s*\*|\*\s' || true)
45 report "no-window-confirm" "window.confirm() — use GoingsOn.ui.showConfirmDialog instead." "$hits"
46
47 # 5. No inline style= that touches color / background / border / shadow / font / padding values.
48 hits=$(grep -rnE 'style="[^"]*(color|background|border|shadow|font-size|font-family|padding)' "$SRC_JS" $SRC_HTML 2>/dev/null || true)
49 report "no-styled-attrs" "Inline style= with color/background/border/shadow/font/padding — use a class." "$hits"
50
51 # 6. Deprecated empty-state classes have been removed.
52 hits=$(grep -rnE 'empty-dashboard-list|kanban-empty|virtual-scroller-empty' "$FRONTEND" --include='*.js' --include='*.html' --include='styles.css' 2>/dev/null | grep -v styles.min.css || true)
53 report "no-deprecated-empty-states" "Deprecated class — use .empty-state with --compact / --dashboard / --error." "$hits"
54
55 # 7. No native browser dialogs. Charter rule from Phase 7 roll-up.
56 hits=$(grep -rnE '\b(window\.)?(confirm|prompt|alert)\(' "$SRC_JS" 2>/dev/null \
57 | grep -vE 'showConfirmDialog|showPromptDialog|confirmDelete|//\s|\*\s' || true)
58 report "no-native-dialogs" "window.confirm/prompt/alert are banned — use GoingsOn.ui.show{Confirm,Prompt}Dialog or showToast." "$hits"
59
60 if [ $violations -eq 0 ]; then
61 echo "frontend lint: clean"
62 exit 0
63 else
64 echo
65 echo "frontend lint: $violations rule(s) failed"
66 exit 1
67 fi
68