@genesislcap/rapid-design-system 14.471.0 → 14.472.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.
@@ -0,0 +1,67 @@
1
+ import { css } from '@microsoft/fast-element';
2
+ import { FLEXLAYOUT_REACT_THEME_CSS, RAPID_FLEXLAYOUT_REACT_VERSION, } from './flexlayout-react-theme.generated';
3
+ /**
4
+ * The flexlayout-react version this theme is built against. flexlayout-react remains an
5
+ * app-level dependency; this is the version the platform theme is known to be compatible
6
+ * with (see the optional `flexlayout-react` peerDependency).
7
+ */
8
+ export { RAPID_FLEXLAYOUT_REACT_VERSION };
9
+ /**
10
+ * The complete, platform-owned flexlayout-react theme as raw CSS text: the vendored
11
+ * flexlayout-react base theme (structural CSS + dark palette) followed by the Rapid Design
12
+ * System overrides (token remap + tweaks). This is the single source of truth — apps should
13
+ * never import flexlayout-react's own stylesheets or copy the overrides locally.
14
+ *
15
+ * Colours resolve from rapid design tokens, so render flexlayout-react under a
16
+ * `<rapid-design-system-provider>` (CSS custom properties inherit across shadow boundaries).
17
+ *
18
+ * Use this when you need the string directly (e.g. server-rendered `<style>`); most callers
19
+ * want {@link installRapidFlexLayoutReactStyles} or {@link getRapidFlexLayoutReactStyleSheet}.
20
+ */
21
+ export const rapidFlexLayoutReactStyleText = FLEXLAYOUT_REACT_THEME_CSS;
22
+ /**
23
+ * The platform flexlayout-react theme as FAST {@link ElementStyles}, for adoption into a
24
+ * web component's shadow root (e.g. composing into a component's `styles`).
25
+ */
26
+ export const rapidFlexLayoutReactStyles = css `
27
+ ${rapidFlexLayoutReactStyleText}
28
+ `;
29
+ const STYLE_MARKER = 'data-rapid-flexlayout-react-theme';
30
+ let cachedSheet;
31
+ /**
32
+ * Returns a cached constructable {@link CSSStyleSheet} for the platform flexlayout-react
33
+ * theme, suitable for `(document | shadowRoot).adoptedStyleSheets`. The sheet is created
34
+ * once and shared across all adopters.
35
+ *
36
+ * @example
37
+ * shadowRoot.adoptedStyleSheets = [...shadowRoot.adoptedStyleSheets, getRapidFlexLayoutReactStyleSheet()];
38
+ */
39
+ export const getRapidFlexLayoutReactStyleSheet = () => {
40
+ if (!cachedSheet) {
41
+ cachedSheet = new CSSStyleSheet();
42
+ cachedSheet.replaceSync(rapidFlexLayoutReactStyleText);
43
+ }
44
+ return cachedSheet;
45
+ };
46
+ /**
47
+ * Installs the platform flexlayout-react theme into a `Document` (default) or `ShadowRoot`.
48
+ * Idempotent — calling it more than once on the same target is a no-op. Call once where
49
+ * flexlayout-react renders:
50
+ * - light DOM: `installRapidFlexLayoutReactStyles()` at app bootstrap;
51
+ * - shadow DOM: `installRapidFlexLayoutReactStyles(myShadowRoot)`.
52
+ *
53
+ * Prefers constructable stylesheets (`adoptedStyleSheets`); falls back to injecting a
54
+ * `<style>` element for older engines.
55
+ */
56
+ export const installRapidFlexLayoutReactStyles = (target = document) => {
57
+ // Cast the `in` operand so TS does not narrow `target` to `never` in the fallback branch
58
+ // (both Document and ShadowRoot declare `adoptedStyleSheets` in the DOM lib types, so the
59
+ // negative branch would otherwise be considered unreachable).
60
+ if ('adoptedStyleSheets' in target) {
61
+ const sheet = getRapidFlexLayoutReactStyleSheet();
62
+ if (!target.adoptedStyleSheets.includes(sheet)) {
63
+ target.adoptedStyleSheets = [...target.adoptedStyleSheets, sheet];
64
+ }
65
+ return;
66
+ }
67
+ };
@@ -0,0 +1,253 @@
1
+ /*
2
+ * flexlayout-react.overrides.css — Rapid Design System theme overrides for flexlayout-react.
3
+ *
4
+ * THIS IS THE SINGLE SOURCE OF TRUTH for how flexlayout-react looks across every app that
5
+ * consumes Foundation. Do NOT copy these rules into apps — import the compiled theme from
6
+ * `@genesislcap/rapid-design-system` instead (see flexlayout-react-theme.ts).
7
+ *
8
+ * Build pipeline: `scripts/generate-flexlayout-theme.mjs` concatenates the vendored
9
+ * flexlayout-react base theme (structural CSS + dark palette) FIRST, then this file LAST,
10
+ * into `flexlayout-react-theme.generated.ts`. Equal specificity means the later sheet wins,
11
+ * so every rule here overrides the vendored default. Run `pnpm flexlayout:generate` after
12
+ * editing (the package build does this automatically).
13
+ *
14
+ * The flexlayout theme is almost entirely driven by CSS custom properties declared on
15
+ * `.flexlayout__layout` (see the full list at the top of the vendored base theme). The
16
+ * easiest way to re-skin is to remap those variables to rapid design-system tokens, as
17
+ * below. For anything the variables don't cover, target the `.flexlayout__*` classes
18
+ * directly (examples at the bottom).
19
+ *
20
+ * Tokens resolve from the nearest design-system provider ancestor (CSS custom properties
21
+ * inherit across shadow boundaries), so flexlayout-react must render under a
22
+ * `<rapid-design-system-provider>` for these to take effect.
23
+ */
24
+
25
+ /* --- Variable remap: flexlayout palette -> rapid design tokens ----------------- */
26
+ .flexlayout__layout {
27
+ --font-family: var(--body-font, Roboto, Arial, sans-serif);
28
+ --font-size: var(--type-ramp-base-font-size);
29
+
30
+ --color-text: var(--neutral-foreground-rest);
31
+ --color-background: var(--fill-color);
32
+
33
+ /* Greyscale ramp used across tabsets, borders and toolbars. */
34
+ --color-1: var(--neutral-layer-1);
35
+ --color-2: var(--neutral-layer-2);
36
+ --color-3: var(--neutral-layer-3);
37
+ --color-4: var(--neutral-layer-4);
38
+
39
+ /* Selected tab + active splitter pick up the accent colour. */
40
+ --color-tab-selected: var(--accent-foreground-rest);
41
+ --color-tab-unselected: var(--neutral-foreground-hint);
42
+ --color-tab-selected-background: var(--accent-fill-rest);
43
+ --color-splitter-drag: var(--accent-fill-rest);
44
+ --color-splitter-hover: var(--accent-fill-hover);
45
+ }
46
+
47
+ .flexlayout__tabset-selected,
48
+ .flexlayout__tabset-maximized {
49
+ background-image: none !important;
50
+ }
51
+
52
+ .flexlayout__tab_button_content {
53
+ font-weight: 400;
54
+ font-size: var(--type-ramp-minus-1-font-size);
55
+ }
56
+
57
+ .flexlayout__tab_button--unselected:hover {
58
+ color: var(--neutral-foreground-rest, #e0e0e0) !important;
59
+ background-color: var(--neutral-fill-stealth-active, rgba(255, 255, 255, 0.06)) !important;
60
+ }
61
+
62
+ .flexlayout__tab_top,
63
+ .flexlayout__tab_bottom {
64
+ border-radius: 0 !important;
65
+ box-shadow: none !important;
66
+ }
67
+
68
+ .flexlayout__tab_toolbar_button-max,
69
+ .flexlayout__tab_toolbar_button-min {
70
+ order: 100;
71
+ }
72
+
73
+ .flexlayout__tab_button_textbox {
74
+ box-sizing: border-box;
75
+ width: auto;
76
+ min-width: 8em;
77
+ max-width: 100%;
78
+ margin: 0;
79
+ padding: 0 calc(var(--design-unit, 4) * 1px);
80
+ font-family: var(--body-font);
81
+ font-size: var(--type-ramp-base-font-size, var(--font-size));
82
+ font-weight: 500;
83
+ line-height: var(--type-ramp-base-line-height, normal);
84
+ color: var(--neutral-foreground-rest);
85
+ background-color: var(--neutral-fill-input-rest);
86
+ border: 1px solid var(--neutral-stroke-rest);
87
+ border-radius: calc(var(--control-corner-radius, 2) * 1px);
88
+
89
+ &:focus {
90
+ outline: none;
91
+ color: var(--neutral-foreground-rest);
92
+ background-color: var(--neutral-fill-input-focus, var(--neutral-fill-input-rest));
93
+ border-color: var(--accent-fill-rest);
94
+ }
95
+ }
96
+
97
+ .flexlayout__tabset {
98
+ border: var(--card-border, 1px solid var(--neutral-stroke-rest));
99
+ border-radius: var(--card-corner-radius, calc(var(--control-corner-radius) * 1.5px));
100
+ background-color: var(--rapid-layout-item-background, var(--neutral-layer-3));
101
+ }
102
+
103
+ .flexlayout__tabset_content {
104
+ margin-top: -1px;
105
+ }
106
+
107
+ .flexlayout__tabset_tabbar_outer_top {
108
+ border: 0;
109
+ height: var(
110
+ --foundation-tab-height,
111
+ calc((((var(--base-height-multiplier) + var(--density)) * var(--design-unit)) - 4) * 1px)
112
+ );
113
+ background: none;
114
+ z-index: 1;
115
+ }
116
+
117
+ .flexlayout__tabset_container {
118
+ border-radius: var(--card-corner-radius, calc(var(--control-corner-radius) * 1.5px));
119
+ }
120
+
121
+ .flexlayout__tabset_tabbar_inner_tab_container_top {
122
+ border-top: 0;
123
+ }
124
+
125
+ .flexlayout__tab_button {
126
+ border-right-style: solid;
127
+ border-right-width: var(--tab-rest-border-width, 1px);
128
+ border-right-color: var(--tab-rest-border-color, var(--neutral-stroke-rest));
129
+ padding: 0 calc((12 + var(--design-unit) * 2 * var(--density)) * 1px);
130
+ gap: 8px;
131
+
132
+ &:first-child {
133
+ border-left-style: solid;
134
+ border-left-width: var(--tab-rest-border-width, 1px);
135
+ border-left-color: var(--tab-rest-border-color, var(--neutral-stroke-rest));
136
+ }
137
+ }
138
+
139
+ .flexlayout__tab_button--selected {
140
+ position: relative;
141
+ color: var(--accent-foreground-rest) !important;
142
+ background: var(--tab-active-background-color, var(--neutral-layer-card-container));
143
+ border-style: solid;
144
+ border-width: var(--tab-active-border-width, 0 1px 0 0);
145
+ border-color: var(--tab-active-border-color, var(--neutral-stroke-rest));
146
+ .flexlayout__tab_button_content {
147
+ font-weight: 700;
148
+ }
149
+ }
150
+
151
+ .flexlayout__tab {
152
+ border-radius: calc(var(--control-corner-radius) * 1.5px)
153
+ calc(var(--control-corner-radius) * 1.5px)
154
+ var(--card-corner-radius, calc(var(--control-corner-radius) * 1.5px))
155
+ var(--card-corner-radius, calc(var(--control-corner-radius) * 1.5px));
156
+ border-top: var(--card-border, 1px solid var(--neutral-stroke-rest));
157
+ background: var(--neutral-layer-card-container);
158
+
159
+ rapid-card {
160
+ display: flex;
161
+ flex-direction: column;
162
+ border: 0;
163
+ border-radius: 0 0 var(--card-corner-radius) var(--card-corner-radius);
164
+ grid-register {
165
+ display: block;
166
+ height: 100%;
167
+ }
168
+ }
169
+ }
170
+
171
+ .flexlayout__tabset_tab_divider {
172
+ width: 0;
173
+ }
174
+
175
+ .flexlayout__tab_button_trailing {
176
+ rapid-icon {
177
+ color: var(--accent-foreground-rest);
178
+
179
+ &:hover {
180
+ color: var(--accent-foreground-hover);
181
+ }
182
+ }
183
+ }
184
+
185
+ .flexlayout__popup_menu_container {
186
+ box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
187
+ padding: 0;
188
+ border: 1px solid var(--neutral-stroke-rest);
189
+ }
190
+
191
+ .flexlayout__popup_menu_item {
192
+ padding: calc((8 + var(--design-unit) * 2 * var(--density)) * 1px);
193
+ border-bottom: 1px solid var(--neutral-stroke-divider-rest);
194
+
195
+ &:hover {
196
+ background-color: var(--neutral-fill-rest);
197
+ color: contrast-color(var(--neutral-fill-rest));
198
+ }
199
+
200
+ &:last-child {
201
+ border-bottom: 0;
202
+ }
203
+ }
204
+
205
+ .flexlayout__popup_menu_item--selected {
206
+ background-color: var(--neutral-fill-rest);
207
+ color: contrast-color(var(--neutral-fill-rest));
208
+ }
209
+
210
+ .flexlayout__tab_toolbar_button {
211
+ padding: 0;
212
+ height: unset;
213
+ width: unset;
214
+ display: flex;
215
+ align-items: center;
216
+ justify-content: center;
217
+ cursor: pointer;
218
+ > svg {
219
+ height: 16px !important;
220
+ width: 16px !important;
221
+ padding: 4px;
222
+ fill: var(--neutral-foreground-hint);
223
+ }
224
+ }
225
+
226
+ .flexlayout__splitter_vert {
227
+ background-color: var(--neutral-foreground-rest);
228
+ mask-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48IS0tISBGb250IEF3ZXNvbWUgUHJvIDYuNi4wIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlIChDb21tZXJjaWFsIExpY2Vuc2UpIENvcHlyaWdodCAyMDI0IEZvbnRpY29ucywgSW5jLiAtLT48cGF0aCBkPSJNNDE2IDI1NmEzMiAzMiAwIDEgMSAtNjQgMCAzMiAzMiAwIDEgMSA2NCAwem0tMTYwIDBhMzIgMzIgMCAxIDEgLTY0IDAgMzIgMzIgMCAxIDEgNjQgMHpNNjQgMjg4YTMyIDMyIDAgMSAxIDAtNjQgMzIgMzIgMCAxIDEgMCA2NHoiLz48L3N2Zz4=);
229
+ mask-repeat: no-repeat;
230
+ mask-position: center;
231
+ mask-size: 12px;
232
+ &:hover {
233
+ mask-image: none;
234
+ }
235
+ }
236
+
237
+ .flexlayout__splitter_horz {
238
+ background-color: var(--neutral-foreground-rest);
239
+ mask-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjggNTEyIj48IS0tISBGb250IEF3ZXNvbWUgUHJvIDYuNi4wIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlIChDb21tZXJjaWFsIExpY2Vuc2UpIENvcHlyaWdodCAyMDI0IEZvbnRpY29ucywgSW5jLiAtLT48cGF0aCBkPSJNNjQgMzg0YTMyIDMyIDAgMSAwIDAgNjQgMzIgMzIgMCAxIDAgMC02NHptMC0xNjBhMzIgMzIgMCAxIDAgMCA2NCAzMiAzMiAwIDEgMCAwLTY0ek05NiA5NkEzMiAzMiAwIDEgMCAzMiA5NmEzMiAzMiAwIDEgMCA2NCAweiIvPjwvc3ZnPg==);
240
+ mask-repeat: no-repeat;
241
+ mask-position: center;
242
+ mask-size: 4px;
243
+ &:hover {
244
+ mask-image: none;
245
+ }
246
+ }
247
+
248
+ .flexlayout__layout {
249
+ top: 8px;
250
+ bottom: 8px;
251
+ left: 8px;
252
+ right: 8px;
253
+ }
@@ -0,0 +1 @@
1
+ export * from './flexlayout-react-theme';
package/dist/esm/index.js CHANGED
@@ -39,6 +39,7 @@ export * from './file-upload';
39
39
  export * from './filter';
40
40
  export * from './filter-bar';
41
41
  export * from './flex-layout';
42
+ export * from './flexlayout-react-theme';
42
43
  export * from './flipper';
43
44
  export * from './flyout';
44
45
  export * from './grid-layout';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genesislcap/rapid-design-system",
3
3
  "description": "Rapid Design System",
4
- "version": "14.471.0",
4
+ "version": "14.472.0",
5
5
  "sideEffects": false,
6
6
  "license": "SEE LICENSE IN license.txt",
7
7
  "main": "dist/esm/index.js",
@@ -15,14 +15,15 @@
15
15
  "PREFIX": "rapid"
16
16
  },
17
17
  "scripts": {
18
- "build": "genx build",
19
- "build:rollup": "genx build -b rollup",
18
+ "build": "node ./scripts/generate-flexlayout-theme.mjs && genx build",
19
+ "build:rollup": "node ./scripts/generate-flexlayout-theme.mjs && genx build -b rollup",
20
20
  "build:rollup:stats": "genx analyze -b rollup",
21
21
  "circular": "npx -y madge --extensions ts --circular ./src",
22
22
  "clean": "rimraf dist temp tsconfig.tsbuildinfo",
23
23
  "dev": "npm run dev:tsc",
24
24
  "dev:rollup": "genx dev -b rollup",
25
25
  "dev:tsc": "genx dev -b ts",
26
+ "flexlayout:generate": "node ./scripts/generate-flexlayout-theme.mjs",
26
27
  "lint": "genx lint -l ox",
27
28
  "lint:fix": "genx lint -l ox --fix"
28
29
  },
@@ -35,17 +36,26 @@
35
36
  },
36
37
  "devDependencies": {
37
38
  "@genesiscommunitysuccess/analyzer-import-alias-plugin": "^5.0.3",
38
- "@genesislcap/genx": "14.471.0",
39
- "@genesislcap/rollup-builder": "14.471.0",
40
- "@genesislcap/ts-builder": "14.471.0",
41
- "@genesislcap/uvu-playwright-builder": "14.471.0",
42
- "@genesislcap/vite-builder": "14.471.0",
43
- "@genesislcap/webpack-builder": "14.471.0"
39
+ "@genesislcap/genx": "14.472.0",
40
+ "@genesislcap/rollup-builder": "14.472.0",
41
+ "@genesislcap/ts-builder": "14.472.0",
42
+ "@genesislcap/uvu-playwright-builder": "14.472.0",
43
+ "@genesislcap/vite-builder": "14.472.0",
44
+ "@genesislcap/webpack-builder": "14.472.0",
45
+ "flexlayout-react": "^0.8.19"
46
+ },
47
+ "peerDependencies": {
48
+ "flexlayout-react": "^0.8.19"
49
+ },
50
+ "peerDependenciesMeta": {
51
+ "flexlayout-react": {
52
+ "optional": true
53
+ }
44
54
  },
45
55
  "dependencies": {
46
- "@genesislcap/foundation-logger": "14.471.0",
47
- "@genesislcap/foundation-ui": "14.471.0",
48
- "@genesislcap/foundation-utils": "14.471.0",
56
+ "@genesislcap/foundation-logger": "14.472.0",
57
+ "@genesislcap/foundation-ui": "14.472.0",
58
+ "@genesislcap/foundation-utils": "14.472.0",
49
59
  "@microsoft/fast-colors": "5.3.1",
50
60
  "@microsoft/fast-components": "2.30.6",
51
61
  "@microsoft/fast-element": "1.14.0",
@@ -73,5 +83,5 @@
73
83
  "require": "./dist/react.cjs"
74
84
  }
75
85
  },
76
- "gitHead": "610c348b892f15a2c15140528863aee389801a78"
86
+ "gitHead": "9518c7fe66db1d4ceafe5555d6e9ded4dd9b249c"
77
87
  }
@@ -0,0 +1,138 @@
1
+ // @ts-check
2
+ /**
3
+ * generate-flexlayout-theme.mjs
4
+ *
5
+ * Builds the single, platform-owned flexlayout-react theme that every Foundation app
6
+ * consumes (so the override can never fall out of sync across apps).
7
+ *
8
+ * It concatenates, in order:
9
+ * 1. the VENDORED flexlayout-react base theme — `flexlayout-react/style/dark.css`
10
+ * (structural CSS + dark palette), read from the installed, pinned dependency; then
11
+ * 2. the Rapid Design System overrides — `flexlayout-react.overrides.css` (token remap +
12
+ * class tweaks). Later sheet wins at equal specificity, so the overrides take effect.
13
+ *
14
+ * The merged CSS + the resolved flexlayout-react version are written to
15
+ * `flexlayout-react-theme.generated.ts` as plain string exports (no `.css` import — the
16
+ * package builds with tsc, which cannot import CSS).
17
+ *
18
+ * Usage:
19
+ * node scripts/generate-flexlayout-theme.mjs # write the generated file
20
+ * node scripts/generate-flexlayout-theme.mjs --check # exit 1 if the file is stale
21
+ *
22
+ * The package `build` runs this in write mode, so a flexlayout-react version bump that is
23
+ * not accompanied by a regenerated theme leaves the working tree dirty and fails CI's
24
+ * "Check working tree" gate — turning silent, per-app drift into one loud build failure.
25
+ */
26
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
27
+ import { dirname, join, resolve } from 'node:path';
28
+ import { fileURLToPath } from 'node:url';
29
+
30
+ const scriptDir = dirname(fileURLToPath(import.meta.url));
31
+ const pkgRoot = resolve(scriptDir, '..');
32
+ const overridesPath = join(
33
+ pkgRoot,
34
+ 'src',
35
+ 'flexlayout-react-theme',
36
+ 'flexlayout-react.overrides.css',
37
+ );
38
+ const outPath = join(
39
+ pkgRoot,
40
+ 'src',
41
+ 'flexlayout-react-theme',
42
+ 'flexlayout-react-theme.generated.ts',
43
+ );
44
+
45
+ /**
46
+ * Locate the installed flexlayout-react package by walking up the directory tree looking
47
+ * for `node_modules/flexlayout-react`. Robust against pnpm layouts and `exports` maps that
48
+ * would otherwise block `require.resolve` of internal subpaths.
49
+ * @returns {string} absolute path to the flexlayout-react package root
50
+ */
51
+ function findFlexlayoutPackage() {
52
+ let dir = pkgRoot;
53
+ for (;;) {
54
+ const candidate = join(dir, 'node_modules', 'flexlayout-react');
55
+ if (existsSync(join(candidate, 'package.json'))) {
56
+ return candidate;
57
+ }
58
+ const parent = dirname(dir);
59
+ if (parent === dir) {
60
+ throw new Error(
61
+ 'Could not resolve `flexlayout-react`. Add it as a devDependency of ' +
62
+ '@genesislcap/rapid-design-system and run `pnpm install`.',
63
+ );
64
+ }
65
+ dir = parent;
66
+ }
67
+ }
68
+
69
+ /** Escape a raw string so it is safe inside a JS template literal. */
70
+ function escapeForTemplateLiteral(text) {
71
+ return text.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$\{/g, '\\${');
72
+ }
73
+
74
+ /** Strip the trailing `/*# sourceMappingURL=... *​/` comment and normalise whitespace. */
75
+ function stripSourceMap(css) {
76
+ return css.replace(/\/\*#\s*sourceMappingURL=[^*]*\*\/\s*$/, '').replace(/\s+$/, '');
77
+ }
78
+
79
+ function buildGeneratedFile() {
80
+ const flexlayoutPkg = findFlexlayoutPackage();
81
+ const version = JSON.parse(readFileSync(join(flexlayoutPkg, 'package.json'), 'utf8')).version;
82
+ const basePath = join(flexlayoutPkg, 'style', 'dark.css');
83
+ if (!existsSync(basePath)) {
84
+ throw new Error(`flexlayout-react base theme not found at ${basePath}`);
85
+ }
86
+
87
+ const base = stripSourceMap(readFileSync(basePath, 'utf8'));
88
+ const overrides = readFileSync(overridesPath, 'utf8').replace(/\s+$/, '');
89
+
90
+ const merged = [
91
+ `/* ============================================================================`,
92
+ ` * flexlayout-react base theme — VENDORED from flexlayout-react@${version} (style/dark.css).`,
93
+ ` * ========================================================================== */`,
94
+ base,
95
+ ``,
96
+ `/* ============================================================================`,
97
+ ` * Rapid Design System overrides (flexlayout-react.overrides.css) — applied last.`,
98
+ ` * ========================================================================== */`,
99
+ overrides,
100
+ ].join('\n');
101
+
102
+ return `/* eslint-disable */
103
+ // =============================================================================
104
+ // AUTO-GENERATED FILE — DO NOT EDIT BY HAND.
105
+ //
106
+ // Source: flexlayout-react@${version} /style/dark.css + flexlayout-react.overrides.css
107
+ // Regenerate: pnpm --filter @genesislcap/rapid-design-system flexlayout:generate
108
+ //
109
+ // The package build regenerates this; CI's "Check working tree" step fails the
110
+ // build if a flexlayout-react bump is not accompanied by a regenerated theme.
111
+ // =============================================================================
112
+
113
+ /** The flexlayout-react version this theme was generated against. */
114
+ export const RAPID_FLEXLAYOUT_REACT_VERSION = '${version}';
115
+
116
+ /** Merged flexlayout-react base theme + Rapid Design System overrides. */
117
+ export const FLEXLAYOUT_REACT_THEME_CSS = \`${escapeForTemplateLiteral(merged)}\`;
118
+ `;
119
+ }
120
+
121
+ const isCheck = process.argv.includes('--check');
122
+ const next = buildGeneratedFile();
123
+ const current = existsSync(outPath) ? readFileSync(outPath, 'utf8') : '';
124
+
125
+ if (isCheck) {
126
+ if (next !== current) {
127
+ console.error(
128
+ '✖ flexlayout-react theme is stale. Run `pnpm --filter @genesislcap/rapid-design-system flexlayout:generate` and commit the result.',
129
+ );
130
+ process.exit(1);
131
+ }
132
+ console.log('✔ flexlayout-react theme is up to date.');
133
+ } else if (next !== current) {
134
+ writeFileSync(outPath, next);
135
+ console.log(`✔ Wrote ${outPath}`);
136
+ } else {
137
+ console.log('✔ flexlayout-react theme already up to date.');
138
+ }