@walkeros/explorer 0.0.7 โ†’ 0.3.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/README.md CHANGED
@@ -1,476 +1,748 @@
1
- # WalkerOS Explorer
1
+ # walkerOS Explorer
2
2
 
3
- Interactive code editor and preview components for walkerOS development,
4
- testing, and debugging. Built with functional factory patterns, zero external
5
- dependencies, and comprehensive TypeScript support.
3
+ Interactive React components for walkerOS documentation and exploration.
4
+ Provides ready-to-use demo components with Monaco Editor integration for live
5
+ code editing and event visualization.
6
6
 
7
- ## ๐ŸŽฏ Overview
7
+ ## Installation
8
8
 
9
- WalkerOS Explorer is a complete toolkit for building interactive development
10
- environments. It provides a set of composable components that can be used
11
- individually or combined to create powerful code editing and preview
12
- experiences.
9
+ ```bash
10
+ npm install @walkeros/explorer
11
+ ```
13
12
 
14
- ### โœจ Key Features
13
+ ## Usage
15
14
 
16
- - ๐Ÿงฉ **Functional Factory Pattern** - Clean, composable component architecture
17
- - ๐Ÿš€ **Zero Dependencies** - No external libraries except for React peer
18
- dependencies
19
- - ๐Ÿ’Ž **Full TypeScript Support** - Complete type definitions and IntelliSense
20
- - ๐ŸŽจ **Theme-aware** - Built-in light/dark theme support
21
- - ๐Ÿ“ฑ **Responsive Design** - Works on all screen sizes
22
- - โšก **High Performance** - Optimized for speed and memory efficiency
23
- - ๐Ÿงช **Fully Tested** - 101 comprehensive tests with Jest and JSDOM
15
+ ```tsx
16
+ import { MappingDemo } from '@walkeros/explorer';
17
+ import '@walkeros/explorer/styles.css';
18
+ ```
24
19
 
25
- ## ๐Ÿ“ฆ Installation
20
+ ## Architecture
26
21
 
27
- ```bash
28
- # In walkerOS monorepo (already included)
29
- npm install
22
+ Components follow atomic design principles:
30
23
 
31
- # As external dependency (future)
32
- npm install @walkeros/explorer
33
- ```
24
+ - **Atoms**: Basic UI elements (Box, Button, Header, ButtonGroup, Toggle, etc.)
25
+ - **Molecules**: Component combinations (AutoSelect, MappingEditor, TreeSidebar)
26
+ - **Organisms**: Complex components (MappingBox, CodeBox, MappingEditorTabs)
27
+ - **Demos**: Ready-to-use complete demos (MappingDemo, DestinationDemo)
34
28
 
35
- ## ๐Ÿ—๏ธ Architecture
29
+ ### Design Principles
36
30
 
37
- The explorer is built in phases, each building upon the previous:
31
+ **Component Reusability**
38
32
 
39
- ### Phase 1: Foundation
33
+ - All components are composable and reusable
34
+ - Shared components over duplicate code
35
+ - Atomic design ensures scalability
40
36
 
41
- - **Component Factory** - Base component system with lifecycle management
42
- - **Event Bus** - Global communication system
43
- - **DOM Utilities** - Safe DOM manipulation and event handling
44
- - **Performance Utilities** - Debounce, throttle, and memoization
45
- - **Syntax Highlighting** - Code syntax detection and highlighting
37
+ **No Inline Styles**
46
38
 
47
- ### Phase 2: Individual Components
39
+ - All styling via CSS classes and CSS variables
40
+ - Inline styles are forbidden
41
+ - Use CSS modules or SCSS for styling
48
42
 
49
- - **CodeEditor** - Interactive code editor with syntax highlighting
50
- - **Preview** - HTML preview with iframe sandboxing
51
- - **ResultDisplay** - Execution results with multiple result types
43
+ **Theme Support Required**
52
44
 
53
- ### Phase 3: Composite Components
45
+ - All components support light/dark themes
46
+ - Theme switching via `data-theme` attribute
47
+ - CSS variables automatically adapt
54
48
 
55
- - **LiveCode** - Combined editor and preview for live development
56
- - **EventFlow** - walkerOS event visualization and debugging
57
- - **Destination** - walkerOS destination testing and configuration
49
+ ## Components
58
50
 
59
- ## ๐Ÿš€ Quick Start
51
+ ### Demos (Ready-to-Use)
60
52
 
61
- ### Individual Components
53
+ #### MappingDemo
62
54
 
63
- ```typescript
64
- import {
65
- createCodeEditor,
66
- createPreview,
67
- createResultDisplay,
68
- } from '@walkeros/explorer';
55
+ Interactive three-panel editor: input โ†’ config โ†’ output transformation.
69
56
 
70
- // Create a code editor
71
- const editor = createCodeEditor('#editor', {
72
- language: 'javascript',
73
- value: 'console.log("Hello World");',
74
- height: '400px',
75
- onChange: (value) => console.log('Code changed:', value),
76
- });
77
-
78
- // Create a preview
79
- const preview = createPreview('#preview', {
80
- html: '<h1>Hello World</h1>',
81
- height: '400px',
82
- });
83
-
84
- // Create a results display
85
- const results = createResultDisplay('#results', {
86
- maxResults: 100,
87
- });
57
+ ```tsx
58
+ <MappingDemo
59
+ input='{"name": "example"}'
60
+ config='{"transform": "uppercase"}'
61
+ labelInput="Event"
62
+ labelConfig="Rules"
63
+ labelOutput="Result"
64
+ fn={async (input, config) => {
65
+ const data = JSON.parse(input);
66
+ const rules = JSON.parse(config);
67
+ return JSON.stringify(result, null, 2);
68
+ }}
69
+ />
88
70
  ```
89
71
 
90
- ### Composite Components
72
+ #### DestinationDemo
91
73
 
92
- ```typescript
93
- import {
94
- createLiveCode,
95
- createEventFlow,
96
- createDestination,
97
- } from '@walkeros/explorer';
74
+ Interactive destination testing with event processing and mapping. Automatically captures destination.push() calls and displays the output.
98
75
 
99
- // Live code editor with preview
100
- const liveCode = createLiveCode('#livecode', {
101
- layout: 'horizontal',
102
- showTabs: true,
103
- initialHTML: '<h1>Hello World</h1>',
104
- initialCSS: 'h1 { color: blue; }',
105
- initialJS: 'console.log("Hello");',
106
- });
107
-
108
- // Event flow visualization
109
- const eventFlow = createEventFlow('#events', {
110
- maxEvents: 1000,
111
- showMetrics: true,
112
- onEventCapture: (event) => console.log('Event:', event),
113
- });
114
-
115
- // Destination testing
116
- const destination = createDestination('#destination', {
117
- showTemplates: true,
118
- enableValidation: true,
119
- });
120
- ```
76
+ **Simple Usage** (Recommended):
121
77
 
122
- ## ๐Ÿ“š Components Reference
123
-
124
- ### CodeEditor
125
-
126
- Interactive code editor with syntax highlighting and multiple language support.
127
-
128
- ```typescript
129
- const editor = createCodeEditor(elementOrSelector, {
130
- language: 'javascript' | 'typescript' | 'html' | 'css' | 'json' | 'markdown',
131
- value: string,
132
- height: string,
133
- readOnly: boolean,
134
- onChange: (value: string, language: string) => void
135
- });
136
-
137
- // API Methods
138
- editor.getValue() // Get current code
139
- editor.setValue(code) // Set code content
140
- editor.getLanguage() // Get current language
141
- editor.setLanguage(lang) // Set programming language
142
- editor.focus() // Focus the editor
143
- editor.selectAll() // Select all content
144
- editor.insertText(text) // Insert text at cursor
145
- ```
78
+ ```tsx
79
+ import { DestinationDemo } from '@walkeros/explorer';
80
+ import { getEvent } from '@walkeros/core';
81
+ import destinationPlausible from '@walkeros/web-destination-plausible';
82
+ import { examples } from '@walkeros/web-destination-plausible';
146
83
 
147
- ### Preview
148
-
149
- HTML preview component with iframe sandboxing and error handling.
150
-
151
- ```typescript
152
- const preview = createPreview(elementOrSelector, {
153
- html: string,
154
- height: string,
155
- sandbox: boolean,
156
- showErrors: boolean,
157
- onLoad: (iframe) => void,
158
- onError: (error) => void
159
- });
160
-
161
- // API Methods
162
- preview.setHTML(html) // Set HTML content
163
- preview.getHTML() // Get current HTML
164
- preview.refresh() // Refresh preview
165
- preview.executeScript(script) // Execute script in preview
166
- preview.injectCSS(css) // Inject CSS into preview
84
+ // Attach examples to destination for auto-capture
85
+ const destination = { ...destinationPlausible, examples };
86
+
87
+ <DestinationDemo
88
+ destination={destination}
89
+ event={getEvent('order complete')}
90
+ mapping={examples.mapping.purchase}
91
+ settings={{ domain: 'elbwalker.com' }}
92
+ generic={true}
93
+ />
167
94
  ```
168
95
 
169
- ### ResultDisplay
170
-
171
- Display execution results with multiple result types and formatting.
172
-
173
- ```typescript
174
- const results = createResultDisplay(elementOrSelector, {
175
- maxResults: number,
176
- height: string,
177
- autoScroll: boolean
178
- });
179
-
180
- // API Methods
181
- results.addValue(value, label?) // Add value result
182
- results.addError(error, label?) // Add error result
183
- results.addLog(message, label?) // Add log result
184
- results.addWarning(message, label?) // Add warning result
185
- results.addInfo(message, label?) // Add info result
186
- results.clear() // Clear all results
187
- results.getResults() // Get all results
96
+ The component auto-detects `destination.examples.env.push` and uses it to capture function calls.
97
+
98
+ **Props:**
99
+ - `destination`: Destination instance with `examples.env.push` export
100
+ - `event`: walkerOS event to process
101
+ - `mapping`: Optional mapping rules (object or JSON string)
102
+ - `settings`: Destination-specific settings
103
+ - `generic`: If true, wraps mapping in `{ '*': { '*': mapping } }`
104
+ - `labelEvent`: Label for event panel (default: 'Event')
105
+ - `labelMapping`: Label for mapping panel (default: 'Mapping')
106
+ - `labelOutput`: Label for output panel (default: 'Result')
107
+
108
+ #### DestinationInitDemo
109
+
110
+ Interactive destination initialization testing. Automatically captures destination.init() calls and displays the output (script loading, configuration calls).
111
+
112
+ **Simple Usage** (Recommended):
113
+
114
+ ```tsx
115
+ import { DestinationInitDemo } from '@walkeros/explorer';
116
+ import destinationGtag from '@walkeros/web-destination-gtag';
117
+ import { examples } from '@walkeros/web-destination-gtag';
118
+
119
+ // Attach examples to destination for auto-capture
120
+ const destination = { ...destinationGtag, examples };
121
+
122
+ <DestinationInitDemo
123
+ destination={destination}
124
+ settings={{
125
+ ga4: {
126
+ measurementId: 'G-XXXXXXXXXX',
127
+ debug: false,
128
+ pageview: false,
129
+ },
130
+ }}
131
+ />
188
132
  ```
189
133
 
190
- ### LiveCode
191
-
192
- Combined code editor and preview for live HTML/CSS/JS development.
193
-
194
- ```typescript
195
- const liveCode = createLiveCode(elementOrSelector, {
196
- layout: 'horizontal' | 'vertical' | 'tabs',
197
- showTabs: boolean,
198
- showResults: boolean,
199
- autoRun: boolean,
200
- initialHTML: string,
201
- initialCSS: string,
202
- initialJS: string,
203
- enableConsoleCapture: boolean,
204
- onRun: (code) => void
205
- });
206
-
207
- // API Methods
208
- liveCode.getHTML() // Get HTML content
209
- liveCode.setHTML(html) // Set HTML content
210
- liveCode.getCSS() // Get CSS content
211
- liveCode.setCSS(css) // Set CSS content
212
- liveCode.getJS() // Get JavaScript content
213
- liveCode.setJS(js) // Set JavaScript content
214
- liveCode.run() // Execute code manually
215
- liveCode.clear() // Clear all editors
216
- liveCode.setLayout(layout) // Change layout
134
+ The component auto-detects `destination.examples.env.init` and uses it to capture function calls during initialization.
135
+
136
+ **Props:**
137
+ - `destination`: Destination instance with `examples.env.init` export
138
+ - `settings`: Destination-specific settings (object or JSON string)
139
+ - `labelSettings`: Label for settings panel (default: 'Settings')
140
+ - `labelOutput`: Label for output panel (default: 'Result')
141
+
142
+ **Use Cases:**
143
+ - Testing destination initialization (script loading, gtag config calls)
144
+ - Documenting initialization behavior
145
+ - Debugging destination setup
146
+
147
+ #### PromotionPlayground
148
+
149
+ Interactive playground for walkerOS promotion events (used in documentation).
150
+
151
+ ### Organisms
152
+
153
+ #### MappingBox
154
+
155
+ Visual mapping configuration editor with code view toggle.
156
+
157
+ ```tsx
158
+ import { MappingBox } from '@walkeros/explorer';
159
+
160
+ <MappingBox
161
+ mapping={{
162
+ product: {
163
+ view: { name: 'view_item', data: { map: { value: 'data.price' } } },
164
+ },
165
+ }}
166
+ onMappingChange={setMapping}
167
+ label="GA4 Mapping"
168
+ useNewEditor={true}
169
+ showTree={true}
170
+ />;
217
171
  ```
218
172
 
219
- ### EventFlow
220
-
221
- WalkerOS event visualization and debugging component.
222
-
223
- ```typescript
224
- const eventFlow = createEventFlow(elementOrSelector, {
225
- maxEvents: number,
226
- showTimeline: boolean,
227
- showFilters: boolean,
228
- showMetrics: boolean,
229
- groupByEntity: boolean,
230
- onEventCapture: (event) => void,
231
- onEventSelect: (event) => void
232
- });
233
-
234
- // API Methods
235
- eventFlow.addEvent(event) // Add new event
236
- eventFlow.getEvents() // Get all events
237
- eventFlow.clearEvents() // Clear all events
238
- eventFlow.filterEvents(filter) // Filter events
239
- eventFlow.exportEvents() // Export filtered events
240
- eventFlow.getMetrics() // Get performance metrics
173
+ Features:
174
+
175
+ - Visual/Code view toggle
176
+ - Tab-based navigation
177
+ - Tree sidebar with breadcrumbs
178
+ - Property-focused editing panels
179
+ - RJSF-based forms with custom widgets
180
+
181
+ #### MappingEditorTabs
182
+
183
+ Advanced tab-based mapping editor with tree navigation.
184
+
185
+ ```tsx
186
+ import { MappingEditorTabs } from '@walkeros/explorer';
187
+
188
+ <MappingEditorTabs
189
+ initialMapping={config}
190
+ onChange={handleChange}
191
+ layout="responsive"
192
+ showTree={true}
193
+ />;
241
194
  ```
242
195
 
243
- ### Destination
244
-
245
- WalkerOS destination testing and configuration component.
246
-
247
- ```typescript
248
- const destination = createDestination(elementOrSelector, {
249
- initialConfig: DestinationConfig,
250
- showTemplates: boolean,
251
- showTesting: boolean,
252
- enableValidation: boolean,
253
- onConfigChange: (config) => void,
254
- onTest: (config, event) => void
255
- });
256
-
257
- // API Methods
258
- destination.getConfig() // Get current configuration
259
- destination.setConfig(config) // Set configuration
260
- destination.testDestination(event) // Test with event
261
- destination.validateConfig() // Validate configuration
262
- destination.exportConfig() // Export config as JSON
263
- destination.importConfig(json) // Import config from JSON
264
- destination.loadTemplate(name) // Load predefined template
265
- destination.getAvailableTemplates() // Get available templates
196
+ Layouts:
197
+
198
+ - `compact`: Single column, mobile-optimized (< 800px)
199
+ - `medium`: Two columns with collapsible sidebar (800-1200px)
200
+ - `wide`: Three columns with persistent sidebar (> 1200px)
201
+ - `responsive`: Auto-detects based on viewport
202
+
203
+ #### LiveCode
204
+
205
+ Generic live code execution with input/config/output panels.
206
+
207
+ ```tsx
208
+ <LiveCode
209
+ input={{ name: 'test event', data: {} }}
210
+ config={{ mapping: 'rules' }}
211
+ fn={async (input, config, log) => {
212
+ log('Processing...', input);
213
+ }}
214
+ fnName="myFunction"
215
+ />
266
216
  ```
267
217
 
268
- ## ๐Ÿงช Testing
218
+ #### CodePanel
269
219
 
270
- The project includes comprehensive testing with Jest and JSDOM:
220
+ Monaco editor with label and formatting controls.
271
221
 
272
- ```bash
273
- # Run all tests
274
- npm run test
222
+ ```tsx
223
+ <CodePanel
224
+ label="Configuration"
225
+ value='{"key": "value"}'
226
+ language="json"
227
+ onChange={setValue}
228
+ />
229
+ ```
275
230
 
276
- # Run tests in watch mode
277
- npm run test:watch
231
+ #### BrowserBox
278
232
 
279
- # Run specific test file
280
- npm run test foundation.test.ts
233
+ Multi-tab code editor (HTML/CSS/JS) with live preview.
281
234
 
282
- # Run tests with coverage
283
- npm run test:coverage
235
+ ```tsx
236
+ <BrowserBox
237
+ html="<div>Hello</div>"
238
+ css="div { color: red; }"
239
+ js="console.log('loaded')"
240
+ onHtmlChange={setHtml}
241
+ showPreview={true}
242
+ initialTab="preview"
243
+ />
284
244
  ```
285
245
 
286
- ### Test Coverage
246
+ #### CollectorBox
247
+
248
+ Displays collector processing with mapping and destination output.
287
249
 
288
- - **101 total tests** across 4 test suites
289
- - **Foundation tests (27)** - Core utilities and base components
290
- - **Phase 2 tests (47)** - Individual component functionality
291
- - **Phase 3 tests (27)** - Composite component integration
292
- - **Quick tests** - Fast smoke tests for CI/CD
250
+ ```tsx
251
+ <CollectorBox
252
+ event='{"name": "page view"}'
253
+ mapping='{"page": {"view": {"name": "pageview"}}}'
254
+ destination={destination}
255
+ />
256
+ ```
293
257
 
294
- ## ๐ŸŽจ Demos
258
+ ### Molecules
295
259
 
296
- Interactive demos are included to showcase all components:
260
+ #### CodeEditor
297
261
 
298
- ### Phase 2 Demo
262
+ Monaco Editor wrapper.
299
263
 
300
- ```bash
301
- # Serves demo-phase2.html
302
- npm run demo:phase2
264
+ ```tsx
265
+ <CodeEditor
266
+ value="console.log('hello')"
267
+ language="javascript"
268
+ onChange={setValue}
269
+ />
303
270
  ```
304
271
 
305
- Features individual components with interactive controls.
272
+ #### Preview
306
273
 
307
- ### Phase 3 Demo
274
+ HTML preview in isolated iframe with walkerOS event capture.
308
275
 
309
- ```bash
310
- # Serves demo-phase3.html
311
- npm run demo:phase3
276
+ ```tsx
277
+ <Preview
278
+ html="<div data-elb='product'>Item</div>"
279
+ css="div { padding: 20px; }"
280
+ onEvent={(event) => console.log(event)}
281
+ />
312
282
  ```
313
283
 
314
- Features composite components with real-world examples.
284
+ #### MappingTreeSidebar
315
285
 
316
- ## ๐Ÿ”ง Development
286
+ Hierarchical tree view for mapping navigation.
317
287
 
318
- ### Project Structure
288
+ ```tsx
289
+ import { MappingTreeSidebar } from '@walkeros/explorer';
319
290
 
291
+ <MappingTreeSidebar
292
+ config={mappingConfig}
293
+ currentPath={['product', 'view']}
294
+ expandedPaths={expandedPaths}
295
+ visible={true}
296
+ onToggle={handleToggle}
297
+ onNavigate={handleNavigate}
298
+ onAddAction={handleAddAction}
299
+ onAddEntity={handleAddEntity}
300
+ />;
320
301
  ```
321
- src/
322
- โ”œโ”€โ”€ core/ # Foundation components
323
- โ”‚ โ”œโ”€โ”€ Component.ts # Base component factory
324
- โ”‚ โ””โ”€โ”€ EventBus.ts # Global event system
325
- โ”œโ”€โ”€ components/ # All components
326
- โ”‚ โ”œโ”€โ”€ CodeEditor.ts # Code editor component
327
- โ”‚ โ”œโ”€โ”€ Preview.ts # HTML preview component
328
- โ”‚ โ”œโ”€โ”€ ResultDisplay.ts # Results display component
329
- โ”‚ โ”œโ”€โ”€ LiveCode.ts # Live coding component
330
- โ”‚ โ”œโ”€โ”€ EventFlow.ts # Event visualization component
331
- โ”‚ โ””โ”€โ”€ Destination.ts # Destination testing component
332
- โ”œโ”€โ”€ utils/ # Utility functions
333
- โ”‚ โ”œโ”€โ”€ dom.ts # DOM manipulation utilities
334
- โ”‚ โ”œโ”€โ”€ debounce.ts # Performance utilities
335
- โ”‚ โ””โ”€โ”€ syntax.ts # Syntax highlighting
336
- โ””โ”€โ”€ __tests__/ # Test suites
337
- โ”œโ”€โ”€ foundation.test.ts
338
- โ”œโ”€โ”€ phase2-components.test.ts
339
- โ””โ”€โ”€ phase3-composites.test.ts
302
+
303
+ #### AutoSelect
304
+
305
+ Dropdown with autocomplete for key selection.
306
+
307
+ ```tsx
308
+ import { AutoSelect } from '@walkeros/explorer';
309
+
310
+ <AutoSelect
311
+ value={selectedKey}
312
+ options={['data.id', 'data.name', 'user.email']}
313
+ onChange={setValue}
314
+ placeholder="Select property..."
315
+ />;
340
316
  ```
341
317
 
342
- ### Build System
318
+ ### Atoms
343
319
 
344
- ```bash
345
- # Development build with watch
346
- npm run dev
320
+ #### Box, Header, Button, ButtonGroup
347
321
 
348
- # Production build
349
- npm run build
322
+ Basic UI building blocks. See exported types for prop details.
350
323
 
351
- # Type checking
352
- npm run type-check
324
+ ```tsx
325
+ import { Box, Button, ButtonGroup } from '@walkeros/explorer';
353
326
 
354
- # Linting
355
- npm run lint
327
+ <Box header="Title" resizable={true}>
328
+ <ButtonGroup
329
+ buttons={[
330
+ { label: 'Option 1', value: '1', active: true },
331
+ { label: 'Option 2', value: '2', active: false },
332
+ ]}
333
+ onButtonClick={handleClick}
334
+ />
335
+ </Box>;
356
336
  ```
357
337
 
358
- The project uses:
338
+ #### Toggle
339
+
340
+ Theme-aware toggle switch component.
359
341
 
360
- - **tsup** for building with multiple output formats (ESM, CJS, IIFE)
361
- - **TypeScript** for type safety and IntelliSense
362
- - **Jest** with JSDOM for testing
363
- - **ESLint** for code quality
342
+ ```tsx
343
+ import { Toggle } from '@walkeros/explorer';
364
344
 
365
- ## ๐ŸŽฏ Use Cases
345
+ <Toggle checked={isEnabled} onChange={setIsEnabled} label="Enable feature" />;
346
+ ```
366
347
 
367
- ### Development Tools
348
+ ### Helpers
368
349
 
369
- Create interactive code playgrounds and documentation with live examples.
350
+ #### Destination Creators
370
351
 
371
- ```typescript
372
- const playground = createLiveCode('#playground', {
373
- layout: 'horizontal',
374
- initialHTML: '<div>Interactive example</div>',
375
- onRun: (code) => console.log('Code executed:', code),
376
- });
352
+ ```tsx
353
+ import {
354
+ createGtagDestination,
355
+ createFbqDestination,
356
+ createPlausibleDestination,
357
+ } from '@walkeros/explorer';
358
+
359
+ const gtag = createGtagDestination();
360
+ gtag.env = { elb: (output) => console.log(output) };
377
361
  ```
378
362
 
379
- ### Event Debugging
363
+ ## Styling
364
+
365
+ **Complete styling documentation:** [STYLE.md](./STYLE.md)
380
366
 
381
- Monitor and debug walkerOS events in real-time.
367
+ ### Quick Start
382
368
 
383
- ```typescript
384
- const debugger = createEventFlow('#debugger', {
385
- showMetrics: true,
386
- onEventCapture: (event) => {
387
- console.log('Event captured:', event);
388
- // Send to analytics, log to server, etc.
389
- }
390
- });
369
+ ```tsx
370
+ import '@walkeros/explorer/styles.css';
391
371
  ```
392
372
 
393
- ### Destination Testing
373
+ ```html
374
+ <!-- Theme switching -->
375
+ <html data-theme="dark">...</html>
376
+ ```
394
377
 
395
- Test and configure walkerOS destinations with built-in templates.
378
+ ### Customization
396
379
 
397
- ```typescript
398
- const tester = createDestination('#tester', {
399
- showTemplates: true,
400
- onTest: (config, event) => {
401
- console.log('Testing destination:', config.name);
402
- },
403
- });
380
+ ```css
381
+ .my-app .elb-explorer {
382
+ --color-button-primary: #ff6b35;
383
+ --bg-box: #fafafa;
384
+ --font-size-base: 16px;
385
+ }
404
386
  ```
405
387
 
406
- ## ๐Ÿ“– Documentation
388
+ **See [STYLE.md](./STYLE.md) for:**
389
+ - Complete Theme Variables Reference (all CSS variables)
390
+ - Grid System (height modes, implementation)
391
+ - Monaco Editor (theming, tokens, IntelliSense)
392
+ - SCSS Architecture & Design Rules
393
+ - Common Tasks & Troubleshooting
394
+
395
+ ### Component Styling Guidelines
396
+
397
+ When contributing components:
407
398
 
408
- - **[API Reference](./API.md)** - Complete API documentation
409
- - **[Testing Guide](./TESTING.md)** - Testing strategy and best practices
410
- - **[Development Guidelines](./DEVELOPMENT_GUIDELINES.md)** - Development best
411
- practices
399
+ **โœ… DO:**
412
400
 
413
- ## ๐ŸŒŸ Key Benefits
401
+ - Use CSS classes with the `elb-` prefix
402
+ - Use CSS variables for colors, spacing, typography
403
+ - Support both light and dark themes
404
+ - Use responsive design patterns
405
+ - Reuse existing components and styles
414
406
 
415
- ### For Developers
407
+ **โŒ DON'T:**
416
408
 
417
- - **Zero Learning Curve** - Familiar functional patterns
418
- - **Full TypeScript Support** - Complete IntelliSense and type safety
419
- - **Composable Architecture** - Use individual components or combine them
420
- - **Performance Optimized** - Debounced updates and efficient rendering
409
+ - Use inline `style` attributes
410
+ - Hardcode colors or spacing values
411
+ - Create duplicate components
412
+ - Use theme-specific selectors in component files
413
+ - Use magic numbers (use CSS variables instead)
421
414
 
422
- ### For Teams
415
+ ### SCSS Architecture (CRITICAL - Must Follow Exactly)
423
416
 
424
- - **Consistent Architecture** - Functional factory pattern across all components
425
- - **Comprehensive Testing** - High test coverage with automated CI/CD
426
- - **Documentation** - Complete API docs and usage examples
427
- - **Maintenance** - Clean, well-organized codebase
417
+ **IMPORTANCE**: The explorer uses a strict, modular SCSS architecture. All new
418
+ components MUST follow the established patterns. Non-compliance breaks the
419
+ design system.
428
420
 
429
- ### For Projects
421
+ **Architecture:**
430
422
 
431
- - **Framework Agnostic** - Works with any framework or vanilla JS
432
- - **Theme Support** - Built-in light/dark mode compatibility
433
- - **Responsive Design** - Works on desktop, tablet, and mobile
434
- - **Accessibility** - ARIA support and keyboard navigation
423
+ ```
424
+ src/styles/
425
+ โ”œโ”€โ”€ index.scss # Main entry point (import new components here)
426
+ โ”œโ”€โ”€ theme/
427
+ โ”‚ โ”œโ”€โ”€ _tokens.scss # SCSS tokens ($spacing-md: 12px, $radius-sm: 3px)
428
+ โ”‚ โ”œโ”€โ”€ _variables.scss # CSS variables (--bg-input, --color-text, etc.)
429
+ โ”‚ โ””โ”€โ”€ _dark.scss # Dark theme overrides
430
+ โ”œโ”€โ”€ foundation/
431
+ โ”‚ โ”œโ”€โ”€ _reset.scss
432
+ โ”‚ โ”œโ”€โ”€ _typography.scss
433
+ โ”‚ โ”œโ”€โ”€ _layout.scss # Grid/flex mixins
434
+ โ”‚ โ”œโ”€โ”€ _spacing.scss # Spacing mixins
435
+ โ”‚ โ””โ”€โ”€ _responsive.scss # Breakpoint mixins
436
+ โ””โ”€โ”€ components/
437
+ โ”œโ”€โ”€ atoms/ # _button.scss, _consent-widget.scss, etc.
438
+ โ”œโ”€โ”€ molecules/ # _rjsf-form.scss, _mapping-editor.scss, etc.
439
+ โ””โ”€โ”€ organisms/ # _box.scss, _mapping-box.scss, etc.
440
+ ```
441
+
442
+ #### SCSS Compliance Rules (MANDATORY)
443
+
444
+ **โœ… DO:**
445
+
446
+ 1. **Use ONLY defined CSS variables** from `theme/_variables.scss`:
447
+ - `--bg-input`, `--border-input`, `--radius-button` (standard form elements)
448
+ - `--color-text`, `--color-text-muted`, `--color-text-label` (typography)
449
+ - `--font-family-base`, `--font-mono` (fonts)
450
+ - `--font-size-base` (base font size)
451
+ 2. **Use `calc()` for font size variations**:
452
+ - Small text: `calc(var(--font-size-base) - 1px)` (NOT `--font-size-sm`)
453
+ - Tiny text: `calc(var(--font-size-base) - 2px)` (NOT `--font-size-xs`)
454
+ 3. **Follow BEM naming**: `elb-{component}-{element}--{modifier}`
455
+ - Example: `.elb-settings-widget-wrapper`, `.elb-settings-widget-form`
456
+ 4. **Use standard gaps**: `12px` for vertical spacing in flex/grid layouts
457
+ 5. **One file per component**: Create `_component-name.scss` in appropriate
458
+ directory
459
+ 6. **Import alphabetically**: Add `@use './components/atoms/your-widget';` in
460
+ `index.scss`
461
+
462
+ **โŒ DON'T:**
463
+
464
+ 1. **NEVER use undefined CSS variables**:
465
+ - โŒ `--bg-secondary`, `--bg-code`, `--border-subtle`, `--radius-base` (don't
466
+ exist)
467
+ - โŒ `--font-size-sm`, `--font-size-xs` (don't exist as CSS variables)
468
+ - โŒ `--font-family-mono` (should be `--font-mono`)
469
+ 2. **NEVER hardcode values** that have CSS variable equivalents
470
+ 3. **NEVER skip the wrapper pattern**: All widgets need `elb-rjsf-widget` โ†’
471
+ `elb-{name}-widget-wrapper`
472
+ 4. **NEVER create duplicate styles** - check existing components first
473
+
474
+ #### CSS Variable Reference (Commonly Used)
475
+
476
+ ```scss
477
+ // Backgrounds
478
+ --bg-input: #ffffff; // Form inputs, fallback containers
479
+ --bg-input-hover: #f9f9f9; // Hover states
480
+
481
+ // Borders
482
+ --border-input: #d1d5db; // Form inputs, containers
483
+ --border-input-focus: #3b82f6; // Focus states
484
+
485
+ // Border Radius
486
+ --radius-button: 3px; // Forms, small elements
487
+ --radius-box: 4px; // Boxes, containers
488
+
489
+ // Typography
490
+ --color-text: #000; // Primary text
491
+ --color-text-muted: #666; // Secondary/hint text
492
+ --color-text-label: #424242; // Labels
493
+ --font-family-base: system-ui, ...; // Body text
494
+ --font-mono: 'SF Mono', ...; // Code blocks
495
+ --font-size-base: 14px; // Base size
496
+
497
+ // Buttons
498
+ --color-button-primary: #3b82f6; // Primary actions
499
+ --color-button-danger: #ef4444; // Destructive actions
500
+ ```
501
+
502
+ **Full list**: See `src/styles/theme/_variables.scss`
503
+
504
+ #### Example: Widget SCSS (Correct Pattern)
505
+
506
+ ```scss
507
+ // _my-widget.scss
508
+ .elb-my-widget-wrapper {
509
+ width: 100%;
510
+ }
511
+
512
+ .elb-my-widget-form {
513
+ display: flex;
514
+ flex-direction: column;
515
+ gap: 12px; // Standard gap
516
+ }
517
+
518
+ .elb-my-widget-hint {
519
+ font-size: calc(var(--font-size-base) - 1px); // โœ… Correct
520
+ color: var(--color-text-muted); // โœ… Defined variable
521
+ margin: 0;
522
+ }
523
+
524
+ .elb-my-widget-code {
525
+ padding: 12px;
526
+ background-color: var(--bg-input); // โœ… Defined variable
527
+ border: 1px solid var(--border-input); // โœ… Defined variable
528
+ border-radius: var(--radius-button); // โœ… Defined variable
529
+ font-family: var(--font-mono); // โœ… Correct variable name
530
+ }
531
+ ```
532
+
533
+ #### Verification Checklist
534
+
535
+ Before submitting SCSS changes:
536
+
537
+ - [ ] All CSS variables exist in `theme/_variables.scss`
538
+ - [ ] No hardcoded colors, spacing, or font sizes (use CSS variables)
539
+ - [ ] BEM naming convention followed (`elb-{component}-{element}`)
540
+ - [ ] File imported in `index.scss` (alphabetical order)
541
+ - [ ] Build succeeds: `npm run build`
542
+ - [ ] Component matches pattern of similar existing components
543
+ - [ ] Tested in both light and dark themes
544
+
545
+ See [LAYOUT.md](./LAYOUT.md) for the complete SCSS migration plan.
546
+
547
+ ## Development
548
+
549
+ ```bash
550
+ npm install # Install dependencies
551
+ npm run start # Start Vite dev server
552
+ npm test # Run tests
553
+ npm run build # Build package
554
+ npm run lint # Lint code
555
+ ```
556
+
557
+ ### Contributing Components
558
+
559
+ Follow these principles when creating new components:
560
+
561
+ 1. **Atomic Design**: Place components in correct directory
562
+ (atoms/molecules/organisms)
563
+ 2. **Reusability**: Extract shared logic into hooks, shared styles into SCSS
564
+ modules
565
+ 3. **Theme Support**: Use CSS variables, test both light/dark themes
566
+ 4. **No Inline Styles**: All styling via CSS classes
567
+ 5. **TypeScript**: Strict typing, export all public types
568
+ 6. **Accessibility**: Semantic HTML, ARIA attributes, keyboard navigation
569
+ 7. **RJSF Patterns**: Follow Field/Widget separation for RJSF components (see
570
+ [PATTERNS.md](./PATTERNS.md))
571
+
572
+ ### RJSF Component Architecture (CRITICAL)
573
+
574
+ **When creating RJSF custom components, you MUST follow the Field/Widget
575
+ separation pattern.**
576
+
577
+ See [PATTERNS.md](./PATTERNS.md) for comprehensive documentation of:
578
+
579
+ - **Field/Widget Separation**: Mandatory two-layer architecture
580
+ - **Component Composition**: MappingCollapsible, MappingFormWrapper, IconButton
581
+ - **State Management**: Controlled state, external sync, deduplication
582
+ - **Data Flow**: Schema passing via `ui:options`, props threading
583
+ - **CSS Conventions**: BEM with `elb-` prefix
584
+ - **Common Utilities**: `cleanFormData`, type guards, validators
585
+ - **Anti-Patterns**: What NOT to do (with examples)
586
+
587
+ **Quick Reference - All RJSF Components:**
588
+
589
+ | Field | Widget | Purpose |
590
+ | ----------------------- | ------------------------ | ------------------------- |
591
+ | `MappingConsentField` | `MappingConsentWidget` | Consent states (checkbox) |
592
+ | `MappingConditionField` | `MappingConditionWidget` | Condition code editor |
593
+ | `MappingDataField` | `MappingDataWidget` | Data transformation rows |
594
+ | `MappingGlobalsField` | `MappingGlobalsWidget` | Global properties |
595
+ | `MappingContextField` | `MappingContextWidget` | Context properties |
596
+ | `MappingNestedField` | `MappingNestedWidget` | Nested entities |
597
+ | `MappingSettingsField` | `MappingSettingsWidget` | Destination settings |
598
+
599
+ **Field responsibilities** (~20 lines):
600
+
601
+ - Convert `FieldProps` โ†’ `WidgetProps`
602
+ - Pass through props (id, value, onChange, schema, uiSchema, rawErrors,
603
+ disabled, readonly)
604
+ - No UI logic
605
+
606
+ **Widget responsibilities** (100-300 lines):
607
+
608
+ - Implement full UI using standard building blocks
609
+ - Manage component state (expand/collapse, show/hide, previous values)
610
+ - Handle form changes and cleanup
611
+ - Sync with external value changes via `useEffect`
612
+ - Use `MappingCollapsible` for toggle/checkbox UI
613
+ - Use `MappingFormWrapper` for nested forms
614
+ - Use `IconButton` for actions
615
+ - Use `cleanFormData` to remove empty values
616
+
617
+ See [PATTERNS.md](./PATTERNS.md) for detailed examples and implementation
618
+ checklist.
619
+
620
+ ### Component Checklist
621
+
622
+ **Before submitting any component:**
623
+
624
+ - [ ] Component placed in correct atomic layer (atoms/molecules/organisms)
625
+ - [ ] TypeScript types exported from component file
626
+ - [ ] **SCSS compliance verified** (see SCSS Architecture section above):
627
+ - [ ] All CSS variables exist in `theme/_variables.scss`
628
+ - [ ] BEM naming: `elb-{component}-{element}`
629
+ - [ ] SCSS file created in correct directory (`atoms/`, `molecules/`,
630
+ `organisms/`)
631
+ - [ ] SCSS imported in `index.scss` (alphabetical order)
632
+ - [ ] No hardcoded values (colors, spacing, fonts)
633
+ - [ ] Uses `calc(var(--font-size-base) - Npx)` for size variations
634
+ - [ ] Light and dark theme tested
635
+ - [ ] No inline `style` attributes
636
+ - [ ] Responsive design considered
637
+ - [ ] Reuses existing components where possible (MappingCollapsible, IconButton,
638
+ etc.)
639
+ - [ ] **RJSF components follow Field/Widget separation pattern** (see
640
+ [PATTERNS.md](./PATTERNS.md))
641
+ - [ ] Build succeeds: `npm run build`
642
+ - [ ] Exported from `src/index.ts` (if public API)
643
+
644
+ ## Monaco Editor Height Management
645
+
646
+ The explorer uses Monaco Editor with a flexible, responsive height system that works across all contexts.
647
+
648
+ ### Height Modes
649
+
650
+ CodeBox supports three height modes:
651
+
652
+ 1. **Default (height="100%")**: Fills parent container
653
+ - Use in Grid contexts for equal row heights
654
+ - Use in Flex contexts to fill available space
655
+ - Requires parent with explicit height or bounded context
656
+
657
+ 2. **Auto-height (autoHeight prop)**: Dynamically sizes to content
658
+ - Grows/shrinks based on Monaco's content height
659
+ - Respects min/max boundaries (customizable)
660
+ - Eliminates blank space in standalone contexts
661
+ - Updates automatically when content changes
662
+
663
+ 3. **Explicit height**: Fixed pixel or viewport height
664
+ - Override with `height` prop (e.g., `height="600px"` or `height="50vh"`)
665
+
666
+ ### Usage Examples
667
+
668
+ **Grid Context - Equal Heights:**
669
+ ```tsx
670
+ // Don't use autoHeight - maintains equal row heights
671
+ <Grid columns={3}>
672
+ <CodeBox code={event} label="Event" />
673
+ <CodeBox code={mapping} label="Mapping" />
674
+ <CodeBox code={output} label="Output" />
675
+ </Grid>
676
+ ```
677
+
678
+ **Standalone - Content-Based Height:**
679
+ ```tsx
680
+ // Use autoHeight to eliminate blank space
681
+ <CodeBox
682
+ code={setupExample}
683
+ label="Setup"
684
+ autoHeight={{ min: 100, max: 600 }}
685
+ disabled
686
+ />
687
+ ```
688
+
689
+ **Flex Context - Fill Parent:**
690
+ ```tsx
691
+ // Don't use autoHeight - fills available flex space
692
+ <div style={{ display: 'flex', flexDirection: 'column', height: '100vh' }}>
693
+ <CodeBox code={largeConfig} onChange={setConfig} />
694
+ </div>
695
+ ```
696
+
697
+ **Explicit Height Override:**
698
+ ```tsx
699
+ <CodeBox code={longCode} height="600px" />
700
+ ```
435
701
 
436
- ## ๐Ÿš€ Roadmap
702
+ ### How Auto-Height Works
437
703
 
438
- ### Immediate (Phase 5)
704
+ When `autoHeight` is enabled:
705
+ 1. Monaco Editor's `getContentHeight()` API measures actual content height
706
+ 2. Hook listens to `onDidContentSizeChange` events (debounced)
707
+ 3. Height calculated and bounded by min/max values
708
+ 4. Monaco receives explicit pixel height (e.g., `height="347px"`)
709
+ 5. Updates automatically on content changes, typing, or formatting
439
710
 
440
- - [x] Complete testing suite
441
- - [x] Comprehensive documentation
442
- - [x] Interactive demos
443
- - [ ] Performance optimizations
444
- - [ ] Accessibility improvements
711
+ **Technical Details:**
712
+ - Uses `useMonacoHeight` hook with Monaco's official APIs
713
+ - Avoids infinite loops by not calling `layout()` in content change handler
714
+ - Includes overhead calculation for header/borders (45px)
715
+ - Default boundaries: min=100px, max=600px (customizable)
445
716
 
446
- ### Short Term
717
+ ### Key Files
447
718
 
448
- - [ ] npm package publication
449
- - [ ] CDN builds for easy integration
450
- - [ ] React wrapper components
451
- - [ ] Storybook integration
719
+ - `explorer/src/components/atoms/code.tsx` - Monaco wrapper with autoHeight integration
720
+ - `explorer/src/hooks/useMonacoHeight.ts` - Content height calculation hook
721
+ - `explorer/src/styles/components/atoms/_code.scss` - Flex-based Monaco container
722
+ - `explorer/src/styles/components/organisms/_box.scss` - Context-specific height rules
452
723
 
453
- ### Long Term
724
+ ### Troubleshooting
454
725
 
455
- - [ ] Browser extension for debugging
456
- - [ ] VS Code extension integration
457
- - [ ] Advanced theming system
458
- - [ ] Plugin architecture for extensibility
726
+ **Monaco shows wrong height?**
727
+ - Check parent context: Grid, Flex, or standalone?
728
+ - Grid/Flex: Don't use autoHeight (use default height="100%")
729
+ - Standalone: Add `autoHeight={{ min: 100, max: 600 }}`
730
+ - Override with explicit `height` prop if needed
459
731
 
460
- ## ๐Ÿค Contributing
732
+ **AutoHeight not working?**
733
+ - Ensure Monaco has mounted (check browser console for errors)
734
+ - Verify min/max boundaries aren't too restrictive
735
+ - Check that content is actually rendering (empty code = min height)
461
736
 
462
- 1. Follow the functional factory pattern established in the codebase
463
- 2. Add comprehensive tests for new functionality
464
- 3. Update documentation and type definitions
465
- 4. Ensure all tests pass: `npm run test`
466
- 5. Follow TypeScript best practices
737
+ **Height grows infinitely?**
738
+ - Should not happen with current implementation
739
+ - Hook avoids calling `layout()` in content change handler
740
+ - Report if you encounter this bug
467
741
 
468
- ## ๐Ÿ“„ License
742
+ ## Browser Support
469
743
 
470
- Part of the walkerOS project. See the main repository for license information.
744
+ Chrome 80+, Firefox 75+, Safari 13+, Edge 80+
471
745
 
472
- ## ๐Ÿ”— Links
746
+ ## License
473
747
 
474
- - **walkerOS Documentation**: https://docs.walkerOS.com
475
- - **GitHub Repository**: https://github.com/elbwalker/walkerOS
476
- - **Issues**: https://github.com/elbwalker/walkerOS/issues
748
+ MIT