@schandlergarcia/sf-web-components 2.3.16 → 2.4.0
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 +27 -0
- package/CLAUDE.md +12 -13
- package/README.md +0 -15
- package/dist/styles/global.css +46 -48
- package/package.json +1 -2
- package/scripts/apply-brand.mjs +47 -30
- package/scripts/postinstall.mjs +1 -11
- package/src/styles/global.css +46 -48
- package/brands/engine/PARTNER_HUB_PRD.md +0 -584
- package/brands/engine/agentApiConfig.ts +0 -36
- package/brands/engine/app/api/graphql-operations-types.ts +0 -11260
- package/brands/engine/app/api/graphqlClient.ts +0 -25
- package/brands/engine/app/api/partnerQueries.ts +0 -212
- package/brands/engine/app/appLayout.tsx +0 -5
- package/brands/engine/app/components/AgentPanel.tsx +0 -402
- package/brands/engine/app/components/AgentforceConversationClient.tsx +0 -201
- package/brands/engine/app/components/__inherit_AgentforceConversationClient.tsx +0 -3
- package/brands/engine/app/components/alerts/status-alert.tsx +0 -49
- package/brands/engine/app/components/layouts/card-layout.tsx +0 -29
- package/brands/engine/app/components/workspace/CommandCenter.tsx +0 -16
- package/brands/engine/app/config/agentApi.ts +0 -36
- package/brands/engine/app/features/object-search/__examples__/api/accountSearchService.ts +0 -46
- package/brands/engine/app/features/object-search/__examples__/api/query/distinctAccountIndustries.graphql +0 -19
- package/brands/engine/app/features/object-search/__examples__/api/query/distinctAccountTypes.graphql +0 -19
- package/brands/engine/app/features/object-search/__examples__/api/query/getAccountDetail.graphql +0 -121
- package/brands/engine/app/features/object-search/__examples__/api/query/searchAccounts.graphql +0 -51
- package/brands/engine/app/features/object-search/__examples__/pages/AccountObjectDetailPage.tsx +0 -357
- package/brands/engine/app/features/object-search/__examples__/pages/AccountSearch.tsx +0 -312
- package/brands/engine/app/features/object-search/__examples__/pages/Home.tsx +0 -34
- package/brands/engine/app/features/object-search/api/objectSearchService.ts +0 -84
- package/brands/engine/app/features/object-search/components/ActiveFilters.tsx +0 -89
- package/brands/engine/app/features/object-search/components/FilterContext.tsx +0 -83
- package/brands/engine/app/features/object-search/components/ObjectBreadcrumb.tsx +0 -66
- package/brands/engine/app/features/object-search/components/PaginationControls.tsx +0 -109
- package/brands/engine/app/features/object-search/components/SearchBar.tsx +0 -41
- package/brands/engine/app/features/object-search/components/SortControl.tsx +0 -143
- package/brands/engine/app/features/object-search/components/filters/BooleanFilter.tsx +0 -78
- package/brands/engine/app/features/object-search/components/filters/DateFilter.tsx +0 -128
- package/brands/engine/app/features/object-search/components/filters/DateRangeFilter.tsx +0 -70
- package/brands/engine/app/features/object-search/components/filters/FilterFieldWrapper.tsx +0 -33
- package/brands/engine/app/features/object-search/components/filters/MultiSelectFilter.tsx +0 -97
- package/brands/engine/app/features/object-search/components/filters/NumericRangeFilter.tsx +0 -163
- package/brands/engine/app/features/object-search/components/filters/SearchFilter.tsx +0 -50
- package/brands/engine/app/features/object-search/components/filters/SelectFilter.tsx +0 -97
- package/brands/engine/app/features/object-search/components/filters/TextFilter.tsx +0 -91
- package/brands/engine/app/features/object-search/hooks/useAsyncData.ts +0 -54
- package/brands/engine/app/features/object-search/hooks/useCachedAsyncData.ts +0 -184
- package/brands/engine/app/features/object-search/hooks/useDebouncedCallback.ts +0 -34
- package/brands/engine/app/features/object-search/hooks/useObjectSearchParams.ts +0 -252
- package/brands/engine/app/features/object-search/utils/debounce.ts +0 -25
- package/brands/engine/app/features/object-search/utils/fieldUtils.ts +0 -29
- package/brands/engine/app/features/object-search/utils/filterUtils.ts +0 -404
- package/brands/engine/app/features/object-search/utils/sortUtils.ts +0 -38
- package/brands/engine/app/hooks/useEngineLiveData.ts +0 -49
- package/brands/engine/app/hooks/useEvaAgent.ts +0 -288
- package/brands/engine/app/hooks/usePartnerDashboardData.ts +0 -141
- package/brands/engine/app/navigationMenu.tsx +0 -80
- package/brands/engine/app/pages/AccountObjectDetailPage.tsx +0 -361
- package/brands/engine/app/pages/AccountSearch.tsx +0 -305
- package/brands/engine/app/pages/BlankDashboard.tsx +0 -15
- package/brands/engine/app/pages/DataTest.tsx +0 -78
- package/brands/engine/app/pages/Home.tsx +0 -5
- package/brands/engine/app/pages/NotFound.tsx +0 -19
- package/brands/engine/app/pages/PartnerHubDashboard.tsx +0 -2077
- package/brands/engine/app/pages/Search.tsx +0 -13
- package/brands/engine/app/router-utils.tsx +0 -35
- package/brands/engine/app/routes.tsx +0 -39
- package/brands/engine/app/styles/global.css +0 -269
- package/brands/engine/brand.css +0 -40
- package/brands/engine/engine-command-center-prd.md +0 -575
- package/brands/engine/engine-live-data.js +0 -135
- package/brands/engine/engine-sample-data.js +0 -378
- package/brands/engine/engine_logo.png +0 -0
- package/brands/engine/global.css +0 -269
- package/brands/engine/partner-hub-sample-data.js +0 -281
- package/brands/engine/schema.graphql +0 -292
- package/brands/engine/useEngineLiveData.ts +0 -49
- package/brands/engine/useEvaAgent.ts +0 -288
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,33 @@ 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
|
+
## [2.4.0] - 2026-05-07
|
|
9
|
+
|
|
10
|
+
### Removed
|
|
11
|
+
- **Engine brand assets** — deleted `brands/engine/` (global.css, app/, sample data, PRD, GraphQL schema, Engine logo, Engine-specific hooks like `useEvaAgent` and `useEngineLiveData`).
|
|
12
|
+
- **Top-level `data/` directory** — removed all Engine Travel Command Center data, schema, agent API config, and the README/USAGE docs that documented Engine-only assets.
|
|
13
|
+
- **`brand:engine` and `demo:engine` npm scripts** — removed from `package.json` and from the postinstall script that adds scripts to consuming projects.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- **`src/styles/global.css` is now truly neutral** — replaced the `--color-engine-*` palette and the Cyan/Engine-Black brand ramp with a slate-based neutral `--color-brand-*` ramp; replaced the Engine-coded `.heroui-scope` (Engine Black `#0D1117`, Cyan `#7DCBD9`, Orange-Red `#FD4B23`, Amber `#FFB200`, Engine Blue `#157DE5`) with neutral `oklch()` defaults. The `:root` `--dash-*` tokens (which previously used Engine amber/cream) now use neutral slate/standard semantic colors.
|
|
17
|
+
- **`scripts/apply-brand.mjs` is now brand-agnostic** — sample-data file copying discovers `*-sample-data.js` / `*-live-data.js` / `*-data.{js,ts}` files dynamically instead of hardcoding `engine-sample-data.js`, `engine-live-data.js`, `partner-hub-sample-data.js`. Logo copying discovers any `*.png|jpg|svg|webp|gif` file at the brand root instead of hardcoding `engine_logo.png`. Updated header docs to remove Engine examples.
|
|
18
|
+
- **`CLAUDE.md` Brand System section rewritten** — removed the "Engine Brand" callout and the `brand:engine` example. Now explains the brand system as optional infrastructure (no brands ship by default) and documents the conventions a `brands/<name>/` folder can use.
|
|
19
|
+
- **`README.md` Sample Data section removed** — the package no longer ships Engine Travel sample data.
|
|
20
|
+
|
|
21
|
+
### Context
|
|
22
|
+
- The package and its source files no longer carry any Engine Travel branding so it can be used as a neutral baseline for building a new app on top of the component library and Command Center builder. The brand system itself remains available; teams can drop their own brand under `brands/<name>/`.
|
|
23
|
+
|
|
24
|
+
## [2.3.17] - 2026-04-15
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- **Two-agent chat system** — AgentPanel now supports Partner Service Agent (booking recovery, default) and Engine Virtual Agent (case triage with handoff). Agents swap via `npm run agent:partner` / `agent:engine` which edits the source directly for instant HMR.
|
|
28
|
+
- **Structured card renderer for chat** — Messages with headers (OPEN CASES SUMMARY, CANCELED BOOKING, PROMOTION LIVE) render as formatted cards with priority dots, key-value pairs, and color-coded sections instead of plain text.
|
|
29
|
+
- **Improved chat readability** — Replaced CSS variable colors with high-contrast solid colors. Warm parchment backgrounds, dark text, visible borders. Bumped all font sizes +1px.
|
|
30
|
+
- **Cascading skeleton loading** — Tab switch skeletons now fade in with randomized stagger delays per element instead of uniform pulse. Each element has a unique random delay for natural feel.
|
|
31
|
+
- **Streamlined promo flow** — Removed ENGINE NETWORK PROMOTION card; upsell pitch now follows directly after CANCELED BOOKING card in a single conversational message.
|
|
32
|
+
- **Demo state manager** — `demo.sh` now tracks AgentPanel.tsx. Added `demo:d360` npm shortcut to fast-forward to Data 360 tab state.
|
|
33
|
+
- **Data 360 demo state** — Pre-built demo version with Data 360 booking segmentation tab, saveable/restorable via `demo:d360` / `demo:reset`.
|
|
34
|
+
|
|
8
35
|
## [2.3.16] - 2026-04-14
|
|
9
36
|
|
|
10
37
|
### Changed
|
package/CLAUDE.md
CHANGED
|
@@ -67,8 +67,7 @@ sf-web-components/
|
|
|
67
67
|
│ │ └── workspace/ # CommandCenter.tsx.template
|
|
68
68
|
│ ├── lib/ # Utilities (utils.ts)
|
|
69
69
|
│ └── styles/ # global.css with neutral brand tokens
|
|
70
|
-
├── brands/
|
|
71
|
-
│ └── engine/ # Engine brand (global.css, sample data, PRD, hooks)
|
|
70
|
+
├── brands/ # Optional brand bundles (none ship by default)
|
|
72
71
|
├── scripts/
|
|
73
72
|
│ ├── postinstall.mjs # Runs after npm install in consuming projects
|
|
74
73
|
│ ├── apply-brand.mjs # Apply/reset brand themes
|
|
@@ -86,23 +85,23 @@ sf-web-components/
|
|
|
86
85
|
|
|
87
86
|
## Brand System
|
|
88
87
|
|
|
89
|
-
The package ships with a **neutral theme** by default.
|
|
88
|
+
The package ships with a **neutral theme** by default. No brands ship out of the box; the brand system is optional infrastructure for layering custom themes/demo apps on top of the neutral baseline.
|
|
90
89
|
|
|
91
90
|
```bash
|
|
92
|
-
npm run brand:
|
|
93
|
-
npm run brand:reset #
|
|
94
|
-
npm run brand:list # Show available brands
|
|
91
|
+
npm run brand:list # Show available brands (empty by default)
|
|
92
|
+
npm run brand:reset # Restore neutral theme (clears any active brand)
|
|
95
93
|
```
|
|
96
94
|
|
|
97
|
-
|
|
95
|
+
To add a brand, drop a folder under `brands/<name>/` containing any of:
|
|
98
96
|
|
|
99
|
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
97
|
+
- `global.css` — overrides applied to `src/styles/global.css`
|
|
98
|
+
- `app/` — full demo app (pages, hooks, api, features) installed via `--demo`
|
|
99
|
+
- `*.png` / `*.svg` — logo assets installed into `src/assets/images/`
|
|
100
|
+
- `*-sample-data.js` / `*-live-data.js` — installed into `src/data/`
|
|
101
|
+
- `*_PRD.md` / `*-prd.md` — product requirements docs copied to project root
|
|
102
|
+
- `schema.graphql` — data schema copied to project root
|
|
104
103
|
|
|
105
|
-
|
|
104
|
+
When a brand is active, the reset script (`npm run reset:command-center`) preserves the brand's `global.css` instead of restoring neutral. The `.brand` marker file tracks which brand is active.
|
|
106
105
|
|
|
107
106
|
## Key Conventions
|
|
108
107
|
|
package/README.md
CHANGED
|
@@ -75,21 +75,6 @@ This library includes:
|
|
|
75
75
|
- Filter components
|
|
76
76
|
- Layout components
|
|
77
77
|
|
|
78
|
-
## Sample Data
|
|
79
|
-
|
|
80
|
-
The package includes pre-seeded sample data in the `data/` directory:
|
|
81
|
-
- **Engine Travel Command Center** sample data with real Salesforce field names
|
|
82
|
-
- Dashboard-ready data (map markers, chart data, metrics, etc.)
|
|
83
|
-
- Easy to swap for live data later
|
|
84
|
-
|
|
85
|
-
**Copy to your project:**
|
|
86
|
-
```bash
|
|
87
|
-
# From your webapp directory
|
|
88
|
-
cp node_modules/@schandlergarcia/sf-web-components/data/engine-sample-data.js src/data/
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
See `data/README.md` and `data/USAGE.md` in the package for full documentation.
|
|
92
|
-
|
|
93
78
|
## Utilities
|
|
94
79
|
|
|
95
80
|
```tsx
|
package/dist/styles/global.css
CHANGED
|
@@ -58,18 +58,18 @@
|
|
|
58
58
|
--color-sidebar-border: var(--sidebar-border);
|
|
59
59
|
--color-sidebar-ring: var(--sidebar-ring);
|
|
60
60
|
|
|
61
|
-
/*
|
|
62
|
-
--color-brand-50: #
|
|
63
|
-
--color-brand-100: #
|
|
64
|
-
--color-brand-200: #
|
|
65
|
-
--color-brand-300: #
|
|
66
|
-
--color-brand-400: #
|
|
67
|
-
--color-brand-500: #
|
|
68
|
-
--color-brand-600: #
|
|
69
|
-
--color-brand-700: #
|
|
70
|
-
--color-brand-800: #
|
|
71
|
-
--color-brand-900: #
|
|
72
|
-
--color-brand-950: #
|
|
61
|
+
/* Neutral brand ramp — override per-app to apply your brand colors */
|
|
62
|
+
--color-brand-50: #f8fafc;
|
|
63
|
+
--color-brand-100: #f1f5f9;
|
|
64
|
+
--color-brand-200: #e2e8f0;
|
|
65
|
+
--color-brand-300: #cbd5e1;
|
|
66
|
+
--color-brand-400: #94a3b8;
|
|
67
|
+
--color-brand-500: #64748b;
|
|
68
|
+
--color-brand-600: #475569;
|
|
69
|
+
--color-brand-700: #334155;
|
|
70
|
+
--color-brand-800: #1e293b;
|
|
71
|
+
--color-brand-900: #0f172a;
|
|
72
|
+
--color-brand-950: #020617;
|
|
73
73
|
|
|
74
74
|
--font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
|
|
75
75
|
--font-mono: 'JetBrains Mono', ui-monospace, monospace;
|
|
@@ -79,24 +79,24 @@
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
:root {
|
|
82
|
-
--dash-text: #
|
|
82
|
+
--dash-text: #0f172a;
|
|
83
83
|
--dash-muted: #475569;
|
|
84
|
-
--dash-label: #
|
|
85
|
-
--dash-surface: #
|
|
86
|
-
--dash-border: #
|
|
87
|
-
--dash-accent: #
|
|
88
|
-
--dash-success: #
|
|
89
|
-
--dash-info: #
|
|
90
|
-
--dash-warning: #
|
|
84
|
+
--dash-label: #94a3b8;
|
|
85
|
+
--dash-surface: #ffffff;
|
|
86
|
+
--dash-border: #e2e8f0;
|
|
87
|
+
--dash-accent: #64748b;
|
|
88
|
+
--dash-success: #34d399;
|
|
89
|
+
--dash-info: #67e8f9;
|
|
90
|
+
--dash-warning: #f59e0b;
|
|
91
91
|
--dash-danger: #dc2626;
|
|
92
|
-
--dash-dark: #
|
|
93
|
-
--dash-darker: #
|
|
94
|
-
--dash-chart-1: #
|
|
95
|
-
--dash-chart-2: #
|
|
96
|
-
--dash-chart-3: #
|
|
97
|
-
--dash-chart-4: #
|
|
98
|
-
--dash-metric-size:
|
|
99
|
-
--dash-metric-sub:
|
|
92
|
+
--dash-dark: #0f172a;
|
|
93
|
+
--dash-darker: #020617;
|
|
94
|
+
--dash-chart-1: #64748b;
|
|
95
|
+
--dash-chart-2: #34d399;
|
|
96
|
+
--dash-chart-3: #67e8f9;
|
|
97
|
+
--dash-chart-4: #f59e0b;
|
|
98
|
+
--dash-metric-size: 2.5rem;
|
|
99
|
+
--dash-metric-sub: 2.25rem;
|
|
100
100
|
--color-dash-text: var(--dash-text);
|
|
101
101
|
--color-dash-muted: var(--dash-muted);
|
|
102
102
|
--color-dash-label: var(--dash-label);
|
|
@@ -193,39 +193,37 @@
|
|
|
193
193
|
|
|
194
194
|
/*
|
|
195
195
|
* Restore HeroUI theme variables inside the Command Center scope.
|
|
196
|
-
*
|
|
197
|
-
* semantics (bg colors vs text colors). This scope restores HeroUI's values
|
|
198
|
-
* so HeroUI components render correctly.
|
|
196
|
+
* Neutral defaults — override per-app to apply your brand colors.
|
|
199
197
|
*/
|
|
200
198
|
.heroui-scope {
|
|
201
|
-
--primary:
|
|
199
|
+
--primary: oklch(0.205 0 0);
|
|
202
200
|
--primary-foreground: oklch(0.9911 0 0);
|
|
203
|
-
--secondary:
|
|
201
|
+
--secondary: oklch(0.55 0.02 240);
|
|
204
202
|
--secondary-foreground: oklch(0.9911 0 0);
|
|
205
|
-
--success: #
|
|
203
|
+
--success: #16a34a;
|
|
206
204
|
--success-foreground: oklch(0.9911 0 0);
|
|
207
|
-
--warning: #
|
|
208
|
-
--warning-foreground: oklch(0.
|
|
209
|
-
--danger: #
|
|
205
|
+
--warning: #f59e0b;
|
|
206
|
+
--warning-foreground: oklch(0.205 0 0);
|
|
207
|
+
--danger: #dc2626;
|
|
210
208
|
--danger-foreground: oklch(0.9911 0 0);
|
|
211
209
|
|
|
212
210
|
--muted: oklch(0.5517 0.0138 285.94);
|
|
213
211
|
--accent: oklch(0.6204 0.195 253.83);
|
|
214
212
|
--accent-foreground: oklch(0.9911 0 0);
|
|
215
|
-
--background: oklch(0.
|
|
216
|
-
--foreground: oklch(0.
|
|
213
|
+
--background: oklch(0.985 0 0);
|
|
214
|
+
--foreground: oklch(0.145 0 0);
|
|
217
215
|
--default: oklch(94% 0.001 286.375);
|
|
218
|
-
--default-foreground: oklch(0.
|
|
219
|
-
--border: oklch(
|
|
216
|
+
--default-foreground: oklch(0.145 0 0);
|
|
217
|
+
--border: oklch(0.85 0.005 286);
|
|
220
218
|
--separator: oklch(92% 0.004 286.32);
|
|
221
219
|
--segment: oklch(100% 0 0);
|
|
222
|
-
--segment-foreground: oklch(0.
|
|
220
|
+
--segment-foreground: oklch(0.145 0 0);
|
|
223
221
|
--surface: oklch(100% 0 0);
|
|
224
|
-
--surface-foreground: oklch(0.
|
|
222
|
+
--surface-foreground: oklch(0.145 0 0);
|
|
225
223
|
--overlay: oklch(100% 0 0);
|
|
226
|
-
--overlay-foreground: oklch(0.
|
|
227
|
-
--focus: oklch(0.
|
|
228
|
-
--link: oklch(0.
|
|
224
|
+
--overlay-foreground: oklch(0.145 0 0);
|
|
225
|
+
--focus: oklch(0.6 0.18 250);
|
|
226
|
+
--link: oklch(0.205 0 0);
|
|
229
227
|
}
|
|
230
228
|
|
|
231
229
|
/* ChatBar expanded overlay — horizontal padding so it doesn't hit window edges */
|
|
@@ -250,9 +248,9 @@ body > .fixed.inset-x-0.rounded-2xl {
|
|
|
250
248
|
--overlay: oklch(0.2103 0.0059 285.89);
|
|
251
249
|
--overlay-foreground: oklch(0.9911 0 0);
|
|
252
250
|
--warning: oklch(0.8203 0.1388 76.34);
|
|
253
|
-
--warning-foreground: oklch(0.
|
|
251
|
+
--warning-foreground: oklch(0.145 0 0);
|
|
254
252
|
--danger: oklch(0.594 0.1967 24.63);
|
|
255
253
|
--danger-foreground: oklch(0.9911 0 0);
|
|
256
|
-
--focus: oklch(0.
|
|
254
|
+
--focus: oklch(0.6 0.18 250);
|
|
257
255
|
--link: oklch(0.9911 0 0);
|
|
258
256
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schandlergarcia/sf-web-components",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
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",
|
|
@@ -52,7 +52,6 @@
|
|
|
52
52
|
"reset:command-center": "bash scripts/reset-command-center.sh",
|
|
53
53
|
"validate:dashboard": "bash scripts/validate-dashboard.sh",
|
|
54
54
|
"graphql:schema": "node scripts/get-graphql-schema.mjs",
|
|
55
|
-
"brand:engine": "node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs engine",
|
|
56
55
|
"brand:reset": "node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs --reset",
|
|
57
56
|
"brand:list": "node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs --list"
|
|
58
57
|
},
|
package/scripts/apply-brand.mjs
CHANGED
|
@@ -4,14 +4,19 @@
|
|
|
4
4
|
* apply-brand.mjs — Apply a brand theme or install a full demo app.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
* node scripts/apply-brand.mjs
|
|
8
|
-
* node scripts/apply-brand.mjs --demo
|
|
9
|
-
* node scripts/apply-brand.mjs --list
|
|
10
|
-
* node scripts/apply-brand.mjs --reset
|
|
7
|
+
* node scripts/apply-brand.mjs <brand> # Apply brand colors only
|
|
8
|
+
* node scripts/apply-brand.mjs --demo <brand> # Install full demo app for a brand
|
|
9
|
+
* node scripts/apply-brand.mjs --list # List available brands
|
|
10
|
+
* node scripts/apply-brand.mjs --reset # Remove brand, restore neutral theme
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* Brands live in brands/<name>/ at the package root. Each brand may provide:
|
|
13
|
+
* - global.css (theme overrides applied to src/styles/global.css)
|
|
14
|
+
* - app/ (full demo app: pages, hooks, api, features, etc.)
|
|
15
|
+
* - schema.graphql (data schema)
|
|
16
|
+
* - *.png (brand logo assets)
|
|
17
|
+
* - *_PRD.md / *-prd.md (product requirements docs)
|
|
18
|
+
*
|
|
19
|
+
* No brands ship with the package by default. Add your own under brands/.
|
|
15
20
|
*/
|
|
16
21
|
|
|
17
22
|
import fs from 'fs';
|
|
@@ -184,17 +189,21 @@ if (isDemo) {
|
|
|
184
189
|
}
|
|
185
190
|
}
|
|
186
191
|
|
|
187
|
-
// Copy
|
|
188
|
-
const dataFiles =
|
|
192
|
+
// Copy any *.js / *.ts data files at the brand root into src/data/
|
|
193
|
+
const dataFiles = fs.readdirSync(brandDir).filter(f => {
|
|
194
|
+
if (!fs.statSync(path.join(brandDir, f)).isFile()) return false;
|
|
195
|
+
return f.endsWith('-sample-data.js')
|
|
196
|
+
|| f.endsWith('-live-data.js')
|
|
197
|
+
|| f.endsWith('-data.ts')
|
|
198
|
+
|| f.endsWith('-data.js');
|
|
199
|
+
});
|
|
189
200
|
for (const file of dataFiles) {
|
|
190
201
|
const src = path.join(brandDir, file);
|
|
191
202
|
const dst = path.join(cwd, 'src/data', file);
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
installed++;
|
|
197
|
-
}
|
|
203
|
+
fs.mkdirSync(path.dirname(dst), { recursive: true });
|
|
204
|
+
fs.copyFileSync(src, dst);
|
|
205
|
+
console.log(` ✓ Installed src/data/${file}`);
|
|
206
|
+
installed++;
|
|
198
207
|
}
|
|
199
208
|
|
|
200
209
|
// Copy PRDs to project root
|
|
@@ -213,13 +222,16 @@ if (isDemo) {
|
|
|
213
222
|
installed++;
|
|
214
223
|
}
|
|
215
224
|
|
|
216
|
-
// Copy logo
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
225
|
+
// Copy any logo/image assets at the brand root into src/assets/images/
|
|
226
|
+
const imageFiles = fs.readdirSync(brandDir).filter(f =>
|
|
227
|
+
/\.(png|jpe?g|svg|webp|gif)$/i.test(f)
|
|
228
|
+
);
|
|
229
|
+
for (const file of imageFiles) {
|
|
230
|
+
const src = path.join(brandDir, file);
|
|
231
|
+
const dst = path.join(cwd, 'src/assets/images', file);
|
|
232
|
+
fs.mkdirSync(path.dirname(dst), { recursive: true });
|
|
233
|
+
fs.copyFileSync(src, dst);
|
|
234
|
+
console.log(` ✓ Installed src/assets/images/${file}`);
|
|
223
235
|
installed++;
|
|
224
236
|
}
|
|
225
237
|
|
|
@@ -259,14 +271,19 @@ if (fs.existsSync(brandCSS)) {
|
|
|
259
271
|
installed++;
|
|
260
272
|
}
|
|
261
273
|
|
|
262
|
-
// 2.
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
274
|
+
// 2. Any logo/image assets → src/assets/images/
|
|
275
|
+
if (fs.existsSync(brandDir)) {
|
|
276
|
+
const imageFiles = fs.readdirSync(brandDir).filter(f =>
|
|
277
|
+
/\.(png|jpe?g|svg|webp|gif)$/i.test(f)
|
|
278
|
+
);
|
|
279
|
+
for (const file of imageFiles) {
|
|
280
|
+
const src = path.join(brandDir, file);
|
|
281
|
+
const dst = path.join(cwd, 'src/assets/images', file);
|
|
282
|
+
fs.mkdirSync(path.dirname(dst), { recursive: true });
|
|
283
|
+
fs.copyFileSync(src, dst);
|
|
284
|
+
console.log(` ✓ Installed src/assets/images/${file}`);
|
|
285
|
+
installed++;
|
|
286
|
+
}
|
|
270
287
|
}
|
|
271
288
|
|
|
272
289
|
// 3. Write .brand marker
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -341,11 +341,7 @@ if (fs.existsSync(packageJsonPath)) {
|
|
|
341
341
|
scriptsAdded.push('sfwc:setup');
|
|
342
342
|
}
|
|
343
343
|
|
|
344
|
-
// Add brand scripts
|
|
345
|
-
if (!packageJson.scripts['brand:engine']) {
|
|
346
|
-
packageJson.scripts['brand:engine'] = 'node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs engine';
|
|
347
|
-
scriptsAdded.push('brand:engine');
|
|
348
|
-
}
|
|
344
|
+
// Add brand scripts (no brands ship by default — add your own under brands/)
|
|
349
345
|
if (!packageJson.scripts['brand:reset']) {
|
|
350
346
|
packageJson.scripts['brand:reset'] = 'node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs --reset';
|
|
351
347
|
scriptsAdded.push('brand:reset');
|
|
@@ -355,12 +351,6 @@ if (fs.existsSync(packageJsonPath)) {
|
|
|
355
351
|
scriptsAdded.push('brand:list');
|
|
356
352
|
}
|
|
357
353
|
|
|
358
|
-
// Add demo scripts
|
|
359
|
-
if (!packageJson.scripts['demo:engine']) {
|
|
360
|
-
packageJson.scripts['demo:engine'] = 'node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs --demo engine';
|
|
361
|
-
scriptsAdded.push('demo:engine');
|
|
362
|
-
}
|
|
363
|
-
|
|
364
354
|
if (scriptsAdded.length > 0) {
|
|
365
355
|
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf-8');
|
|
366
356
|
scriptsAdded.forEach(script => {
|
package/src/styles/global.css
CHANGED
|
@@ -58,18 +58,18 @@
|
|
|
58
58
|
--color-sidebar-border: var(--sidebar-border);
|
|
59
59
|
--color-sidebar-ring: var(--sidebar-ring);
|
|
60
60
|
|
|
61
|
-
/*
|
|
62
|
-
--color-brand-50: #
|
|
63
|
-
--color-brand-100: #
|
|
64
|
-
--color-brand-200: #
|
|
65
|
-
--color-brand-300: #
|
|
66
|
-
--color-brand-400: #
|
|
67
|
-
--color-brand-500: #
|
|
68
|
-
--color-brand-600: #
|
|
69
|
-
--color-brand-700: #
|
|
70
|
-
--color-brand-800: #
|
|
71
|
-
--color-brand-900: #
|
|
72
|
-
--color-brand-950: #
|
|
61
|
+
/* Neutral brand ramp — override per-app to apply your brand colors */
|
|
62
|
+
--color-brand-50: #f8fafc;
|
|
63
|
+
--color-brand-100: #f1f5f9;
|
|
64
|
+
--color-brand-200: #e2e8f0;
|
|
65
|
+
--color-brand-300: #cbd5e1;
|
|
66
|
+
--color-brand-400: #94a3b8;
|
|
67
|
+
--color-brand-500: #64748b;
|
|
68
|
+
--color-brand-600: #475569;
|
|
69
|
+
--color-brand-700: #334155;
|
|
70
|
+
--color-brand-800: #1e293b;
|
|
71
|
+
--color-brand-900: #0f172a;
|
|
72
|
+
--color-brand-950: #020617;
|
|
73
73
|
|
|
74
74
|
--font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
|
|
75
75
|
--font-mono: 'JetBrains Mono', ui-monospace, monospace;
|
|
@@ -79,24 +79,24 @@
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
:root {
|
|
82
|
-
--dash-text: #
|
|
82
|
+
--dash-text: #0f172a;
|
|
83
83
|
--dash-muted: #475569;
|
|
84
|
-
--dash-label: #
|
|
85
|
-
--dash-surface: #
|
|
86
|
-
--dash-border: #
|
|
87
|
-
--dash-accent: #
|
|
88
|
-
--dash-success: #
|
|
89
|
-
--dash-info: #
|
|
90
|
-
--dash-warning: #
|
|
84
|
+
--dash-label: #94a3b8;
|
|
85
|
+
--dash-surface: #ffffff;
|
|
86
|
+
--dash-border: #e2e8f0;
|
|
87
|
+
--dash-accent: #64748b;
|
|
88
|
+
--dash-success: #34d399;
|
|
89
|
+
--dash-info: #67e8f9;
|
|
90
|
+
--dash-warning: #f59e0b;
|
|
91
91
|
--dash-danger: #dc2626;
|
|
92
|
-
--dash-dark: #
|
|
93
|
-
--dash-darker: #
|
|
94
|
-
--dash-chart-1: #
|
|
95
|
-
--dash-chart-2: #
|
|
96
|
-
--dash-chart-3: #
|
|
97
|
-
--dash-chart-4: #
|
|
98
|
-
--dash-metric-size:
|
|
99
|
-
--dash-metric-sub:
|
|
92
|
+
--dash-dark: #0f172a;
|
|
93
|
+
--dash-darker: #020617;
|
|
94
|
+
--dash-chart-1: #64748b;
|
|
95
|
+
--dash-chart-2: #34d399;
|
|
96
|
+
--dash-chart-3: #67e8f9;
|
|
97
|
+
--dash-chart-4: #f59e0b;
|
|
98
|
+
--dash-metric-size: 2.5rem;
|
|
99
|
+
--dash-metric-sub: 2.25rem;
|
|
100
100
|
--color-dash-text: var(--dash-text);
|
|
101
101
|
--color-dash-muted: var(--dash-muted);
|
|
102
102
|
--color-dash-label: var(--dash-label);
|
|
@@ -193,39 +193,37 @@
|
|
|
193
193
|
|
|
194
194
|
/*
|
|
195
195
|
* Restore HeroUI theme variables inside the Command Center scope.
|
|
196
|
-
*
|
|
197
|
-
* semantics (bg colors vs text colors). This scope restores HeroUI's values
|
|
198
|
-
* so HeroUI components render correctly.
|
|
196
|
+
* Neutral defaults — override per-app to apply your brand colors.
|
|
199
197
|
*/
|
|
200
198
|
.heroui-scope {
|
|
201
|
-
--primary:
|
|
199
|
+
--primary: oklch(0.205 0 0);
|
|
202
200
|
--primary-foreground: oklch(0.9911 0 0);
|
|
203
|
-
--secondary:
|
|
201
|
+
--secondary: oklch(0.55 0.02 240);
|
|
204
202
|
--secondary-foreground: oklch(0.9911 0 0);
|
|
205
|
-
--success: #
|
|
203
|
+
--success: #16a34a;
|
|
206
204
|
--success-foreground: oklch(0.9911 0 0);
|
|
207
|
-
--warning: #
|
|
208
|
-
--warning-foreground: oklch(0.
|
|
209
|
-
--danger: #
|
|
205
|
+
--warning: #f59e0b;
|
|
206
|
+
--warning-foreground: oklch(0.205 0 0);
|
|
207
|
+
--danger: #dc2626;
|
|
210
208
|
--danger-foreground: oklch(0.9911 0 0);
|
|
211
209
|
|
|
212
210
|
--muted: oklch(0.5517 0.0138 285.94);
|
|
213
211
|
--accent: oklch(0.6204 0.195 253.83);
|
|
214
212
|
--accent-foreground: oklch(0.9911 0 0);
|
|
215
|
-
--background: oklch(0.
|
|
216
|
-
--foreground: oklch(0.
|
|
213
|
+
--background: oklch(0.985 0 0);
|
|
214
|
+
--foreground: oklch(0.145 0 0);
|
|
217
215
|
--default: oklch(94% 0.001 286.375);
|
|
218
|
-
--default-foreground: oklch(0.
|
|
219
|
-
--border: oklch(
|
|
216
|
+
--default-foreground: oklch(0.145 0 0);
|
|
217
|
+
--border: oklch(0.85 0.005 286);
|
|
220
218
|
--separator: oklch(92% 0.004 286.32);
|
|
221
219
|
--segment: oklch(100% 0 0);
|
|
222
|
-
--segment-foreground: oklch(0.
|
|
220
|
+
--segment-foreground: oklch(0.145 0 0);
|
|
223
221
|
--surface: oklch(100% 0 0);
|
|
224
|
-
--surface-foreground: oklch(0.
|
|
222
|
+
--surface-foreground: oklch(0.145 0 0);
|
|
225
223
|
--overlay: oklch(100% 0 0);
|
|
226
|
-
--overlay-foreground: oklch(0.
|
|
227
|
-
--focus: oklch(0.
|
|
228
|
-
--link: oklch(0.
|
|
224
|
+
--overlay-foreground: oklch(0.145 0 0);
|
|
225
|
+
--focus: oklch(0.6 0.18 250);
|
|
226
|
+
--link: oklch(0.205 0 0);
|
|
229
227
|
}
|
|
230
228
|
|
|
231
229
|
/* ChatBar expanded overlay — horizontal padding so it doesn't hit window edges */
|
|
@@ -250,9 +248,9 @@ body > .fixed.inset-x-0.rounded-2xl {
|
|
|
250
248
|
--overlay: oklch(0.2103 0.0059 285.89);
|
|
251
249
|
--overlay-foreground: oklch(0.9911 0 0);
|
|
252
250
|
--warning: oklch(0.8203 0.1388 76.34);
|
|
253
|
-
--warning-foreground: oklch(0.
|
|
251
|
+
--warning-foreground: oklch(0.145 0 0);
|
|
254
252
|
--danger: oklch(0.594 0.1967 24.63);
|
|
255
253
|
--danger-foreground: oklch(0.9911 0 0);
|
|
256
|
-
--focus: oklch(0.
|
|
254
|
+
--focus: oklch(0.6 0.18 250);
|
|
257
255
|
--link: oklch(0.9911 0 0);
|
|
258
256
|
}
|