slicejs-web-framework 2.3.0 → 2.3.2

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
@@ -1,156 +1,155 @@
1
- <!-- Improved compatibility of back to top link: See: https://github.com/VKneider/slice.js/pull/73 -->
2
- <a name="readme-top"></a>
3
- <!--
4
- *** Thanks for checking out the slice.js. If you have a suggestion
5
- *** that would make this better, please fork the repo and create a pull request
6
- *** or simply open an issue with the tag "enhancement".
7
- *** Don't forget to give the project a star!
8
- *** Thanks again! Now go create something AMAZING! :D
9
- -->
10
-
11
-
12
-
13
- <!-- PROJECT SHIELDS -->
14
- <!--
15
- *** I'm using markdown "reference style" links for readability.
16
- *** Reference links are enclosed in brackets [ ] instead of parentheses ( ).
17
- *** See the bottom of this document for the declaration of the reference variables
18
- *** for contributors-url, forks-url, etc. This is an optional, concise syntax you may use.
19
- *** https://www.markdownguide.org/basic-syntax/#reference-style-links
20
- -->
21
- [![Contributors][contributors-shield]][contributors-url]
22
- [![Forks][forks-shield]][forks-url]
23
- [![Stargazers][stars-shield]][stars-url]
24
- [![Issues][issues-shield]][issues-url]
25
- [![MIT License][license-shield]][license-url]
26
-
27
-
28
-
29
- <!-- PROJECT LOGO -->
30
- <br />
31
- <div align="center">
32
- <a href="https://github.com/VKneider/slice.js">
33
- <img src="readme_images/Slice.js-logo.svg" alt="Logo" width="150" height="150">
34
- </a>
35
-
36
- <h3 align="center">Slice.js</h3>
37
-
38
- <p align="center">
39
- Component-Based Web Development Framework
40
- <br />
41
- <a href="https://slice-js-docs.vercel.app/Documentation"><strong>Explore the docs »</strong></a>
42
- <br />
43
- <br />
44
- <a href="https://slice-js-docs.vercel.app/">View Demo</a>
45
- ·
46
- <a href="https://github.com/VKneider/slice.js/issues/new?labels=bug&template=bug-report---.md">Report Bug</a>
47
- ·
48
- <a href="https://github.com/VKneider/slice.js/issues/new?labels=enhancement&template=feature-request---.md">Request Feature</a>
49
- </p>
50
- </div>
51
-
52
-
53
-
54
- <!-- TABLE OF CONTENTS -->
55
- <details>
56
- <summary>Table of Contents</summary>
57
- <ol>
58
- <li>
59
- <a href="#about-the-project">About The Project</a>
60
- </li>
61
- <li>
62
- <a href="#getting-started">Getting Started</a>
63
- <ul>
64
- <li><a href="#prerequisites">Prerequisites</a></li>
65
- <li><a href="#installation">Installation</a></li>
66
- </ul>
67
- </li>
68
- <li><a href="#roadmap">Roadmap</a></li>
69
- <li><a href="#contributing">Contributing</a></li>
70
- <li><a href="#license">License</a></li>
71
- <li><a href="#contact">Contact</a></li>
72
- </ol>
73
- </details>
74
-
75
-
76
-
77
- <!-- ABOUT THE PROJECT -->
78
- ## About The Project
79
-
80
- [![Product Name Screen Shot][product-screenshot]](https://slice-js-docs.vercel.app/)
81
-
82
- <p align="right">(<a href="#readme-top">back to top</a>)</p>
83
-
84
- <!-- GETTING STARTED -->
85
- ## Getting Started
86
-
87
- This is an example of how you may give instructions on setting up your project locally.
88
- To get a local copy up and running follow these simple example steps.
89
-
90
- ### Installation
91
-
92
- _Below is an example of how you can instruct your audience on installing and setting up your app. This template doesn't rely on any external dependencies or services._
93
-
94
- 1. Install slicejs cli dependencies
95
- ```sh
96
- npm i slicejs-cli
97
- ```
98
- 2. Initialize slice project
99
- ```sh
100
- npm run slice:init
101
- ```
102
- 3. Start web server
103
- ```sh
104
- npm run slice:start
105
- ```
106
-
107
- <p align="right">(<a href="#readme-top">back to top</a>)</p>
108
-
109
-
110
-
111
- <!-- ROADMAP -->
112
- ## Roadmap
113
-
114
- - [x] Add Changelog
115
- - [ ] Add Image visual component
116
- - [ ] Modify Slice Card Visual Component
117
- - [ ] Create internationalization Translator Service component.
118
-
119
- See the [open issues](https://github.com/VKneider/slice.js/issues) for a full list of proposed features (and known issues).
120
-
121
- <p align="right">(<a href="#readme-top">back to top</a>)</p>
122
-
123
-
124
-
125
- <!-- CONTRIBUTING -->
126
- ## Contributing
127
-
128
- We welcome contributions to the project! Please make sure to review the guidelines in the [CONTRIBUTING.md](docs/CONTRIBUTING.md) file before submitting any changes.
129
-
130
- <p align="right">(<a href="#readme-top">back to top</a>)</p>
131
-
132
-
133
-
134
- <!-- LICENSE -->
135
- ## License
136
-
137
- Distributed under the MIT License. See `LICENSE` for more information.
138
-
139
- <p align="right">(<a href="#readme-top">back to top</a>)</p>
140
-
141
- <!-- MARKDOWN LINKS & IMAGES -->
142
- <!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
143
- [contributors-shield]: https://img.shields.io/github/contributors/VKneider/slice.js.svg?style=for-the-badge
144
- [contributors-url]: https://github.com/VKneider/slice.js/graphs/contributors
145
- [forks-shield]: https://img.shields.io/github/forks/VKneider/slice.js.svg?style=for-the-badge
146
- [forks-url]: https://github.com/VKneider/slice.js/network/members
147
- [stars-shield]: https://img.shields.io/github/stars/VKneider/slice.js.svg?style=for-the-badge
148
- [stars-url]: https://github.com/VKneider/slice.js/stargazers
149
- [issues-shield]: https://img.shields.io/github/issues/VKneider/slice.js.svg?style=for-the-badge
150
- [issues-url]: https://github.com/VKneider/slice.js/issues
151
- [license-shield]: https://img.shields.io/github/license/VKneider/slice.js.svg?style=for-the-badge
152
- [license-url]: https://github.com/VKneider/slice.js/blob/master/LICENSE.txt
153
- [linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555
154
- [linkedin-url]: https://linkedin.com/in/VKneider
155
- [product-screenshot]: readme_images/screenshot.JPG
156
-
1
+ <!-- Improved compatibility of back to top link: See: https://github.com/VKneider/slice.js/pull/73 -->
2
+ <a name="readme-top"></a>
3
+ <!--
4
+ *** Thanks for checking out the slice.js. If you have a suggestion
5
+ *** that would make this better, please fork the repo and create a pull request
6
+ *** or simply open an issue with the tag "enhancement".
7
+ *** Don't forget to give the project a star!
8
+ *** Thanks again! Now go create something AMAZING! :D
9
+ -->
10
+
11
+
12
+
13
+ <!-- PROJECT SHIELDS -->
14
+ <!--
15
+ *** I'm using markdown "reference style" links for readability.
16
+ *** Reference links are enclosed in brackets [ ] instead of parentheses ( ).
17
+ *** See the bottom of this document for the declaration of the reference variables
18
+ *** for contributors-url, forks-url, etc. This is an optional, concise syntax you may use.
19
+ *** https://www.markdownguide.org/basic-syntax/#reference-style-links
20
+ -->
21
+ [![Contributors][contributors-shield]][contributors-url]
22
+ [![Forks][forks-shield]][forks-url]
23
+ [![Stargazers][stars-shield]][stars-url]
24
+ [![Issues][issues-shield]][issues-url]
25
+ [![MIT License][license-shield]][license-url]
26
+
27
+
28
+
29
+ <!-- PROJECT LOGO -->
30
+ <br />
31
+ <div align="center">
32
+ <a href="https://github.com/VKneider/slice.js">
33
+ <img src="readme_images/Slice.js-logo.svg" alt="Logo" width="150" height="150">
34
+ </a>
35
+
36
+ <h3 align="center">Slice.js</h3>
37
+
38
+ <p align="center">
39
+ Component-Based Web Development Framework
40
+ <br />
41
+ <a href="https://slice-js-docs.vercel.app/Documentation"><strong>Explore the docs »</strong></a>
42
+ <br />
43
+ <br />
44
+ <a href="https://slice-js-docs.vercel.app/">View Demo</a>
45
+ ·
46
+ <a href="https://github.com/VKneider/slice.js/issues/new?labels=bug&template=bug-report---.md">Report Bug</a>
47
+ ·
48
+ <a href="https://github.com/VKneider/slice.js/issues/new?labels=enhancement&template=feature-request---.md">Request Feature</a>
49
+ </p>
50
+ </div>
51
+
52
+
53
+
54
+ <!-- TABLE OF CONTENTS -->
55
+ <details>
56
+ <summary>Table of Contents</summary>
57
+ <ol>
58
+ <li>
59
+ <a href="#about-the-project">About The Project</a>
60
+ </li>
61
+ <li>
62
+ <a href="#getting-started">Getting Started</a>
63
+ <ul>
64
+ <li><a href="#prerequisites">Prerequisites</a></li>
65
+ <li><a href="#installation">Installation</a></li>
66
+ </ul>
67
+ </li>
68
+ <li><a href="#roadmap">Roadmap</a></li>
69
+ <li><a href="#contributing">Contributing</a></li>
70
+ <li><a href="#license">License</a></li>
71
+ <li><a href="#contact">Contact</a></li>
72
+ </ol>
73
+ </details>
74
+
75
+
76
+
77
+ <!-- ABOUT THE PROJECT -->
78
+ ## About The Project
79
+
80
+ [![Product Name Screen Shot][product-screenshot]](https://slice-js-docs.vercel.app/)
81
+
82
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
83
+
84
+ <!-- GETTING STARTED -->
85
+ ## Getting Started
86
+
87
+ This is an example of how you may give instructions on setting up your project locally.
88
+ To get a local copy up and running follow these simple example steps.
89
+
90
+ ### Installation
91
+
92
+ _Below is an example of how you can instruct your audience on installing and setting up your app. This template doesn't rely on any external dependencies or services._
93
+
94
+ 1. Install slicejs cli dependencies
95
+ ```sh
96
+ npm i slicejs-cli
97
+ ```
98
+ 2. Initialize slice project
99
+ ```sh
100
+ npm run slice:init
101
+ ```
102
+ 3. Start web server
103
+ ```sh
104
+ npm run slice:start
105
+ ```
106
+
107
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
108
+
109
+
110
+
111
+ <!-- ROADMAP -->
112
+ ## Roadmap
113
+
114
+ - [x] Add Changelog
115
+ - [ ] Add Image visual component
116
+ - [ ] Modify Slice Card Visual Component
117
+
118
+ See the [open issues](https://github.com/VKneider/slice.js/issues) for a full list of proposed features (and known issues).
119
+
120
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
121
+
122
+
123
+
124
+ <!-- CONTRIBUTING -->
125
+ ## Contributing
126
+
127
+ We welcome contributions to the project! Please make sure to review the guidelines in the [CONTRIBUTING.md](docs/CONTRIBUTING.md) file before submitting any changes.
128
+
129
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
130
+
131
+
132
+
133
+ <!-- LICENSE -->
134
+ ## License
135
+
136
+ Distributed under the MIT License. See `LICENSE` for more information.
137
+
138
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
139
+
140
+ <!-- MARKDOWN LINKS & IMAGES -->
141
+ <!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
142
+ [contributors-shield]: https://img.shields.io/github/contributors/VKneider/slice.js.svg?style=for-the-badge
143
+ [contributors-url]: https://github.com/VKneider/slice.js/graphs/contributors
144
+ [forks-shield]: https://img.shields.io/github/forks/VKneider/slice.js.svg?style=for-the-badge
145
+ [forks-url]: https://github.com/VKneider/slice.js/network/members
146
+ [stars-shield]: https://img.shields.io/github/stars/VKneider/slice.js.svg?style=for-the-badge
147
+ [stars-url]: https://github.com/VKneider/slice.js/stargazers
148
+ [issues-shield]: https://img.shields.io/github/issues/VKneider/slice.js.svg?style=for-the-badge
149
+ [issues-url]: https://github.com/VKneider/slice.js/issues
150
+ [license-shield]: https://img.shields.io/github/license/VKneider/slice.js.svg?style=for-the-badge
151
+ [license-url]: https://github.com/VKneider/slice.js/blob/master/LICENSE.txt
152
+ [linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555
153
+ [linkedin-url]: https://linkedin.com/in/VKneider
154
+ [product-screenshot]: readme_images/screenshot.JPG
155
+
@@ -9,6 +9,12 @@
9
9
  * - Auto-limpieza cuando componentes se destruyen
10
10
  * - Persistencia opcional en localStorage
11
11
  */
12
+ /**
13
+ * @typedef {Object} ContextOptions
14
+ * @property {boolean} [persist]
15
+ * @property {string} [storageKey]
16
+ */
17
+
12
18
  export default class ContextManager {
13
19
  constructor() {
14
20
  // Map<contextName, { state, options }>
@@ -25,9 +31,10 @@ export default class ContextManager {
25
31
 
26
32
  /**
27
33
  * Crear un nuevo contexto
28
- * @param {string} name - Nombre único del contexto
29
- * @param {Object} initialState - Estado inicial
30
- * @param {Object} options - Opciones: { persist: boolean }
34
+ * @param {string} name - Nombre unico del contexto
35
+ * @param {Object} [initialState] - Estado inicial
36
+ * @param {ContextOptions} [options] - Opciones: { persist, storageKey }
37
+ * @returns {boolean}
31
38
  *
32
39
  * @example
33
40
  * slice.context.create('auth', {
@@ -76,7 +83,7 @@ export default class ContextManager {
76
83
  /**
77
84
  * Obtener el estado actual de un contexto
78
85
  * @param {string} name - Nombre del contexto
79
- * @returns {*} Estado actual o null si no existe
86
+ * @returns {any|null} Estado actual o null si no existe
80
87
  *
81
88
  * @example
82
89
  * const auth = slice.context.getState('auth');
@@ -98,7 +105,8 @@ export default class ContextManager {
98
105
  /**
99
106
  * Actualizar el estado de un contexto
100
107
  * @param {string} name - Nombre del contexto
101
- * @param {Object|Function} updater - Nuevo estado o función (prevState) => newState
108
+ * @param {Object|Function} updater - Nuevo estado o funcion (prevState) => newState
109
+ * @returns {void}
102
110
  *
103
111
  * @example
104
112
  * // Reemplazar con objeto
@@ -107,7 +115,7 @@ export default class ContextManager {
107
115
  * user: { name: 'Juan' }
108
116
  * });
109
117
  *
110
- * // Usar función para acceder al estado anterior
118
+ * // Usar funcion para acceder al estado anterior
111
119
  * slice.context.setState('cart', (prev) => ({
112
120
  * ...prev,
113
121
  * items: [...prev.items, nuevoProducto],
@@ -153,9 +161,9 @@ export default class ContextManager {
153
161
  * Observar cambios en un contexto
154
162
  * @param {string} name - Nombre del contexto
155
163
  * @param {HTMLElement} component - Componente Slice para auto-cleanup
156
- * @param {Function} callback - Función a ejecutar cuando cambia
157
- * @param {Function} selector - Opcional. Función para seleccionar campos específicos
158
- * @returns {string} subscriptionId
164
+ * @param {(value: any) => void} callback - Funcion a ejecutar cuando cambia
165
+ * @param {(state: any) => any} [selector] - Opcional. Funcion para seleccionar campos
166
+ * @returns {string|null} subscriptionId
159
167
  *
160
168
  * @example
161
169
  * // Observar todo el estado
@@ -163,12 +171,12 @@ export default class ContextManager {
163
171
  * this.render(state);
164
172
  * });
165
173
  *
166
- * // Observar un campo específico
174
+ * // Observar un campo especifico
167
175
  * slice.context.watch('auth', this, (name) => {
168
176
  * this.$name.textContent = name;
169
177
  * }, state => state.user.name);
170
178
  *
171
- * // Observar múltiples campos
179
+ * // Observar multiples campos
172
180
  * slice.context.watch('auth', this, (data) => {
173
181
  * this.$name.textContent = data.name;
174
182
  * this.$avatar.src = data.avatar;
@@ -179,7 +187,7 @@ export default class ContextManager {
179
187
  *
180
188
  * // Valores computados
181
189
  * slice.context.watch('cart', this, (total) => {
182
- * this.$total.textContent = `$${total}`;
190
+ * this.$total.textContent = `${total}`;
183
191
  * }, state => state.items.reduce((sum, i) => sum + i.price, 0));
184
192
  */
185
193
  watch(name, component, callback, selector = null) {
@@ -265,7 +273,7 @@ export default class ContextManager {
265
273
 
266
274
  /**
267
275
  * Obtener lista de todos los contextos
268
- * @returns {Array<string>}
276
+ * @returns {string[]}
269
277
  */
270
278
  list() {
271
279
  return Array.from(this.contexts.keys());
@@ -0,0 +1,258 @@
1
+ /**
2
+ * ContextManager debug panel.
3
+ */
4
+ export default class ContextManagerDebugger extends HTMLElement {
5
+ constructor() {
6
+ super();
7
+ this.isOpen = false;
8
+ this.filterText = '';
9
+ }
10
+
11
+ /**
12
+ * Initialize panel UI.
13
+ * @returns {Promise<void>}
14
+ */
15
+ async init() {
16
+ this.innerHTML = this.renderTemplate();
17
+ slice.stylesManager.registerComponentStyles('ContextManagerDebugger', this.renderStyles());
18
+ this.cacheElements();
19
+ this.bindEvents();
20
+ this.renderList();
21
+ }
22
+
23
+ /**
24
+ * Toggle panel visibility.
25
+ * @returns {void}
26
+ */
27
+ toggle() {
28
+ this.isOpen = !this.isOpen;
29
+ this.container.classList.toggle('active', this.isOpen);
30
+ if (this.isOpen) {
31
+ this.renderList();
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Show panel.
37
+ * @returns {void}
38
+ */
39
+ open() {
40
+ this.isOpen = true;
41
+ this.container.classList.add('active');
42
+ this.renderList();
43
+ }
44
+
45
+ /**
46
+ * Hide panel.
47
+ * @returns {void}
48
+ */
49
+ close() {
50
+ this.isOpen = false;
51
+ this.container.classList.remove('active');
52
+ }
53
+
54
+ cacheElements() {
55
+ this.container = this.querySelector('#context-debugger');
56
+ this.list = this.querySelector('#context-list');
57
+ this.filterInput = this.querySelector('#context-filter');
58
+ this.countLabel = this.querySelector('#context-count');
59
+ this.refreshButton = this.querySelector('#context-refresh');
60
+ this.closeButton = this.querySelector('#context-close');
61
+ }
62
+
63
+ bindEvents() {
64
+ this.refreshButton.addEventListener('click', () => this.renderList());
65
+ this.closeButton.addEventListener('click', () => this.close());
66
+ this.filterInput.addEventListener('input', (event) => {
67
+ this.filterText = event.target.value.trim().toLowerCase();
68
+ this.renderList();
69
+ });
70
+ }
71
+
72
+ renderList() {
73
+ if (!slice?.context?.contexts) {
74
+ this.list.textContent = 'ContextManager not available.';
75
+ this.countLabel.textContent = '0';
76
+ return;
77
+ }
78
+
79
+ const items = [];
80
+ slice.context.contexts.forEach((value, name) => {
81
+ if (this.filterText && !name.toLowerCase().includes(this.filterText)) {
82
+ return;
83
+ }
84
+ const keys = value?.state ? Object.keys(value.state).length : 0;
85
+ items.push({ name, keys, state: value?.state || {} });
86
+ });
87
+
88
+ items.sort((a, b) => a.name.localeCompare(b.name));
89
+
90
+ this.countLabel.textContent = String(items.length);
91
+ this.list.innerHTML = items.length
92
+ ? items.map((item) => {
93
+ const preview = JSON.stringify(item.state, null, 2);
94
+ return `
95
+ <div class="context-row">
96
+ <div class="context-header">
97
+ <div class="context-name">${item.name}</div>
98
+ <div class="context-keys">${item.keys} keys</div>
99
+ </div>
100
+ <pre class="context-preview">${this.escapeHtml(preview)}</pre>
101
+ </div>
102
+ `;
103
+ }).join('')
104
+ : '<div class="empty">No contexts</div>';
105
+ }
106
+
107
+ escapeHtml(value) {
108
+ return value
109
+ .replace(/&/g, '&amp;')
110
+ .replace(/</g, '&lt;')
111
+ .replace(/>/g, '&gt;')
112
+ .replace(/"/g, '&quot;')
113
+ .replace(/'/g, '&#39;');
114
+ }
115
+
116
+ renderTemplate() {
117
+ return `
118
+ <div id="context-debugger">
119
+ <div class="context-header">
120
+ <div class="title">Contexts</div>
121
+ <div class="actions">
122
+ <button id="context-refresh" class="btn">Refresh</button>
123
+ <button id="context-close" class="btn">Close</button>
124
+ </div>
125
+ </div>
126
+ <div class="context-toolbar">
127
+ <input id="context-filter" type="text" placeholder="Filter contexts" />
128
+ <div class="count">Total: <span id="context-count">0</span></div>
129
+ </div>
130
+ <div class="context-list" id="context-list"></div>
131
+ </div>
132
+ `;
133
+ }
134
+
135
+ renderStyles() {
136
+ return `
137
+ #context-debugger {
138
+ position: fixed;
139
+ bottom: 20px;
140
+ left: 20px;
141
+ width: min(380px, calc(100vw - 40px));
142
+ max-height: 60vh;
143
+ background: var(--primary-background-color);
144
+ border: 1px solid var(--medium-color);
145
+ border-radius: 12px;
146
+ box-shadow: 0 16px 32px rgba(0, 0, 0, 0.15);
147
+ display: none;
148
+ flex-direction: column;
149
+ z-index: 10001;
150
+ overflow: hidden;
151
+ }
152
+
153
+ #context-debugger.active {
154
+ display: flex;
155
+ }
156
+
157
+ #context-debugger * {
158
+ box-sizing: border-box;
159
+ }
160
+
161
+ .context-header {
162
+ display: flex;
163
+ justify-content: space-between;
164
+ align-items: center;
165
+ padding: 12px 14px;
166
+ background: var(--tertiary-background-color);
167
+ border-bottom: 1px solid var(--medium-color);
168
+ }
169
+
170
+ .context-header .title {
171
+ font-weight: 600;
172
+ color: var(--font-primary-color);
173
+ }
174
+
175
+ .context-header .actions {
176
+ display: flex;
177
+ gap: 8px;
178
+ }
179
+
180
+ .context-header .btn {
181
+ padding: 6px 10px;
182
+ border-radius: 6px;
183
+ border: 1px solid var(--medium-color);
184
+ background: var(--primary-background-color);
185
+ color: var(--font-primary-color);
186
+ cursor: pointer;
187
+ font-size: 12px;
188
+ }
189
+
190
+ .context-toolbar {
191
+ display: flex;
192
+ gap: 10px;
193
+ align-items: center;
194
+ padding: 10px 12px;
195
+ border-bottom: 1px solid var(--medium-color);
196
+ }
197
+
198
+ .context-toolbar input {
199
+ flex: 1;
200
+ min-width: 0;
201
+ padding: 6px 8px;
202
+ border-radius: 6px;
203
+ border: 1px solid var(--medium-color);
204
+ background: var(--primary-background-color);
205
+ color: var(--font-primary-color);
206
+ }
207
+
208
+ .context-list {
209
+ padding: 10px 12px;
210
+ overflow: auto;
211
+ display: flex;
212
+ flex-direction: column;
213
+ gap: 10px;
214
+ }
215
+
216
+ .context-row {
217
+ border: 1px solid var(--medium-color);
218
+ border-radius: 8px;
219
+ background: var(--tertiary-background-color);
220
+ padding: 10px;
221
+ display: flex;
222
+ flex-direction: column;
223
+ gap: 6px;
224
+ }
225
+
226
+ .context-name {
227
+ font-weight: 600;
228
+ color: var(--font-primary-color);
229
+ }
230
+
231
+ .context-keys {
232
+ font-size: 12px;
233
+ color: var(--font-secondary-color);
234
+ }
235
+
236
+ .context-preview {
237
+ background: var(--primary-background-color);
238
+ border-radius: 6px;
239
+ padding: 8px;
240
+ border: 1px solid var(--medium-color);
241
+ max-height: 180px;
242
+ overflow: auto;
243
+ font-size: 11px;
244
+ font-family: monospace;
245
+ color: var(--font-primary-color);
246
+ }
247
+
248
+ .empty {
249
+ color: var(--font-secondary-color);
250
+ font-size: 12px;
251
+ text-align: center;
252
+ padding: 12px 0;
253
+ }
254
+ `;
255
+ }
256
+ }
257
+
258
+ customElements.define('slice-contextmanager-debugger', ContextManagerDebugger);