@adaptabletools/adaptable 24.0.0-canary.9 → 24.0.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.
@@ -7,7 +7,6 @@ import { formatColumnInspectorPinning, formatColumnInspectorSizing, } from './Vi
7
7
  import { getVariableColor } from './Utilities/Helpers/StyleHelper';
8
8
  import { isSummaryColorLabel, parseSummaryLabelValueString, } from './View/Wizard/SummaryColorTag';
9
9
  import { debug } from '@infinite-table/infinite-react';
10
- import { colorSchemeDark, colorSchemeLight, themeQuartz } from 'ag-grid-enterprise';
11
10
  import { warnOnce } from './agGrid/AdaptableLogger';
12
11
  let DEV_TOOLS_LISTENING_STARTED = false;
13
12
  let DEV_TOOLS_READY = false;
@@ -181,12 +180,7 @@ function ensureLogIntentListening() {
181
180
  });
182
181
  });
183
182
  }
184
- function ensureDevToolsReady() {
185
- if (DEV_TOOLS_READY) {
186
- return;
187
- }
188
- DEV_TOOLS_READY = true;
189
- console.log('Adaptable DevTools is listening for messages!');
183
+ function announceInstancesToDevTools() {
190
184
  for (const [adaptableId, registration] of INSTANCE_REGISTRATIONS) {
191
185
  if (registration.instance?.isDestroyed) {
192
186
  continue;
@@ -195,6 +189,25 @@ function ensureDevToolsReady() {
195
189
  postStateChangeMessage(adaptableId, { api: registration.api });
196
190
  }
197
191
  }
192
+ function ensureDevToolsReady() {
193
+ if (DEV_TOOLS_READY) {
194
+ return;
195
+ }
196
+ DEV_TOOLS_READY = true;
197
+ console.log('Adaptable DevTools is listening for messages!');
198
+ announceInstancesToDevTools();
199
+ }
200
+ const SEEN_CONTENT_SCRIPT_IDS = new Set();
201
+ function handleRegisterMessage(payload, devToolsWasReady) {
202
+ const contentScriptId = payload?.contentScriptId;
203
+ if (typeof contentScriptId !== 'string' || SEEN_CONTENT_SCRIPT_IDS.has(contentScriptId)) {
204
+ return;
205
+ }
206
+ SEEN_CONTENT_SCRIPT_IDS.add(contentScriptId);
207
+ if (devToolsWasReady) {
208
+ announceInstancesToDevTools();
209
+ }
210
+ }
198
211
  function handleGetColumnInfoMessage(payload) {
199
212
  const adaptableId = payload?.adaptableId;
200
213
  if (!adaptableId) {
@@ -237,182 +250,41 @@ function clearInlineAbVars(el) {
237
250
  }
238
251
  }
239
252
  }
240
- let themeAliasMaps = null;
241
- let themeAliasSheetCount = -1;
242
- function collectThemeAliases() {
243
- const sheetCount = document.styleSheets.length;
244
- if (themeAliasMaps && themeAliasSheetCount === sheetCount) {
245
- return themeAliasMaps;
246
- }
247
- const root = new Map();
248
- const dark = new Map();
249
- const visit = (rules) => {
250
- for (let index = 0; index < rules.length; index++) {
251
- const rule = rules[index];
252
- const group = rule;
253
- if (group.cssRules) {
254
- visit(group.cssRules);
255
- }
256
- const styleRule = rule;
257
- if (!styleRule.style || !styleRule.selectorText) {
258
- continue;
259
- }
260
- const selector = styleRule.selectorText;
261
- const isDark = selector.includes('ab--theme-dark');
262
- const isRoot = selector.includes(':root') ||
263
- selector.includes('ab--theme-light') ||
264
- /(^|[^\w-])html([^\w-]|$)/.test(selector);
265
- if (!isDark && !isRoot) {
266
- continue;
267
- }
268
- const target = isDark ? dark : root;
269
- for (let i = 0; i < styleRule.style.length; i++) {
270
- const prop = styleRule.style[i];
271
- if (!prop?.startsWith('--')) {
272
- continue;
273
- }
274
- const value = styleRule.style.getPropertyValue(prop).trim();
275
- if (value.includes('var(')) {
276
- target.set(prop, value);
277
- }
278
- }
279
- }
280
- };
281
- for (let index = 0; index < document.styleSheets.length; index++) {
282
- const sheet = document.styleSheets[index];
283
- try {
284
- visit(sheet.cssRules);
285
- }
286
- catch {
287
- }
288
- }
289
- themeAliasMaps = { root, dark };
290
- themeAliasSheetCount = sheetCount;
291
- return themeAliasMaps;
292
- }
293
- let darkThemeProbe = null;
294
- function themeDefaultStyle(variant) {
295
- if (variant === 'light') {
296
- return getComputedStyle(document.documentElement);
297
- }
298
- if (!darkThemeProbe) {
299
- darkThemeProbe = document.createElement('div');
300
- darkThemeProbe.className = 'ab--theme-dark';
301
- darkThemeProbe.setAttribute('data-ab-devtools-theme-probe', '');
302
- darkThemeProbe.style.cssText =
303
- 'position:absolute;width:0;height:0;overflow:hidden;pointer-events:none';
304
- document.body.appendChild(darkThemeProbe);
305
- }
306
- return getComputedStyle(darkThemeProbe);
307
- }
308
- function installLiveAliases(el, variant) {
309
- const { root, dark } = collectThemeAliases();
310
- const defaults = themeDefaultStyle(variant);
311
- const aliases = variant === 'dark' ? new Map([...root, ...dark]) : root;
312
- for (const [name, raw] of aliases) {
313
- const inline = el.style.getPropertyValue(name).trim();
314
- const fallback = defaults.getPropertyValue(name).trim();
315
- if (!inline || inline === raw || inline === fallback) {
316
- el.style.setProperty(name, raw);
317
- }
318
- }
319
- }
320
- function clearDocumentThemePreview() {
321
- clearInlineAbVars(document.documentElement);
322
- }
323
- function getInstanceThemeElements(adaptableId) {
324
- const instance = getRegistration(adaptableId)?.instance;
325
- if (!instance) {
326
- return [];
327
- }
328
- const elements = [
329
- instance.getAdaptableContainerElement(),
330
- instance.getAgGridContainerElement(),
331
- ].filter((el) => el instanceof HTMLElement);
332
- return [...new Set(elements)];
333
- }
334
- const originalAgGridThemes = new Map();
335
- function applyAgGridPreviewTheme(adaptableId, variant) {
336
- const instance = getRegistration(adaptableId)?.instance;
337
- const gridApi = instance?.agGridAdapter.getAgGridApi();
338
- if (!instance || instance.isDestroyed || !gridApi || gridApi.isDestroyed()) {
339
- return;
340
- }
341
- if (instance.agGridThemeAdapter.getAgGridThemeMode() === 'legacy') {
342
- return;
343
- }
344
- if (!originalAgGridThemes.has(adaptableId)) {
345
- originalAgGridThemes.set(adaptableId, gridApi.getGridOption('theme'));
346
- }
347
- const original = originalAgGridThemes.get(adaptableId);
348
- const base = original && original !== 'legacy' && typeof original.withPart === 'function'
349
- ? original
350
- : themeQuartz;
351
- gridApi.setGridOption('theme', base.withPart(variant === 'dark' ? colorSchemeDark : colorSchemeLight));
352
- }
353
- function syncAgGridPreviewThemes(activeId, variant) {
354
- applyAgGridPreviewTheme(activeId, variant);
253
+ function clearThemePreview() {
254
+ const root = document.documentElement;
255
+ clearInlineAbVars(root);
256
+ root.removeAttribute(THEME_PREVIEW_ATTR);
355
257
  }
356
- function applyThemeVars(el, payload) {
357
- clearInlineAbVars(el);
358
- for (const [name, value] of Object.entries(payload.light)) {
359
- if (value != null && value !== '') {
360
- el.style.setProperty(name, String(value));
361
- }
258
+ function clearThemePreviewNotMatching(variant) {
259
+ const previewVariant = document.documentElement.getAttribute(THEME_PREVIEW_ATTR);
260
+ if (previewVariant && previewVariant !== variant) {
261
+ clearThemePreview();
362
262
  }
363
- if (payload.variant === 'dark') {
364
- for (const [name, value] of Object.entries(payload.dark)) {
365
- if (value != null && value !== '') {
366
- el.style.setProperty(name, String(value));
367
- }
368
- }
369
- el.classList.add('ab--theme-dark');
370
- }
371
- else if (el.getAttribute(THEME_PREVIEW_ATTR) === 'dark') {
372
- el.classList.remove('ab--theme-dark');
373
- }
374
- el.setAttribute(THEME_PREVIEW_ATTR, payload.variant);
375
- installLiveAliases(el, payload.variant);
376
263
  }
377
264
  function handleThemeVarChangeMessage(payload) {
378
- const { name, value, adaptableId } = payload ?? {};
379
- if (!name || !adaptableId) {
265
+ const { name, value } = payload ?? {};
266
+ if (!name) {
380
267
  return;
381
268
  }
382
- const targets = getInstanceThemeElements(adaptableId);
383
- if (targets.length === 0) {
384
- console.warn(`Adaptable DevTools: no theme container for "${adaptableId}"`);
385
- return;
386
- }
387
- const variant = payload.variant === 'dark' ? 'dark' : 'light';
388
- clearDocumentThemePreview();
389
- for (const el of targets) {
390
- if (!el.hasAttribute(THEME_PREVIEW_ATTR)) {
391
- el.setAttribute(THEME_PREVIEW_ATTR, variant);
392
- }
393
- installLiveAliases(el, variant);
394
- el.style.setProperty(name, String(value ?? ''));
269
+ const root = document.documentElement;
270
+ if (!root.hasAttribute(THEME_PREVIEW_ATTR)) {
271
+ root.setAttribute(THEME_PREVIEW_ATTR, payload.variant === 'dark' ? 'dark' : 'light');
395
272
  }
273
+ root.style.setProperty(name, String(value ?? ''));
396
274
  }
397
275
  function handleApplyThemeMessage(payload) {
398
276
  if (!payload || (payload.variant !== 'light' && payload.variant !== 'dark')) {
399
277
  return;
400
278
  }
401
- const { adaptableId } = payload;
402
- if (!adaptableId) {
403
- console.warn('Adaptable DevTools: apply-theme message missing adaptableId');
404
- return;
405
- }
406
- const targets = getInstanceThemeElements(adaptableId);
407
- if (targets.length === 0) {
408
- console.warn(`Adaptable DevTools: no theme container for "${adaptableId}"`);
409
- return;
410
- }
411
- clearDocumentThemePreview();
412
- for (const el of targets) {
413
- applyThemeVars(el, payload);
279
+ const root = document.documentElement;
280
+ clearInlineAbVars(root);
281
+ const values = payload.variant === 'dark' ? { ...payload.light, ...payload.dark } : payload.light;
282
+ for (const [name, value] of Object.entries(values)) {
283
+ if (value != null && value !== '') {
284
+ root.style.setProperty(name, String(value));
285
+ }
414
286
  }
415
- syncAgGridPreviewThemes(adaptableId, payload.variant);
287
+ root.setAttribute(THEME_PREVIEW_ATTR, payload.variant);
416
288
  }
417
289
  function handleLoadVariantMessage(payload) {
418
290
  const { adaptableId, variant } = payload ?? {};
@@ -583,6 +455,9 @@ function viewItemLabel(item) {
583
455
  function serializeViewItems(items) {
584
456
  const rows = [];
585
457
  for (const item of items) {
458
+ if (!item) {
459
+ continue;
460
+ }
586
461
  const variant = item.tagVariant === 'default' ? undefined : item.tagVariant;
587
462
  const italic = item.tagClassName?.includes('italic') ? true : undefined;
588
463
  const tags = (item.values ?? [])
@@ -900,8 +775,10 @@ export function listenForDevTools(adaptableInstance) {
900
775
  if (!isMessageFromDevToolsContentScript(event.data)) {
901
776
  return;
902
777
  }
778
+ const devToolsWasReady = DEV_TOOLS_READY;
903
779
  ensureDevToolsReady();
904
780
  const handlers = {
781
+ register: (payload) => handleRegisterMessage(payload, devToolsWasReady),
905
782
  'restore-state': handleRestoreStateMessage,
906
783
  'open-settings-panel': handleOpenSettingsPanelMessage,
907
784
  'get-column-info': handleGetColumnInfoMessage,
@@ -919,6 +796,48 @@ export function listenForDevTools(adaptableInstance) {
919
796
  }
920
797
  registerAdaptableInstanceInDevTools(adaptableOptions.adaptableId, api, adaptableInstance);
921
798
  }
799
+ function readAppThemeVars() {
800
+ const root = document.documentElement;
801
+ const hadLight = root.classList.contains('ab--theme-light');
802
+ const hadDark = root.classList.contains('ab--theme-dark');
803
+ const previewStyle = root.hasAttribute(THEME_PREVIEW_ATTR) ? root.style.cssText : null;
804
+ if (previewStyle != null) {
805
+ clearInlineAbVars(root);
806
+ }
807
+ const readVariant = (variant) => {
808
+ root.classList.toggle('ab--theme-light', variant === 'light');
809
+ root.classList.toggle('ab--theme-dark', variant === 'dark');
810
+ const style = getComputedStyle(root);
811
+ const values = {};
812
+ for (let i = 0; i < style.length; i++) {
813
+ const name = style[i];
814
+ if (name.startsWith('--ab-')) {
815
+ values[name] = style.getPropertyValue(name).trim();
816
+ }
817
+ }
818
+ return values;
819
+ };
820
+ try {
821
+ return { light: readVariant('light'), dark: readVariant('dark') };
822
+ }
823
+ finally {
824
+ root.classList.toggle('ab--theme-light', hadLight);
825
+ root.classList.toggle('ab--theme-dark', hadDark);
826
+ if (previewStyle != null) {
827
+ root.style.cssText = previewStyle;
828
+ }
829
+ }
830
+ }
831
+ function getThemeVariant(api) {
832
+ const themeName = api.themeApi.getCurrentTheme();
833
+ if (themeName === 'os') {
834
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
835
+ }
836
+ const variant = api.themeApi.internalApi.isSystemTheme(themeName)
837
+ ? themeName
838
+ : api.themeApi.getCurrentThemeObject()?.Variant;
839
+ return variant === 'dark' ? 'dark' : 'light';
840
+ }
922
841
  function postMountMessage(adaptableId, api) {
923
842
  window.postMessage(buildMessageForExtension({
924
843
  type: 'mount',
@@ -927,6 +846,8 @@ function postMountMessage(adaptableId, api) {
927
846
  agGridVersion: AG_GRID_VERSION,
928
847
  ...buildInstanceSummary(api),
929
848
  settingsPanelNavigation: resolveVisibleSettingsPanelNavigationGroups(api),
849
+ appThemeVars: readAppThemeVars(),
850
+ themeVariant: getThemeVariant(api),
930
851
  }));
931
852
  }
932
853
  function cancelScheduledGridRuntimeUpdate(adaptableId) {
@@ -955,6 +876,7 @@ function postStateChangeMessage(adaptableId, options) {
955
876
  actionName: options?.actionName,
956
877
  ...buildInstanceSummary(api),
957
878
  settingsPanelNavigation: resolveVisibleSettingsPanelNavigationGroups(api),
879
+ themeVariant: getThemeVariant(api),
958
880
  }));
959
881
  if (options?.api) {
960
882
  scheduleGridRuntimeUpdate(adaptableId, options.api);
@@ -1021,6 +943,8 @@ function buildMessageForExtension(params) {
1021
943
  userName: payload?.userName,
1022
944
  primaryKey: payload?.primaryKey,
1023
945
  settingsPanelNavigation: payload?.settingsPanelNavigation,
946
+ appThemeVars: payload?.appThemeVars,
947
+ themeVariant: payload?.themeVariant,
1024
948
  },
1025
949
  };
1026
950
  }
@@ -1049,6 +973,7 @@ function buildMessageForExtension(params) {
1049
973
  userName: payload?.userName,
1050
974
  primaryKey: payload?.primaryKey,
1051
975
  settingsPanelNavigation: payload?.settingsPanelNavigation,
976
+ themeVariant: payload?.themeVariant,
1052
977
  },
1053
978
  };
1054
979
  }
@@ -1077,16 +1002,27 @@ function registerAdaptableInstanceInDevTools(adaptableId, api, adaptableInstance
1077
1002
  actions: [],
1078
1003
  unsubscribe: () => { },
1079
1004
  };
1005
+ let themeVariant = getThemeVariant(api);
1006
+ const onThemeVariantMaybeChanged = () => {
1007
+ const nextVariant = getThemeVariant(api);
1008
+ if (nextVariant === themeVariant) {
1009
+ return;
1010
+ }
1011
+ themeVariant = nextVariant;
1012
+ clearThemePreviewNotMatching(nextVariant);
1013
+ };
1080
1014
  const onStateChange = (info) => {
1081
1015
  if (isTransientReduxAction(info.actionName)) {
1082
1016
  return;
1083
1017
  }
1018
+ onThemeVariantMaybeChanged();
1084
1019
  recordAction(registration, info.actionName);
1085
1020
  if (DEV_TOOLS_READY) {
1086
1021
  postStateChangeMessage(adaptableId, { actionName: info.actionName, api });
1087
1022
  }
1088
1023
  };
1089
1024
  const onStateReloaded = () => {
1025
+ onThemeVariantMaybeChanged();
1090
1026
  recordAction(registration, 'AdaptableStateReloaded');
1091
1027
  if (DEV_TOOLS_READY) {
1092
1028
  postStateChangeMessage(adaptableId, { actionName: 'AdaptableStateReloaded', api });