@c15t/dev-tools 2.0.0-rc.8 → 2.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.
package/README.md CHANGED
@@ -77,22 +77,57 @@ devtools.destroy();
77
77
 
78
78
  ### TanStack DevTools Plugin
79
79
 
80
- Integrate with TanStack DevTools:
80
+ Integrate c15t into TanStack Devtools with the same `render: <Panel />` pattern
81
+ used by the official TanStack plugins:
81
82
 
82
83
  ```tsx
84
+ import * as React from 'react';
85
+ import { useRouter } from '@tanstack/react-router';
83
86
  import { TanStackDevtools } from '@tanstack/react-devtools';
84
- import { c15tDevtoolsPlugin } from '@c15t/dev-tools/tanstack';
87
+ import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools';
88
+ import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools';
89
+ import { c15tDevtools } from '@c15t/dev-tools/tanstack';
90
+
91
+ export function AppDevtools() {
92
+ const router = useRouter();
85
93
 
86
- function App() {
87
94
  return (
88
- <>
89
- <YourApp />
90
- <TanStackDevtools plugins={[c15tDevtoolsPlugin()]} />
91
- </>
95
+ <TanStackDevtools
96
+ plugins={[
97
+ {
98
+ name: 'TanStack Query',
99
+ render: <ReactQueryDevtoolsPanel />,
100
+ },
101
+ {
102
+ name: 'TanStack Router',
103
+ render: <TanStackRouterDevtoolsPanel router={router} />,
104
+ },
105
+ c15tDevtools({
106
+ defaultOpen: true,
107
+ }),
108
+ ]}
109
+ />
92
110
  );
93
111
  }
94
112
  ```
95
113
 
114
+ If you want full control over the plugin entry, you can also render the exported
115
+ panel component directly:
116
+
117
+ ```tsx
118
+ import { C15tTanStackDevtoolsPanel } from '@c15t/dev-tools/tanstack';
119
+
120
+ <TanStackDevtools
121
+ plugins={[
122
+ {
123
+ id: 'c15t',
124
+ name: 'c15t',
125
+ render: <C15tTanStackDevtoolsPanel namespace="c15tStore" />,
126
+ },
127
+ ]}
128
+ />
129
+ ```
130
+
96
131
  ## Console API
97
132
 
98
133
  The DevTools expose a global API for quick debugging:
@@ -184,4 +219,4 @@ You can also force dark mode:
184
219
 
185
220
  ## License
186
221
 
187
- GPL-3.0-only
222
+ Apache-2.0
package/dist/379.js CHANGED
@@ -2294,7 +2294,6 @@ function getPreferenceCenterOpener(namespace = 'c15tStore') {
2294
2294
  }
2295
2295
  return null;
2296
2296
  }
2297
- const version = '2.0.0-rc.8';
2298
2297
  const DEVTOOLS_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 446 445" aria-label="c15t">
2299
2298
  <path fill="currentColor" d="M223.178.313c39.064 0 70.732 31.668 70.732 70.732-.001 39.064-31.668 70.731-70.732 70.731-12.181 0-23.642-3.079-33.649-8.502l-55.689 55.689a70.267 70.267 0 0 1 5.574 13.441h167.531c8.695-29.217 35.762-50.523 67.804-50.523 39.064 0 70.731 31.668 70.731 70.732s-31.668 70.732-70.731 70.732c-32.042 0-59.108-21.306-67.803-50.523H139.413a70.417 70.417 0 0 1-7.888 17.396l54.046 54.046c10.893-6.851 23.786-10.815 37.605-10.815 39.064 0 70.732 31.669 70.732 70.733 0 39.064-31.668 70.731-70.732 70.731s-70.732-31.667-70.732-70.731c0-10.518 2.296-20.499 6.414-29.471l-57.78-57.78c-8.972 4.117-18.952 6.414-29.47 6.414-39.063 0-70.731-31.668-70.732-70.732 0-39.064 31.669-70.732 70.733-70.732 12.18 0 23.642 3.079 33.649 8.502l55.688-55.688c-5.423-10.007-8.502-21.469-8.502-33.65 0-39.064 31.668-70.733 70.732-70.733Zm0 343.555c-16.742 0-30.314 13.572-30.314 30.314 0 16.741 13.572 30.313 30.314 30.313s30.314-13.572 30.314-30.313c0-16.742-13.572-30.314-30.314-30.314ZM71.611 192.299c-16.742 0-30.315 13.572-30.315 30.314s13.573 30.314 30.315 30.314c16.741 0 30.313-13.572 30.313-30.314 0-16.741-13.572-30.314-30.313-30.314Zm303.138 0c-16.729 0-30.294 13.551-30.315 30.275l.001.039-.001.038c.021 16.725 13.586 30.276 30.315 30.276 16.741 0 30.313-13.572 30.313-30.314 0-16.741-13.572-30.314-30.313-30.314ZM223.178 40.73c-16.742 0-30.314 13.573-30.314 30.315s13.573 30.313 30.314 30.313c16.742 0 30.313-13.572 30.314-30.313 0-16.742-13.572-30.314-30.314-30.315Z"/>
2300
2299
  </svg>`;
@@ -2711,7 +2710,7 @@ function createPanel(options) {
2711
2710
  }
2712
2711
  }));
2713
2712
  footerElement.appendChild(renderer_span({
2714
- text: `v${version}`
2713
+ text: "v2.0.1"
2715
2714
  }));
2716
2715
  }
2717
2716
  function renderErrorState(container) {
@@ -6732,6 +6731,133 @@ function createStateCopy(state) {
6732
6731
  loadedScripts: state.loadedScripts
6733
6732
  };
6734
6733
  }
6734
+ const EMBEDDED_TABS = [
6735
+ {
6736
+ id: 'location',
6737
+ label: 'Location'
6738
+ },
6739
+ {
6740
+ id: 'policy',
6741
+ label: 'Policy'
6742
+ },
6743
+ {
6744
+ id: 'consents',
6745
+ label: 'Consents'
6746
+ },
6747
+ {
6748
+ id: "scripts",
6749
+ label: 'Scripts'
6750
+ },
6751
+ {
6752
+ id: 'iab',
6753
+ label: 'IAB'
6754
+ },
6755
+ {
6756
+ id: 'actions',
6757
+ label: 'Actions'
6758
+ },
6759
+ {
6760
+ id: 'events',
6761
+ label: 'Events'
6762
+ }
6763
+ ];
6764
+ const EMBEDDED_THEME_VARIABLES = {
6765
+ '--c15t-surface': '#1f222b',
6766
+ '--c15t-surface-hover': '#272b35',
6767
+ '--c15t-surface-muted': '#252933',
6768
+ '--c15t-border': 'rgba(255, 255, 255, 0.08)',
6769
+ '--c15t-border-hover': 'rgba(255, 255, 255, 0.16)',
6770
+ '--c15t-text': '#eef2ff',
6771
+ '--c15t-text-muted': '#99a2b3',
6772
+ '--c15t-primary': '#8b5cf6',
6773
+ '--c15t-primary-hover': '#7c3aed',
6774
+ '--c15t-text-on-primary': '#f7f3ff',
6775
+ '--c15t-shadow-sm': 'none',
6776
+ '--c15t-shadow-md': 'none',
6777
+ '--c15t-devtools-surface-elevated': '#1f222b',
6778
+ '--c15t-devtools-surface-muted': '#272b35',
6779
+ '--c15t-devtools-surface-subtle': '#181b22',
6780
+ '--c15t-devtools-border-strong': 'rgba(255, 255, 255, 0.08)',
6781
+ '--c15t-devtools-code-surface': '#15181f',
6782
+ '--c15t-devtools-accent-soft': 'rgba(139, 92, 246, 0.18)',
6783
+ '--c15t-devtools-focus-ring': '#8b5cf6',
6784
+ '--c15t-devtools-badge-success-bg': 'rgba(16, 185, 129, 0.16)',
6785
+ '--c15t-devtools-badge-error-bg': 'rgba(248, 113, 113, 0.18)',
6786
+ '--c15t-devtools-badge-warning-bg': 'rgba(251, 191, 36, 0.18)',
6787
+ '--c15t-devtools-badge-info-bg': 'rgba(96, 165, 250, 0.18)',
6788
+ '--c15t-devtools-badge-neutral-bg': 'rgba(148, 163, 184, 0.16)',
6789
+ '--c15t-devtools-embedded-tab-active-border': 'rgba(139, 92, 246, 0.55)'
6790
+ };
6791
+ function createEmbeddedTabs(options) {
6792
+ const { onTabChange, disabledTabs = [] } = options;
6793
+ let activeTab = options.activeTab;
6794
+ const buttons = new Map();
6795
+ const tabList = renderer_div({
6796
+ role: 'tablist',
6797
+ ariaLabel: 'DevTools tabs',
6798
+ style: {
6799
+ display: 'flex',
6800
+ flexWrap: 'wrap',
6801
+ gap: '0.5rem',
6802
+ alignItems: 'center',
6803
+ paddingBottom: '0.25rem',
6804
+ borderBottom: '1px solid var(--c15t-devtools-border-strong, rgba(255, 255, 255, 0.08))'
6805
+ }
6806
+ });
6807
+ function applyButtonState(tab, buttonElement) {
6808
+ const isActive = tab === activeTab;
6809
+ const isDisabled = disabledTabs.includes(tab);
6810
+ buttonElement.disabled = isDisabled;
6811
+ buttonElement.setAttribute('aria-selected', isActive ? 'true' : 'false');
6812
+ buttonElement.style.borderColor = isActive ? 'var(--c15t-devtools-embedded-tab-active-border, rgba(139, 92, 246, 0.55))' : 'transparent';
6813
+ buttonElement.style.backgroundColor = isActive ? 'var(--c15t-devtools-accent-soft, rgba(139, 92, 246, 0.18))' : 'transparent';
6814
+ buttonElement.style.color = isActive ? 'var(--c15t-text, #eef2ff)' : 'var(--c15t-text-muted, #99a2b3)';
6815
+ buttonElement.style.opacity = isDisabled ? '0.45' : '1';
6816
+ buttonElement.style.cursor = isDisabled ? 'not-allowed' : 'pointer';
6817
+ buttonElement.style.boxShadow = isActive ? 'inset 0 0 0 1px var(--c15t-devtools-embedded-tab-active-border, rgba(139, 92, 246, 0.55))' : 'none';
6818
+ }
6819
+ for (const tab of EMBEDDED_TABS){
6820
+ const buttonElement = renderer_button({
6821
+ role: 'tab',
6822
+ text: tab.label,
6823
+ onClick: ()=>{
6824
+ if (disabledTabs.includes(tab.id)) return;
6825
+ activeTab = tab.id;
6826
+ for (const [tabId, tabButton] of buttons)applyButtonState(tabId, tabButton);
6827
+ onTabChange(tab.id);
6828
+ },
6829
+ style: {
6830
+ display: 'inline-flex',
6831
+ alignItems: 'center',
6832
+ justifyContent: 'center',
6833
+ minHeight: '1.875rem',
6834
+ padding: '0.3125rem 0.75rem',
6835
+ border: '1px solid transparent',
6836
+ borderRadius: '999px',
6837
+ backgroundColor: 'transparent',
6838
+ fontFamily: 'inherit',
6839
+ fontSize: 'var(--c15t-devtools-font-size-xs, 0.75rem)',
6840
+ fontWeight: '500',
6841
+ lineHeight: '1.25',
6842
+ transition: 'background-color var(--c15t-duration-fast, 100ms) var(--c15t-easing, cubic-bezier(0.4, 0, 0.2, 1)), border-color var(--c15t-duration-fast, 100ms) var(--c15t-easing, cubic-bezier(0.4, 0, 0.2, 1)), box-shadow var(--c15t-duration-fast, 100ms) var(--c15t-easing, cubic-bezier(0.4, 0, 0.2, 1)), color var(--c15t-duration-fast, 100ms) var(--c15t-easing, cubic-bezier(0.4, 0, 0.2, 1))'
6843
+ }
6844
+ });
6845
+ if ('iab' === tab.id) buttonElement.title = 'Available when IAB TCF mode is enabled';
6846
+ applyButtonState(tab.id, buttonElement);
6847
+ buttons.set(tab.id, buttonElement);
6848
+ tabList.appendChild(buttonElement);
6849
+ }
6850
+ return {
6851
+ element: tabList,
6852
+ setActiveTab: (tab)=>{
6853
+ activeTab = tab;
6854
+ for (const [tabId, tabButton] of buttons)applyButtonState(tabId, tabButton);
6855
+ },
6856
+ destroy: ()=>{
6857
+ buttons.clear();
6858
+ }
6859
+ };
6860
+ }
6735
6861
  function scriptDebugEventToLogEntry(event) {
6736
6862
  return {
6737
6863
  type: "script",
@@ -6915,9 +7041,11 @@ function createDevTools(options = {}) {
6915
7041
  return instance;
6916
7042
  }
6917
7043
  function createDevToolsPanel(options) {
6918
- const { namespace = 'c15tStore' } = options;
7044
+ const { namespace = 'c15tStore', mode = 'standalone' } = options;
7045
+ const isEmbedded = 'embedded' === mode;
6919
7046
  let detachInstrumentation = null;
6920
7047
  let detachScriptDebug = null;
7048
+ let contentArea = null;
6921
7049
  const stateManager = createStateManager({
6922
7050
  isOpen: true
6923
7051
  });
@@ -6945,6 +7073,7 @@ function createDevToolsPanel(options) {
6945
7073
  gpc: persistedOverrides.gpc
6946
7074
  });
6947
7075
  }
7076
+ renderActivePanel();
6948
7077
  },
6949
7078
  onDisconnect: ()=>{
6950
7079
  stateManager.setConnected(false);
@@ -6952,6 +7081,7 @@ function createDevToolsPanel(options) {
6952
7081
  detachInstrumentation = null;
6953
7082
  detachScriptDebug?.();
6954
7083
  detachScriptDebug = null;
7084
+ renderActivePanel();
6955
7085
  }
6956
7086
  });
6957
7087
  const panelRenderer = createPanelRenderer({
@@ -6984,25 +7114,33 @@ function createDevToolsPanel(options) {
6984
7114
  display: 'flex',
6985
7115
  flexDirection: 'column',
6986
7116
  height: '100%',
6987
- fontFamily: 'var(--c15t-devtools-font-family)',
7117
+ boxSizing: 'border-box',
7118
+ gap: '0.75rem',
7119
+ padding: '0.75rem',
7120
+ fontFamily: 'inherit',
6988
7121
  fontSize: 'var(--c15t-devtools-font-size-sm)',
6989
- color: 'var(--c15t-devtools-text)',
6990
- backgroundColor: 'var(--c15t-devtools-surface)'
7122
+ color: isEmbedded ? 'var(--c15t-text, #eef2ff)' : 'inherit',
7123
+ backgroundColor: 'transparent',
7124
+ colorScheme: isEmbedded ? 'dark' : void 0,
7125
+ ...isEmbedded ? EMBEDDED_THEME_VARIABLES : {}
6991
7126
  }
6992
7127
  });
6993
- const contentArea = renderer_div({
7128
+ contentArea = renderer_div({
6994
7129
  style: {
6995
7130
  flex: '1',
7131
+ minHeight: '0',
6996
7132
  overflowY: 'auto',
6997
- overscrollBehavior: 'contain'
7133
+ overscrollBehavior: 'contain',
7134
+ backgroundColor: 'transparent'
6998
7135
  }
6999
7136
  });
7000
7137
  function renderActivePanel() {
7138
+ if (!contentArea) return;
7001
7139
  const activeTab = syncTabs();
7002
7140
  panelRenderer.renderPanel(contentArea, activeTab);
7003
7141
  }
7004
7142
  let tabsInstance = null;
7005
- let iabDisabled = true;
7143
+ let disabledTabsKey = '';
7006
7144
  function getDisabledTabs() {
7007
7145
  const disabledTabs = [];
7008
7146
  const storeState = storeConnector.getState();
@@ -7011,16 +7149,16 @@ function createDevToolsPanel(options) {
7011
7149
  }
7012
7150
  function syncTabs() {
7013
7151
  const disabledTabs = getDisabledTabs();
7014
- const nextIabDisabled = disabledTabs.includes('iab');
7152
+ const nextDisabledTabsKey = disabledTabs.join('|');
7015
7153
  let activeTab = stateManager.getState().activeTab;
7016
7154
  if (disabledTabs.includes(activeTab)) {
7017
7155
  activeTab = 'consents';
7018
7156
  stateManager.setActiveTab(activeTab);
7019
7157
  }
7020
- if (tabsInstance && iabDisabled === nextIabDisabled) tabsInstance.setActiveTab(activeTab);
7158
+ if (tabsInstance && disabledTabsKey === nextDisabledTabsKey) tabsInstance.setActiveTab(activeTab);
7021
7159
  else {
7022
7160
  tabsInstance?.destroy();
7023
- tabsInstance = createTabs({
7161
+ tabsInstance = createEmbeddedTabs({
7024
7162
  activeTab,
7025
7163
  onTabChange: (tab)=>{
7026
7164
  stateManager.setActiveTab(tab);
@@ -7028,8 +7166,9 @@ function createDevToolsPanel(options) {
7028
7166
  },
7029
7167
  disabledTabs
7030
7168
  });
7031
- iabDisabled = nextIabDisabled;
7032
- if (!tabsInstance.element.parentElement) container.appendChild(tabsInstance.element);
7169
+ disabledTabsKey = nextDisabledTabsKey;
7170
+ if (!tabsInstance.element.parentElement) if (contentArea?.parentElement === container) container.insertBefore(tabsInstance.element, contentArea);
7171
+ else container.appendChild(tabsInstance.element);
7033
7172
  }
7034
7173
  return activeTab;
7035
7174
  }
package/dist/index.cjs CHANGED
@@ -2348,7 +2348,6 @@ var __webpack_exports__ = {};
2348
2348
  }
2349
2349
  return null;
2350
2350
  }
2351
- const version = '2.0.0-rc.8';
2352
2351
  const DEVTOOLS_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 446 445" aria-label="c15t">
2353
2352
  <path fill="currentColor" d="M223.178.313c39.064 0 70.732 31.668 70.732 70.732-.001 39.064-31.668 70.731-70.732 70.731-12.181 0-23.642-3.079-33.649-8.502l-55.689 55.689a70.267 70.267 0 0 1 5.574 13.441h167.531c8.695-29.217 35.762-50.523 67.804-50.523 39.064 0 70.731 31.668 70.731 70.732s-31.668 70.732-70.731 70.732c-32.042 0-59.108-21.306-67.803-50.523H139.413a70.417 70.417 0 0 1-7.888 17.396l54.046 54.046c10.893-6.851 23.786-10.815 37.605-10.815 39.064 0 70.732 31.669 70.732 70.733 0 39.064-31.668 70.731-70.732 70.731s-70.732-31.667-70.732-70.731c0-10.518 2.296-20.499 6.414-29.471l-57.78-57.78c-8.972 4.117-18.952 6.414-29.47 6.414-39.063 0-70.731-31.668-70.732-70.732 0-39.064 31.669-70.732 70.733-70.732 12.18 0 23.642 3.079 33.649 8.502l55.688-55.688c-5.423-10.007-8.502-21.469-8.502-33.65 0-39.064 31.668-70.733 70.732-70.733Zm0 343.555c-16.742 0-30.314 13.572-30.314 30.314 0 16.741 13.572 30.313 30.314 30.313s30.314-13.572 30.314-30.313c0-16.742-13.572-30.314-30.314-30.314ZM71.611 192.299c-16.742 0-30.315 13.572-30.315 30.314s13.573 30.314 30.315 30.314c16.741 0 30.313-13.572 30.313-30.314 0-16.741-13.572-30.314-30.313-30.314Zm303.138 0c-16.729 0-30.294 13.551-30.315 30.275l.001.039-.001.038c.021 16.725 13.586 30.276 30.315 30.276 16.741 0 30.313-13.572 30.313-30.314 0-16.741-13.572-30.314-30.313-30.314ZM223.178 40.73c-16.742 0-30.314 13.573-30.314 30.315s13.573 30.313 30.314 30.313c16.742 0 30.313-13.572 30.314-30.313 0-16.742-13.572-30.314-30.314-30.315Z"/>
2354
2353
  </svg>`;
@@ -2765,7 +2764,7 @@ var __webpack_exports__ = {};
2765
2764
  }
2766
2765
  }));
2767
2766
  footerElement.appendChild(renderer_span({
2768
- text: `v${version}`
2767
+ text: "v2.0.1"
2769
2768
  }));
2770
2769
  }
2771
2770
  function renderErrorState(container) {
@@ -6786,6 +6785,133 @@ var __webpack_exports__ = {};
6786
6785
  loadedScripts: state.loadedScripts
6787
6786
  };
6788
6787
  }
6788
+ const EMBEDDED_TABS = [
6789
+ {
6790
+ id: 'location',
6791
+ label: 'Location'
6792
+ },
6793
+ {
6794
+ id: 'policy',
6795
+ label: 'Policy'
6796
+ },
6797
+ {
6798
+ id: 'consents',
6799
+ label: 'Consents'
6800
+ },
6801
+ {
6802
+ id: "scripts",
6803
+ label: 'Scripts'
6804
+ },
6805
+ {
6806
+ id: 'iab',
6807
+ label: 'IAB'
6808
+ },
6809
+ {
6810
+ id: 'actions',
6811
+ label: 'Actions'
6812
+ },
6813
+ {
6814
+ id: 'events',
6815
+ label: 'Events'
6816
+ }
6817
+ ];
6818
+ const EMBEDDED_THEME_VARIABLES = {
6819
+ '--c15t-surface': '#1f222b',
6820
+ '--c15t-surface-hover': '#272b35',
6821
+ '--c15t-surface-muted': '#252933',
6822
+ '--c15t-border': 'rgba(255, 255, 255, 0.08)',
6823
+ '--c15t-border-hover': 'rgba(255, 255, 255, 0.16)',
6824
+ '--c15t-text': '#eef2ff',
6825
+ '--c15t-text-muted': '#99a2b3',
6826
+ '--c15t-primary': '#8b5cf6',
6827
+ '--c15t-primary-hover': '#7c3aed',
6828
+ '--c15t-text-on-primary': '#f7f3ff',
6829
+ '--c15t-shadow-sm': 'none',
6830
+ '--c15t-shadow-md': 'none',
6831
+ '--c15t-devtools-surface-elevated': '#1f222b',
6832
+ '--c15t-devtools-surface-muted': '#272b35',
6833
+ '--c15t-devtools-surface-subtle': '#181b22',
6834
+ '--c15t-devtools-border-strong': 'rgba(255, 255, 255, 0.08)',
6835
+ '--c15t-devtools-code-surface': '#15181f',
6836
+ '--c15t-devtools-accent-soft': 'rgba(139, 92, 246, 0.18)',
6837
+ '--c15t-devtools-focus-ring': '#8b5cf6',
6838
+ '--c15t-devtools-badge-success-bg': 'rgba(16, 185, 129, 0.16)',
6839
+ '--c15t-devtools-badge-error-bg': 'rgba(248, 113, 113, 0.18)',
6840
+ '--c15t-devtools-badge-warning-bg': 'rgba(251, 191, 36, 0.18)',
6841
+ '--c15t-devtools-badge-info-bg': 'rgba(96, 165, 250, 0.18)',
6842
+ '--c15t-devtools-badge-neutral-bg': 'rgba(148, 163, 184, 0.16)',
6843
+ '--c15t-devtools-embedded-tab-active-border': 'rgba(139, 92, 246, 0.55)'
6844
+ };
6845
+ function createEmbeddedTabs(options) {
6846
+ const { onTabChange, disabledTabs = [] } = options;
6847
+ let activeTab = options.activeTab;
6848
+ const buttons = new Map();
6849
+ const tabList = renderer_div({
6850
+ role: 'tablist',
6851
+ ariaLabel: 'DevTools tabs',
6852
+ style: {
6853
+ display: 'flex',
6854
+ flexWrap: 'wrap',
6855
+ gap: '0.5rem',
6856
+ alignItems: 'center',
6857
+ paddingBottom: '0.25rem',
6858
+ borderBottom: '1px solid var(--c15t-devtools-border-strong, rgba(255, 255, 255, 0.08))'
6859
+ }
6860
+ });
6861
+ function applyButtonState(tab, buttonElement) {
6862
+ const isActive = tab === activeTab;
6863
+ const isDisabled = disabledTabs.includes(tab);
6864
+ buttonElement.disabled = isDisabled;
6865
+ buttonElement.setAttribute('aria-selected', isActive ? 'true' : 'false');
6866
+ buttonElement.style.borderColor = isActive ? 'var(--c15t-devtools-embedded-tab-active-border, rgba(139, 92, 246, 0.55))' : 'transparent';
6867
+ buttonElement.style.backgroundColor = isActive ? 'var(--c15t-devtools-accent-soft, rgba(139, 92, 246, 0.18))' : 'transparent';
6868
+ buttonElement.style.color = isActive ? 'var(--c15t-text, #eef2ff)' : 'var(--c15t-text-muted, #99a2b3)';
6869
+ buttonElement.style.opacity = isDisabled ? '0.45' : '1';
6870
+ buttonElement.style.cursor = isDisabled ? 'not-allowed' : 'pointer';
6871
+ buttonElement.style.boxShadow = isActive ? 'inset 0 0 0 1px var(--c15t-devtools-embedded-tab-active-border, rgba(139, 92, 246, 0.55))' : 'none';
6872
+ }
6873
+ for (const tab of EMBEDDED_TABS){
6874
+ const buttonElement = renderer_button({
6875
+ role: 'tab',
6876
+ text: tab.label,
6877
+ onClick: ()=>{
6878
+ if (disabledTabs.includes(tab.id)) return;
6879
+ activeTab = tab.id;
6880
+ for (const [tabId, tabButton] of buttons)applyButtonState(tabId, tabButton);
6881
+ onTabChange(tab.id);
6882
+ },
6883
+ style: {
6884
+ display: 'inline-flex',
6885
+ alignItems: 'center',
6886
+ justifyContent: 'center',
6887
+ minHeight: '1.875rem',
6888
+ padding: '0.3125rem 0.75rem',
6889
+ border: '1px solid transparent',
6890
+ borderRadius: '999px',
6891
+ backgroundColor: 'transparent',
6892
+ fontFamily: 'inherit',
6893
+ fontSize: 'var(--c15t-devtools-font-size-xs, 0.75rem)',
6894
+ fontWeight: '500',
6895
+ lineHeight: '1.25',
6896
+ transition: 'background-color var(--c15t-duration-fast, 100ms) var(--c15t-easing, cubic-bezier(0.4, 0, 0.2, 1)), border-color var(--c15t-duration-fast, 100ms) var(--c15t-easing, cubic-bezier(0.4, 0, 0.2, 1)), box-shadow var(--c15t-duration-fast, 100ms) var(--c15t-easing, cubic-bezier(0.4, 0, 0.2, 1)), color var(--c15t-duration-fast, 100ms) var(--c15t-easing, cubic-bezier(0.4, 0, 0.2, 1))'
6897
+ }
6898
+ });
6899
+ if ('iab' === tab.id) buttonElement.title = 'Available when IAB TCF mode is enabled';
6900
+ applyButtonState(tab.id, buttonElement);
6901
+ buttons.set(tab.id, buttonElement);
6902
+ tabList.appendChild(buttonElement);
6903
+ }
6904
+ return {
6905
+ element: tabList,
6906
+ setActiveTab: (tab)=>{
6907
+ activeTab = tab;
6908
+ for (const [tabId, tabButton] of buttons)applyButtonState(tabId, tabButton);
6909
+ },
6910
+ destroy: ()=>{
6911
+ buttons.clear();
6912
+ }
6913
+ };
6914
+ }
6789
6915
  function scriptDebugEventToLogEntry(event) {
6790
6916
  return {
6791
6917
  type: "script",
@@ -6969,9 +7095,11 @@ var __webpack_exports__ = {};
6969
7095
  return instance;
6970
7096
  }
6971
7097
  function createDevToolsPanel(options) {
6972
- const { namespace = 'c15tStore' } = options;
7098
+ const { namespace = 'c15tStore', mode = 'standalone' } = options;
7099
+ const isEmbedded = 'embedded' === mode;
6973
7100
  let detachInstrumentation = null;
6974
7101
  let detachScriptDebug = null;
7102
+ let contentArea = null;
6975
7103
  const stateManager = createStateManager({
6976
7104
  isOpen: true
6977
7105
  });
@@ -6999,6 +7127,7 @@ var __webpack_exports__ = {};
6999
7127
  gpc: persistedOverrides.gpc
7000
7128
  });
7001
7129
  }
7130
+ renderActivePanel();
7002
7131
  },
7003
7132
  onDisconnect: ()=>{
7004
7133
  stateManager.setConnected(false);
@@ -7006,6 +7135,7 @@ var __webpack_exports__ = {};
7006
7135
  detachInstrumentation = null;
7007
7136
  detachScriptDebug?.();
7008
7137
  detachScriptDebug = null;
7138
+ renderActivePanel();
7009
7139
  }
7010
7140
  });
7011
7141
  const panelRenderer = createPanelRenderer({
@@ -7038,25 +7168,33 @@ var __webpack_exports__ = {};
7038
7168
  display: 'flex',
7039
7169
  flexDirection: 'column',
7040
7170
  height: '100%',
7041
- fontFamily: 'var(--c15t-devtools-font-family)',
7171
+ boxSizing: 'border-box',
7172
+ gap: '0.75rem',
7173
+ padding: '0.75rem',
7174
+ fontFamily: 'inherit',
7042
7175
  fontSize: 'var(--c15t-devtools-font-size-sm)',
7043
- color: 'var(--c15t-devtools-text)',
7044
- backgroundColor: 'var(--c15t-devtools-surface)'
7176
+ color: isEmbedded ? 'var(--c15t-text, #eef2ff)' : 'inherit',
7177
+ backgroundColor: 'transparent',
7178
+ colorScheme: isEmbedded ? 'dark' : void 0,
7179
+ ...isEmbedded ? EMBEDDED_THEME_VARIABLES : {}
7045
7180
  }
7046
7181
  });
7047
- const contentArea = renderer_div({
7182
+ contentArea = renderer_div({
7048
7183
  style: {
7049
7184
  flex: '1',
7185
+ minHeight: '0',
7050
7186
  overflowY: 'auto',
7051
- overscrollBehavior: 'contain'
7187
+ overscrollBehavior: 'contain',
7188
+ backgroundColor: 'transparent'
7052
7189
  }
7053
7190
  });
7054
7191
  function renderActivePanel() {
7192
+ if (!contentArea) return;
7055
7193
  const activeTab = syncTabs();
7056
7194
  panelRenderer.renderPanel(contentArea, activeTab);
7057
7195
  }
7058
7196
  let tabsInstance = null;
7059
- let iabDisabled = true;
7197
+ let disabledTabsKey = '';
7060
7198
  function getDisabledTabs() {
7061
7199
  const disabledTabs = [];
7062
7200
  const storeState = storeConnector.getState();
@@ -7065,16 +7203,16 @@ var __webpack_exports__ = {};
7065
7203
  }
7066
7204
  function syncTabs() {
7067
7205
  const disabledTabs = getDisabledTabs();
7068
- const nextIabDisabled = disabledTabs.includes('iab');
7206
+ const nextDisabledTabsKey = disabledTabs.join('|');
7069
7207
  let activeTab = stateManager.getState().activeTab;
7070
7208
  if (disabledTabs.includes(activeTab)) {
7071
7209
  activeTab = 'consents';
7072
7210
  stateManager.setActiveTab(activeTab);
7073
7211
  }
7074
- if (tabsInstance && iabDisabled === nextIabDisabled) tabsInstance.setActiveTab(activeTab);
7212
+ if (tabsInstance && disabledTabsKey === nextDisabledTabsKey) tabsInstance.setActiveTab(activeTab);
7075
7213
  else {
7076
7214
  tabsInstance?.destroy();
7077
- tabsInstance = createTabs({
7215
+ tabsInstance = createEmbeddedTabs({
7078
7216
  activeTab,
7079
7217
  onTabChange: (tab)=>{
7080
7218
  stateManager.setActiveTab(tab);
@@ -7082,8 +7220,9 @@ var __webpack_exports__ = {};
7082
7220
  },
7083
7221
  disabledTabs
7084
7222
  });
7085
- iabDisabled = nextIabDisabled;
7086
- if (!tabsInstance.element.parentElement) container.appendChild(tabsInstance.element);
7223
+ disabledTabsKey = nextDisabledTabsKey;
7224
+ if (!tabsInstance.element.parentElement) if (contentArea?.parentElement === container) container.insertBefore(tabsInstance.element, contentArea);
7225
+ else container.appendChild(tabsInstance.element);
7087
7226
  }
7088
7227
  return activeTab;
7089
7228
  }
package/dist/react.cjs CHANGED
@@ -2347,7 +2347,6 @@ var __webpack_exports__ = {};
2347
2347
  }
2348
2348
  return null;
2349
2349
  }
2350
- const version = '2.0.0-rc.8';
2351
2350
  const DEVTOOLS_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 446 445" aria-label="c15t">
2352
2351
  <path fill="currentColor" d="M223.178.313c39.064 0 70.732 31.668 70.732 70.732-.001 39.064-31.668 70.731-70.732 70.731-12.181 0-23.642-3.079-33.649-8.502l-55.689 55.689a70.267 70.267 0 0 1 5.574 13.441h167.531c8.695-29.217 35.762-50.523 67.804-50.523 39.064 0 70.731 31.668 70.731 70.732s-31.668 70.732-70.731 70.732c-32.042 0-59.108-21.306-67.803-50.523H139.413a70.417 70.417 0 0 1-7.888 17.396l54.046 54.046c10.893-6.851 23.786-10.815 37.605-10.815 39.064 0 70.732 31.669 70.732 70.733 0 39.064-31.668 70.731-70.732 70.731s-70.732-31.667-70.732-70.731c0-10.518 2.296-20.499 6.414-29.471l-57.78-57.78c-8.972 4.117-18.952 6.414-29.47 6.414-39.063 0-70.731-31.668-70.732-70.732 0-39.064 31.669-70.732 70.733-70.732 12.18 0 23.642 3.079 33.649 8.502l55.688-55.688c-5.423-10.007-8.502-21.469-8.502-33.65 0-39.064 31.668-70.733 70.732-70.733Zm0 343.555c-16.742 0-30.314 13.572-30.314 30.314 0 16.741 13.572 30.313 30.314 30.313s30.314-13.572 30.314-30.313c0-16.742-13.572-30.314-30.314-30.314ZM71.611 192.299c-16.742 0-30.315 13.572-30.315 30.314s13.573 30.314 30.315 30.314c16.741 0 30.313-13.572 30.313-30.314 0-16.741-13.572-30.314-30.313-30.314Zm303.138 0c-16.729 0-30.294 13.551-30.315 30.275l.001.039-.001.038c.021 16.725 13.586 30.276 30.315 30.276 16.741 0 30.313-13.572 30.313-30.314 0-16.741-13.572-30.314-30.313-30.314ZM223.178 40.73c-16.742 0-30.314 13.573-30.314 30.315s13.573 30.313 30.314 30.313c16.742 0 30.313-13.572 30.314-30.313 0-16.742-13.572-30.314-30.314-30.315Z"/>
2353
2352
  </svg>`;
@@ -2764,7 +2763,7 @@ var __webpack_exports__ = {};
2764
2763
  }
2765
2764
  }));
2766
2765
  footerElement.appendChild(renderer_span({
2767
- text: `v${version}`
2766
+ text: "v2.0.1"
2768
2767
  }));
2769
2768
  }
2770
2769
  function renderErrorState(container) {
@@ -2982,7 +2981,7 @@ var __webpack_exports__ = {};
2982
2981
  icon: EVENTS_ICON
2983
2982
  }
2984
2983
  ];
2985
- function tabs_createTabs(options) {
2984
+ function createTabs(options) {
2986
2985
  const { onTabChange, disabledTabs = [] } = options;
2987
2986
  let activeTab = options.activeTab;
2988
2987
  let isOverflowMenuOpen = false;
@@ -6911,7 +6910,7 @@ var __webpack_exports__ = {};
6911
6910
  currentActiveTab = 'consents';
6912
6911
  }
6913
6912
  if (tabsInstance) tabsInstance.destroy();
6914
- tabsInstance = tabs_createTabs({
6913
+ tabsInstance = createTabs({
6915
6914
  activeTab: currentActiveTab,
6916
6915
  onTabChange: (tab)=>{
6917
6916
  stateManager.setActiveTab(tab);