@schandlergarcia/sf-web-components 1.9.48 → 1.9.50

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/CHANGELOG.md CHANGED
@@ -5,6 +5,85 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.9.50] - 2026-04-01
9
+
10
+ ### Added
11
+ - **scripts/postinstall.mjs** - Now copies engine-sample-data.js to src/data/ on installation
12
+ - Issue: Phase 2 of Engine PRD required manually creating sample data file
13
+ - Solution: Automatically install pre-built sample data during package setup
14
+ - Sample data includes all Salesforce-shaped records and dashboard-ready derivatives
15
+ - File location: `src/data/engine-sample-data.js` (31KB of ready-to-use data)
16
+ - Eliminates manual data creation step from Phase 2 build process
17
+
18
+ - **scripts/reset-command-center.sh** - Now restores engine-sample-data.js during reset
19
+ - Issue: Reset could leave app with modified or missing sample data
20
+ - Solution: Added step 10 that copies fresh engine-sample-data.js from package
21
+ - Handles both installed package and source package locations
22
+ - Ensures consistent data state across resets
23
+
24
+ ### Changed
25
+ - **engine-command-center-prd.md** - Updated Phase 2 prompt to use pre-installed data
26
+ - Before: "Create `src/data/engine-sample-data.js` with travelers, flights..."
27
+ - After: "Build components using the pre-installed sample data at `src/data/engine-sample-data.js`"
28
+ - Simplified Phase 2: just import and use, no data creation needed
29
+
30
+ - **Postinstall summary** - Now reports data files installed
31
+ - Added line: "Installed X sample data files"
32
+
33
+ - **Reset success message** - Now highlights sample data restoration
34
+ - Added: "Engine sample data (engine-sample-data.js)"
35
+
36
+ ### Rationale
37
+ The engine-sample-data.js file (31KB) contains complete, dashboard-ready data for all Engine Travel Command Center components:
38
+ - Raw Salesforce records (Contact, Trip__c, Flight__c, Booking__c, Disruption__c, etc.)
39
+ - Pre-computed dashboard derivatives (MAP_MARKERS, MAP_ARCS, TRAVELER_CARDS, etc.)
40
+ - All field names match the org schema for easy live-data swap in Phase 3
41
+
42
+ Installing this automatically:
43
+ - Eliminates a 30+ minute manual data-creation step from Phase 2
44
+ - Ensures all developers use the same sample data
45
+ - Makes the Phase 2 prompt simpler and faster
46
+ - Consistent with how we handle other templates (Home.tsx, routes.tsx, etc.)
47
+
48
+ Restoring on reset:
49
+ - Prevents issues where modified sample data breaks demo builds
50
+ - Keeps data in sync with global.css, templates, and structure
51
+ - Allows developers to experiment with data changes and easily revert
52
+
53
+ ---
54
+
55
+ ## [1.9.49] - 2026-04-01
56
+
57
+ ### Added
58
+ - **scripts/reset-command-center.sh** - Now restores Engine-branded global.css during reset
59
+ - Issue: Reset didn't touch global.css, leaving inconsistent styling state
60
+ - Solution: Added step 9 that writes complete Engine-branded global.css template
61
+ - Includes all Engine brand tokens:
62
+ - `--color-engine-*` tokens (teal, coral, green, savings, etc.)
63
+ - `--color-brand-*` palette (12 teal shades from 50-950)
64
+ - Inter font stack (`--font-sans`)
65
+ - JetBrains Mono (`--font-mono`)
66
+ - Engine border radius tokens (`--radius-pill`, `--radius-card`)
67
+ - Complete `.heroui-scope` theme overrides with Engine colors
68
+ - Ensures consistent Engine branding across all reset operations
69
+ - Template sourced from enginewebexperience production configuration
70
+
71
+ ### Changed
72
+ - **Reset success message** - Updated to highlight Engine branding restoration
73
+ - Before: "Everything preserved: Theme (global.css + initialMode)"
74
+ - After: "Restored: Engine brand theme (global.css)" with brand details
75
+ - Clarifies that reset actively restores Engine branding, not just preserves it
76
+
77
+ ### Rationale
78
+ The reset script is tooling specifically for Engine Travel Command Center development. Making it restore Engine branding by default is consistent with:
79
+ - The script's existing opinionated behavior (specific templates for Home, Search, routes)
80
+ - The engine-command-center-prd.md PRD section 3 which specifies Engine brand tokens
81
+ - The fact that the script lives in sf-web-components package used for Engine dashboards
82
+
83
+ This eliminates a common source of confusion where developers would reset the app structure but be left with mismatched or baseline styling.
84
+
85
+ ---
86
+
8
87
  ## Critical History: Component Naming Crisis (v1.9.29 - v1.9.42)
9
88
 
10
89
  ### The Problem
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schandlergarcia/sf-web-components",
3
- "version": "1.9.48",
3
+ "version": "1.9.50",
4
4
  "description": "Reusable Salesforce web components library with Tailwind CSS v4 and shadcn/ui",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -227,6 +227,35 @@ if (fs.existsSync(templatesDir)) {
227
227
  }
228
228
  }
229
229
 
230
+ // Copy sample data files
231
+ const dataSourceDir = path.join(packageRoot, 'data');
232
+ const targetDataDir = path.join(cwd, 'src/data');
233
+
234
+ console.log('\nšŸ“Š Installing sample data files...\n');
235
+
236
+ let dataFilesInstalled = 0;
237
+
238
+ if (fs.existsSync(dataSourceDir)) {
239
+ // Create target data directory if it doesn't exist
240
+ if (!fs.existsSync(targetDataDir)) {
241
+ fs.mkdirSync(targetDataDir, { recursive: true });
242
+ }
243
+
244
+ // Copy engine-sample-data.js
245
+ const engineDataSource = path.join(dataSourceDir, 'engine-sample-data.js');
246
+ const engineDataTarget = path.join(targetDataDir, 'engine-sample-data.js');
247
+
248
+ if (fs.existsSync(engineDataSource)) {
249
+ try {
250
+ fs.copyFileSync(engineDataSource, engineDataTarget);
251
+ console.log(' āœ“ Installed engine-sample-data.js');
252
+ dataFilesInstalled++;
253
+ } catch (error) {
254
+ console.error(` āœ— Failed to install engine-sample-data.js: ${error.message}`);
255
+ }
256
+ }
257
+ }
258
+
230
259
  // Copy routes.tsx template with full configuration
231
260
  const routesTemplatePath = path.join(packageRoot, 'src/templates/config/routes.tsx.template');
232
261
  const routesPath = path.join(cwd, 'src/routes.tsx');
@@ -359,6 +388,7 @@ console.log('\nšŸ“Š Summary:');
359
388
  console.log(` - Copied ${componentsCopied} UI components`);
360
389
  console.log(` - Updated ${filesUpdated} files`);
361
390
  console.log(` - Installed ${templatesInstalled} page templates`);
391
+ console.log(` - Installed ${dataFilesInstalled} sample data files`);
362
392
  console.log(` - Installed CommandCenter.tsx for dashboard management`);
363
393
  console.log(` - Added "npm run reset:command-center" script`);
364
394
  console.log(` - Installed AI assistant rules for command center building`);
@@ -402,17 +402,294 @@ echo "→ Cleaning caches…"
402
402
  rm -rf node_modules/.vite 2>/dev/null && echo " āœ“ Cleared Vite cache" || true
403
403
  echo ""
404
404
 
405
+ # ── 9. Restore Engine-branded global.css ────────────────────────────────────
406
+
407
+ # Ensure src/styles directory exists
408
+ mkdir -p src/styles
409
+
410
+ GLOBAL_CSS="src/styles/global.css"
411
+ echo "→ Restoring Engine-branded ${GLOBAL_CSS}..."
412
+
413
+ cat > "$GLOBAL_CSS" << 'GLOBAL_CSS_EOF'
414
+ @import '@heroui/styles';
415
+
416
+ @layer base {
417
+ html,
418
+ body,
419
+ #root {
420
+ @apply min-h-screen;
421
+ }
422
+
423
+ body {
424
+ @apply antialiased bg-white;
425
+ }
426
+ }
427
+
428
+ @import 'tw-animate-css';
429
+ @import 'shadcn/tailwind.css';
430
+
431
+ @custom-variant dark (&:is(.dark *));
432
+
433
+ @source "../components/library";
434
+ @source "../components/pages";
435
+
436
+ @theme inline {
437
+ --color-background: var(--background);
438
+ --color-foreground: var(--foreground);
439
+ --color-card: var(--card);
440
+ --color-card-foreground: var(--card-foreground);
441
+ --color-popover: var(--popover);
442
+ --color-popover-foreground: var(--popover-foreground);
443
+ --color-primary: var(--primary);
444
+ --color-primary-foreground: var(--primary-foreground);
445
+ --color-secondary: var(--secondary);
446
+ --color-secondary-foreground: var(--secondary-foreground);
447
+ --color-muted: var(--muted);
448
+ --color-muted-foreground: var(--muted-foreground);
449
+ --color-accent: var(--accent);
450
+ --color-accent-foreground: var(--accent-foreground);
451
+ --color-destructive: var(--destructive);
452
+ --color-destructive-foreground: var(--destructive-foreground);
453
+ --color-border: var(--border);
454
+ --color-input: var(--input);
455
+ --color-ring: var(--ring);
456
+ --color-chart-1: var(--chart-1);
457
+ --color-chart-2: var(--chart-2);
458
+ --color-chart-3: var(--chart-3);
459
+ --color-chart-4: var(--chart-4);
460
+ --color-chart-5: var(--chart-5);
461
+ --radius-sm: calc(var(--radius) - 4px);
462
+ --radius-md: calc(var(--radius) - 2px);
463
+ --radius-lg: var(--radius);
464
+ --radius-xl: calc(var(--radius) + 4px);
465
+ --color-sidebar: var(--sidebar);
466
+ --color-sidebar-foreground: var(--sidebar-foreground);
467
+ --color-sidebar-primary: var(--sidebar-primary);
468
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
469
+ --color-sidebar-accent: var(--sidebar-accent);
470
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
471
+ --color-sidebar-border: var(--sidebar-border);
472
+ --color-sidebar-ring: var(--sidebar-ring);
473
+
474
+ /* Engine brand palette */
475
+ --color-engine-black: #111111;
476
+ --color-engine-teal: #5BC8C8;
477
+ --color-engine-green: #3DAB5F;
478
+ --color-engine-coral: #FF5722;
479
+ --color-engine-orange: #F59E0B;
480
+ --color-engine-savings: #16A34A;
481
+ --color-engine-bg: #F7F8FA;
482
+ --color-engine-border: #E5E7EB;
483
+ --color-engine-text: #111111;
484
+ --color-engine-muted: #6B7280;
485
+ --color-engine-label: #9CA3AF;
486
+
487
+ /* Engine teal brand palette */
488
+ --color-brand-50: #ECFDF9;
489
+ --color-brand-100: #D1FAF0;
490
+ --color-brand-200: #A7F3E1;
491
+ --color-brand-300: #6EE7C8;
492
+ --color-brand-400: #34D3AB;
493
+ --color-brand-500: #5BC8C8;
494
+ --color-brand-600: #0D9488;
495
+ --color-brand-700: #0F766E;
496
+ --color-brand-800: #115E59;
497
+ --color-brand-900: #134E4A;
498
+ --color-brand-950: #042F2E;
499
+
500
+ --font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
501
+ --font-mono: 'JetBrains Mono', ui-monospace, monospace;
502
+
503
+ /* Engine border radius tokens */
504
+ --radius-pill: 9999px;
505
+ --radius-card: 10px;
506
+ }
507
+
508
+ :root {
509
+ --radius: 0.625rem;
510
+ --background: oklch(1 0 0);
511
+ --foreground: oklch(0.145 0 0);
512
+ --card: oklch(1 0 0);
513
+ --card-foreground: oklch(0.145 0 0);
514
+ --popover: oklch(1 0 0);
515
+ --popover-foreground: oklch(0.145 0 0);
516
+ --primary: oklch(0.205 0 0);
517
+ --primary-foreground: oklch(0.985 0 0);
518
+ --secondary: oklch(0.97 0 0);
519
+ --secondary-foreground: oklch(0.205 0 0);
520
+ --muted: oklch(0.97 0 0);
521
+ --muted-foreground: oklch(0.556 0 0);
522
+ --accent: oklch(0.97 0 0);
523
+ --accent-foreground: oklch(0.205 0 0);
524
+ --destructive: oklch(0.577 0.245 27.325);
525
+ --border: oklch(0.922 0 0);
526
+ --input: oklch(0.922 0 0);
527
+ --ring: oklch(0.708 0 0);
528
+ --chart-1: oklch(0.646 0.222 41.116);
529
+ --chart-2: oklch(0.6 0.118 184.704);
530
+ --chart-3: oklch(0.398 0.07 227.392);
531
+ --chart-4: oklch(0.828 0.189 84.429);
532
+ --chart-5: oklch(0.769 0.188 70.08);
533
+ --sidebar: oklch(0.985 0 0);
534
+ --sidebar-foreground: oklch(0.145 0 0);
535
+ --sidebar-primary: oklch(0.205 0 0);
536
+ --sidebar-primary-foreground: oklch(0.985 0 0);
537
+ --sidebar-accent: oklch(0.97 0 0);
538
+ --sidebar-accent-foreground: oklch(0.205 0 0);
539
+ --sidebar-border: oklch(0.922 0 0);
540
+ --sidebar-ring: oklch(0.708 0 0);
541
+ }
542
+
543
+ .dark {
544
+ --background: oklch(0.145 0 0);
545
+ --foreground: oklch(0.985 0 0);
546
+ --card: oklch(0.205 0 0);
547
+ --card-foreground: oklch(0.985 0 0);
548
+ --popover: oklch(0.205 0 0);
549
+ --popover-foreground: oklch(0.985 0 0);
550
+ --primary: oklch(0.922 0 0);
551
+ --primary-foreground: oklch(0.205 0 0);
552
+ --secondary: oklch(0.269 0 0);
553
+ --secondary-foreground: oklch(0.985 0 0);
554
+ --muted: oklch(0.269 0 0);
555
+ --muted-foreground: oklch(0.708 0 0);
556
+ --accent: oklch(0.269 0 0);
557
+ --accent-foreground: oklch(0.985 0 0);
558
+ --destructive: oklch(0.704 0.191 22.216);
559
+ --border: oklch(1 0 0 / 10%);
560
+ --input: oklch(1 0 0 / 15%);
561
+ --ring: oklch(0.556 0 0);
562
+ --chart-1: oklch(0.488 0.243 264.376);
563
+ --chart-2: oklch(0.696 0.17 162.48);
564
+ --chart-3: oklch(0.769 0.188 70.08);
565
+ --chart-4: oklch(0.627 0.265 303.9);
566
+ --chart-5: oklch(0.645 0.246 16.439);
567
+ --sidebar: oklch(0.205 0 0);
568
+ --sidebar-foreground: oklch(0.985 0 0);
569
+ --sidebar-primary: oklch(0.488 0.243 264.376);
570
+ --sidebar-primary-foreground: oklch(0.985 0 0);
571
+ --sidebar-accent: oklch(0.269 0 0);
572
+ --sidebar-accent-foreground: oklch(0.985 0 0);
573
+ --sidebar-border: oklch(1 0 0 / 10%);
574
+ --sidebar-ring: oklch(0.556 0 0);
575
+ }
576
+
577
+ @layer base {
578
+ * {
579
+ @apply border-border outline-ring/50;
580
+ }
581
+ body {
582
+ @apply bg-background text-foreground;
583
+ }
584
+ }
585
+
586
+ /*
587
+ * Restore HeroUI theme variables inside the Command Center scope.
588
+ * shadcn redefines --muted, --accent, --accent-foreground with different
589
+ * semantics (bg colors vs text colors). This scope restores HeroUI's values
590
+ * so HeroUI components render correctly.
591
+ */
592
+ .heroui-scope {
593
+ /* Engine HeroUI theme overrides */
594
+ --primary: #000000;
595
+ --primary-foreground: oklch(0.9911 0 0);
596
+ --secondary: #5BC8C8;
597
+ --secondary-foreground: oklch(0.2103 0.0059 285.89);
598
+ --success: #16A34A;
599
+ --success-foreground: oklch(0.9911 0 0);
600
+ --warning: #F59E0B;
601
+ --warning-foreground: oklch(0.2103 0.0059 285.89);
602
+ --danger: #FF5722;
603
+ --danger-foreground: oklch(0.9911 0 0);
604
+
605
+ --muted: oklch(0.5517 0.0138 285.94);
606
+ --accent: oklch(0.6204 0.195 253.83);
607
+ --accent-foreground: oklch(0.9911 0 0);
608
+ --background: oklch(0.9702 0 0);
609
+ --foreground: oklch(0.2103 0.0059 285.89);
610
+ --default: oklch(94% 0.001 286.375);
611
+ --default-foreground: oklch(0.2103 0.0059 285.89);
612
+ --border: oklch(90% 0.004 286.32);
613
+ --separator: oklch(92% 0.004 286.32);
614
+ --segment: oklch(100% 0 0);
615
+ --segment-foreground: oklch(0.2103 0.0059 285.89);
616
+ --surface: oklch(100% 0 0);
617
+ --surface-foreground: oklch(0.2103 0.0059 285.89);
618
+ --overlay: oklch(100% 0 0);
619
+ --overlay-foreground: oklch(0.2103 0.0059 285.89);
620
+ --focus: oklch(0.6204 0.195 253.83);
621
+ --link: oklch(0.2103 0.0059 285.89);
622
+ }
623
+
624
+ .dark .heroui-scope,
625
+ .heroui-scope.dark {
626
+ --muted: oklch(70.5% 0.015 286.067);
627
+ --background: oklch(12% 0.005 285.823);
628
+ --foreground: oklch(0.9911 0 0);
629
+ --default: oklch(27.4% 0.006 286.033);
630
+ --default-foreground: oklch(0.9911 0 0);
631
+ --border: oklch(28% 0.006 286.033);
632
+ --separator: oklch(25% 0.006 286.033);
633
+ --segment: oklch(0.3964 0.01 285.93);
634
+ --segment-foreground: oklch(0.9911 0 0);
635
+ --surface: oklch(0.2103 0.0059 285.89);
636
+ --surface-foreground: oklch(0.9911 0 0);
637
+ --overlay: oklch(0.2103 0.0059 285.89);
638
+ --overlay-foreground: oklch(0.9911 0 0);
639
+ --warning: oklch(0.8203 0.1388 76.34);
640
+ --warning-foreground: oklch(0.2103 0.0059 285.89);
641
+ --danger: oklch(0.594 0.1967 24.63);
642
+ --danger-foreground: oklch(0.9911 0 0);
643
+ --focus: oklch(0.6204 0.195 253.83);
644
+ --link: oklch(0.9911 0 0);
645
+ }
646
+ GLOBAL_CSS_EOF
647
+
648
+ echo " āœ“ Engine branding restored"
649
+ echo ""
650
+
651
+ # ── 10. Restore Engine sample data ──────────────────────────────────────────
652
+
653
+ # Ensure src/data directory exists
654
+ mkdir -p src/data
655
+
656
+ ENGINE_DATA="src/data/engine-sample-data.js"
657
+ echo "→ Restoring ${ENGINE_DATA}..."
658
+
659
+ # Detect package location
660
+ if [ -d "node_modules/@schandlergarcia/sf-web-components/data" ]; then
661
+ PACKAGE_DATA="node_modules/@schandlergarcia/sf-web-components/data/engine-sample-data.js"
662
+ elif [ -f "$SCRIPT_DIR/../data/engine-sample-data.js" ]; then
663
+ # Running from package source
664
+ PACKAGE_DATA="$SCRIPT_DIR/../data/engine-sample-data.js"
665
+ else
666
+ echo " ⚠ Could not find engine-sample-data.js in package"
667
+ PACKAGE_DATA=""
668
+ fi
669
+
670
+ if [ -n "$PACKAGE_DATA" ] && [ -f "$PACKAGE_DATA" ]; then
671
+ cp "$PACKAGE_DATA" "$ENGINE_DATA"
672
+ echo " āœ“ Engine sample data restored"
673
+ else
674
+ echo " ⚠ Skipped (package data not found)"
675
+ fi
676
+
677
+ echo ""
678
+
405
679
  # ── Done ─────────────────────────────────────────────────────────────────────
406
680
 
407
681
  echo "╔════════════════════════════════════════════════╗"
408
682
  echo "ā•‘ āœ“ Reset complete! ā•‘"
409
683
  echo "ā•‘ ā•‘"
410
- echo "ā•‘ Everything preserved: ā•‘"
411
- echo "ā•‘ • Theme (global.css + initialMode) ā•‘"
684
+ echo "ā•‘ Restored: ā•‘"
685
+ echo "ā•‘ • Engine brand theme (global.css) ā•‘"
686
+ echo "ā•‘ - Teal brand palette (#5BC8C8) ā•‘"
687
+ echo "ā•‘ - Inter font stack ā•‘"
688
+ echo "ā•‘ - HeroUI Engine theme overrides ā•‘"
689
+ echo "ā•‘ • Engine sample data (engine-sample-data.js)ā•‘"
412
690
  echo "ā•‘ • Component library (cards, charts, etc.) ā•‘"
413
691
  echo "ā•‘ • HeroUI wrappers & theme providers ā•‘"
414
692
  echo "ā•‘ • Salesforce SDK stubs for local dev ā•‘"
415
- echo "ā•‘ • All styles & dependencies ā•‘"
416
693
  echo "ā•‘ ā•‘"
417
694
  echo "ā•‘ Layout: ā•‘"
418
695
  echo "ā•‘ / → Home (search page) ā•‘"