gardenjs 1.6.8 → 1.7.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.
Files changed (47) hide show
  1. package/.prettierrc +16 -5
  2. package/README.md +1 -1
  3. package/dist/assets/frame-BOcgZVOc.js +9 -0
  4. package/dist/assets/index-BDdBNVTh.css +19 -0
  5. package/dist/assets/index-DFG9gkdS.js +46 -0
  6. package/dist/assets/props-COK33XqS.js +2 -0
  7. package/dist/frame.html +2 -2
  8. package/dist/index.html +3 -3
  9. package/eslint.config.js +14 -1
  10. package/package.json +3 -1
  11. package/src/client/GardenApp.svelte +105 -92
  12. package/src/client/GardenFrame.svelte +25 -3
  13. package/src/client/assets/scss/main.scss +0 -1
  14. package/src/client/components/panes/HorizontalSplitPane.svelte +28 -24
  15. package/src/client/components/panes/VerticalSplitPane.svelte +118 -0
  16. package/src/client/components/sidebar/Sidebar.svelte +8 -11
  17. package/src/client/components/stage/Stage.svelte +76 -1
  18. package/src/client/components/stage/panel/PanelCode.svelte +7 -1
  19. package/src/client/components/stage/panel/PanelComponent.svelte +0 -1
  20. package/src/client/components/stage/panel/PanelDescription.svelte +6 -0
  21. package/src/client/components/stage/panel/PanelExamplesNav.svelte +38 -12
  22. package/src/client/components/stage/panel/ParamsPane.svelte +201 -0
  23. package/src/client/components/stage/panel/controls/ArrayControl.svelte +242 -0
  24. package/src/client/components/stage/panel/controls/BooleanControl.svelte +142 -0
  25. package/src/client/components/stage/panel/controls/ColorPickerControl.svelte +185 -0
  26. package/src/client/components/stage/panel/controls/DateControl.svelte +64 -0
  27. package/src/client/components/stage/panel/controls/DatetimeControl.svelte +64 -0
  28. package/src/client/components/stage/panel/controls/JsonControl.svelte +29 -0
  29. package/src/client/components/stage/panel/controls/MultiselectControl.svelte +354 -0
  30. package/src/client/components/stage/panel/controls/NumberControl.svelte +31 -0
  31. package/src/client/components/stage/panel/controls/ObjectControl.svelte +148 -0
  32. package/src/client/components/stage/panel/controls/RangeControl.svelte +156 -0
  33. package/src/client/components/stage/panel/controls/SelectControl.svelte +233 -0
  34. package/src/client/components/stage/panel/controls/TextInputControl.svelte +85 -0
  35. package/src/client/components/stage/panel/controls/TimeControl.svelte +64 -0
  36. package/src/client/components/stage/panel/controls/button.scss +15 -0
  37. package/src/client/components/stage/panel/controls/button_unset.scss +35 -0
  38. package/src/client/components/stage/panel/controls/input.scss +15 -0
  39. package/src/client/components/topbar/Topbar.svelte +8 -0
  40. package/src/client/logic/localStore.js +23 -0
  41. package/src/client/logic/sidebar.svelte.js +55 -0
  42. package/src/client/logic/stage.js +2 -63
  43. package/dist/assets/frame-B7ff1vAd.js +0 -9
  44. package/dist/assets/index-DfGHKcnI.css +0 -19
  45. package/dist/assets/index-WI1a7nYK.js +0 -46
  46. package/dist/assets/props-DKVIKFn7.js +0 -2
  47. package/src/client/assets/scss/base/input-number.css +0 -11
@@ -2,6 +2,17 @@
2
2
  import Stage from './components/stage/Stage.svelte'
3
3
  import Sidebar from './components/sidebar/Sidebar.svelte'
4
4
  import Topbar from './components/topbar/Topbar.svelte'
5
+ import VerticalSplitPane from './components/panes/VerticalSplitPane.svelte'
6
+ import {
7
+ sidebarWidth,
8
+ sidebarExpanded,
9
+ sidebarMaxWidth,
10
+ updateSidebarWidth,
11
+ updateSidebarMaxWidth,
12
+ toggleExpandSidebar,
13
+ collapseMobileNavIfVisible,
14
+ initSidebar,
15
+ } from './logic/sidebar.svelte.js'
5
16
  import {
6
17
  stageStyle,
7
18
  stageSize,
@@ -31,12 +42,9 @@
31
42
  updateStageWidth,
32
43
  updateStageRect,
33
44
  resetStage,
34
- sidebarExpanded,
35
- toggleExpandSidebar,
36
45
  toggleShowInspector,
37
46
  toggleShowGrid,
38
47
  toggleOrientation,
39
- handleSelectionChanged,
40
48
  showInspector,
41
49
  showGrid,
42
50
  gridSettings,
@@ -92,9 +100,11 @@
92
100
  })
93
101
  $effect(() => {
94
102
  updateSelectedComponent($componentName)
95
- handleSelectionChanged()
103
+ collapseMobileNavIfVisible()
96
104
  })
97
105
 
106
+ initSidebar()
107
+
98
108
  let projectTitle = config.project_title || ''
99
109
  let projectLogo = config.project_logo?.split('/').pop() || null
100
110
  let projectLogoDarkmode =
@@ -132,99 +142,101 @@
132
142
  </div>
133
143
  {:else}
134
144
  <div class="garden">
135
- <div class="sidebar">
136
- <Sidebar
137
- {docsLink}
138
- {projectLogoDarkmode}
139
- {projectLogo}
140
- {projectTitle}
141
- appTheme={$appTheme}
142
- bookmarks={$bookmarks}
143
- filter={$filterNavTree}
144
- nodes={$nodes}
145
- panelExpanded={$panelExpanded}
146
- treeCollapsed={$treeCollapsed}
147
- sidebarExpanded={$sidebarExpanded}
148
- onLogoClicked={resetStage}
149
- onToggleBookmark={toggleBookmark}
150
- onToggleExpandPanel={toggleExpandPanel}
151
- onToggleFoldStatusOfNode={toggleFolder}
152
- onUpdateFilter={updateFilter}
153
- onCollapseTree={collapseTree}
154
- onExpandTree={expandTree}
155
- />
156
- </div>
157
- <div class="main">
158
- <Topbar
159
- appTheme={$appTheme}
160
- landscape={$landscape}
161
- node={$selectedNode}
162
- showGrid={$showGrid}
163
- nodeVisibleInExplorer={$selectedNodeVisibleInTree}
164
- showInspector={$showInspector}
165
- sidebarExpanded={$sidebarExpanded}
166
- stageHeight={$stageHeight}
167
- stageMaxHeight={$stageMaxHeight}
168
- stageMaxWidth={$stageMaxWidth}
169
- stageRect={$stageRect}
170
- stageSize={$stageSize}
171
- stageSizes={$stageSizes}
172
- stageWidth={$stageWidth}
173
- themes={$themes}
174
- onOpenInTab={openInTab}
175
- onSetStageHeight={updateStageHeight}
176
- onSetStageWidth={updateStageWidth}
177
- onSetStageSize={setStagesize}
178
- onSetTheme={setTheme}
179
- onToggleAppTheme={toggleAppTheme}
180
- onToggleBookmark={toggleBookmark}
181
- onToggleExpandSidebar={toggleExpandSidebar}
182
- onToggleOrientation={toggleOrientation}
183
- onToggleShowGrid={toggleShowGrid}
184
- onToggleShowInspector={toggleShowInspector}
185
- onRevealInExplorer={() => navigateToLeafNode($selectedNode?.href)}
186
- />
187
- <Stage
188
- appTheme={$appTheme}
189
- componentName={$componentName}
190
- das={$das}
191
- devmodus={config.devmodus}
192
- gridSettings={$gridSettings}
193
- panelExpanded={$panelExpanded}
194
- selectedExample={$selectedExample}
195
- showGrid={$showGrid}
196
- showInspector={$showInspector}
197
- stageContainerHeight={$stageContainerHeight}
198
- stageContainerMaxHeight={$stageContainerMaxHeight}
199
- stageHeight={$stageHeight}
200
- stageMaxHeight={$stageMaxHeight}
201
- stageMaxWidth={$stageMaxWidth}
202
- stageSize={$stageSize}
203
- stageStyle={$stageStyle}
204
- stageWidth={$stageWidth}
205
- theme={$activeTheme}
206
- onSetStageContainerHeight={updateStageContainerHeight}
207
- onSetStageContainerMaxHeight={updateStageContainerMaxHeight}
208
- onSetStageContainerWidth={updateStageContainerWidth}
209
- onSetStageHeight={updateStageHeight}
210
- onSetStageWidth={updateStageWidth}
211
- onToggleExpandPanel={toggleExpandPanel}
212
- onUpdateStageRect={updateStageRect}
213
- />
214
- </div>
145
+ <VerticalSplitPane
146
+ leftWidth={$sidebarWidth}
147
+ maxWidth={$sidebarMaxWidth}
148
+ onSetLeftWidth={updateSidebarWidth}
149
+ onSetMaxWidth={updateSidebarMaxWidth}
150
+ hideDragBar
151
+ >
152
+ {#snippet left()}
153
+ <Sidebar
154
+ {docsLink}
155
+ {projectLogoDarkmode}
156
+ {projectLogo}
157
+ {projectTitle}
158
+ appTheme={$appTheme}
159
+ bookmarks={$bookmarks}
160
+ filter={$filterNavTree}
161
+ nodes={$nodes}
162
+ panelExpanded={$panelExpanded}
163
+ treeCollapsed={$treeCollapsed}
164
+ sidebarExpanded={$sidebarExpanded}
165
+ onLogoClicked={resetStage}
166
+ onToggleBookmark={toggleBookmark}
167
+ onToggleExpandPanel={toggleExpandPanel}
168
+ onToggleFoldStatusOfNode={toggleFolder}
169
+ onUpdateFilter={updateFilter}
170
+ onCollapseTree={collapseTree}
171
+ onExpandTree={expandTree}
172
+ />
173
+ {/snippet}
174
+ {#snippet right()}
175
+ <div class="main">
176
+ <Topbar
177
+ appTheme={$appTheme}
178
+ landscape={$landscape}
179
+ node={$selectedNode}
180
+ showGrid={$showGrid}
181
+ nodeVisibleInExplorer={$selectedNodeVisibleInTree}
182
+ showInspector={$showInspector}
183
+ sidebarExpanded={$sidebarExpanded}
184
+ stageHeight={$stageHeight}
185
+ stageMaxHeight={$stageMaxHeight}
186
+ stageMaxWidth={$stageMaxWidth}
187
+ stageRect={$stageRect}
188
+ stageSize={$stageSize}
189
+ stageSizes={$stageSizes}
190
+ stageWidth={$stageWidth}
191
+ themes={$themes}
192
+ onOpenInTab={openInTab}
193
+ onSetStageHeight={updateStageHeight}
194
+ onSetStageWidth={updateStageWidth}
195
+ onSetStageSize={setStagesize}
196
+ onSetTheme={setTheme}
197
+ onToggleAppTheme={toggleAppTheme}
198
+ onToggleBookmark={toggleBookmark}
199
+ onToggleExpandSidebar={toggleExpandSidebar}
200
+ onToggleOrientation={toggleOrientation}
201
+ onToggleShowGrid={toggleShowGrid}
202
+ onToggleShowInspector={toggleShowInspector}
203
+ onRevealInExplorer={() => navigateToLeafNode($selectedNode?.href)}
204
+ />
205
+ <Stage
206
+ appTheme={$appTheme}
207
+ componentName={$componentName}
208
+ das={$das}
209
+ devmodus={config.devmodus}
210
+ gridSettings={$gridSettings}
211
+ panelExpanded={$panelExpanded}
212
+ selectedExample={$selectedExample}
213
+ showGrid={$showGrid}
214
+ showInspector={$showInspector}
215
+ stageContainerHeight={$stageContainerHeight}
216
+ stageContainerMaxHeight={$stageContainerMaxHeight}
217
+ stageHeight={$stageHeight}
218
+ stageMaxHeight={$stageMaxHeight}
219
+ stageMaxWidth={$stageMaxWidth}
220
+ stageSize={$stageSize}
221
+ stageStyle={$stageStyle}
222
+ stageWidth={$stageWidth}
223
+ theme={$activeTheme}
224
+ onSetStageContainerHeight={updateStageContainerHeight}
225
+ onSetStageContainerMaxHeight={updateStageContainerMaxHeight}
226
+ onSetStageContainerWidth={updateStageContainerWidth}
227
+ onSetStageHeight={updateStageHeight}
228
+ onSetStageWidth={updateStageWidth}
229
+ onToggleExpandPanel={toggleExpandPanel}
230
+ onUpdateStageRect={updateStageRect}
231
+ />
232
+ </div>
233
+ {/snippet}
234
+ </VerticalSplitPane>
215
235
  </div>
216
236
  {/if}
217
237
 
218
238
  <style>
219
- .sidebar {
220
- flex-grow: 0;
221
- flex-shrink: 0;
222
- }
223
239
  .garden {
224
- display: flex;
225
- flex-direction: row;
226
- flex-wrap: nowrap;
227
- flex-grow: 1;
228
240
  margin: 0;
229
241
  padding: 0 0.375rem;
230
242
  width: 100vw;
@@ -233,6 +245,7 @@
233
245
  background-color: var(--c-bg-body);
234
246
  }
235
247
  .main {
248
+ margin-left: 0.125rem;
236
249
  display: flex;
237
250
  flex-direction: column;
238
251
  width: 100%;
@@ -54,8 +54,13 @@
54
54
  showGrid = evt.data.showGrid === true
55
55
  gridSettings = evt.data.gridSettings
56
56
  das = dasMap[evt.data.componentName]
57
- selectedExample =
57
+ const rawSelectedExample =
58
58
  das?.examples?.find((ex) => ex.title === evt.data.selectedExample) ?? {}
59
+ const paramValues = evt.data?.paramValues ?? undefined
60
+ selectedExample = {
61
+ ...rawSelectedExample,
62
+ input: paramValues ?? rawSelectedExample?.input ?? {},
63
+ }
59
64
  componentChanged = componentName !== evt.data.componentName
60
65
  componentName = evt.data.componentName || 'Welcome'
61
66
  selectedExampleChanged = selectedExampleTitle !== evt.data.selectedExample
@@ -68,7 +73,7 @@
68
73
  redirectData = {}
69
74
  return
70
75
  } else {
71
- updateComponent(component, selectedExample, das)
76
+ executeLatest(() => updateComponent(component, selectedExample, das))
72
77
  }
73
78
  })
74
79
 
@@ -84,6 +89,23 @@
84
89
  return DefaultRendererBuilder
85
90
  }
86
91
 
92
+ let latestTask
93
+ let running = false
94
+
95
+ const executeLatest = async (task) => {
96
+ latestTask = task
97
+ if (running) return
98
+ if (!running) {
99
+ running = true
100
+ while (latestTask != null) {
101
+ const currentTask = latestTask
102
+ latestTask = undefined
103
+ await currentTask()
104
+ }
105
+ running = false
106
+ }
107
+ }
108
+
87
109
  async function updateComponent(component, selectedExample, das) {
88
110
  if (config.renderer) {
89
111
  const newRendererBuilder = await getRendererBuilderFor(das?.file)
@@ -95,7 +117,7 @@
95
117
  await runHooks()
96
118
 
97
119
  try {
98
- currentRenderer?.updateComponent({
120
+ await currentRenderer?.updateComponent({
99
121
  component,
100
122
  selectedExample,
101
123
  das,
@@ -3,4 +3,3 @@
3
3
  @use './base/typography';
4
4
  @use './base/navs';
5
5
  @use './base/buttons';
6
- @use './base/input-number.css';
@@ -1,12 +1,11 @@
1
1
  <script>
2
- import { onMount, onDestroy } from 'svelte'
3
2
  let {
4
3
  topHeight = $bindable(),
5
4
  maxHeight,
6
5
  top,
7
6
  bottom,
8
- onSetMaxWidth,
9
7
  onSetMaxHeight,
8
+ onSetMaxWidth,
10
9
  onSetTopHeight,
11
10
  } = $props()
12
11
  let element = $state()
@@ -33,39 +32,38 @@
33
32
  return undefined
34
33
  })
35
34
 
36
- const resizeObserver = new ResizeObserver((entries) => {
37
- entries.forEach(() => {
38
- onSetMaxHeight(element.offsetHeight)
39
- onSetMaxWidth(element.offsetWidth)
35
+ $effect(() => {
36
+ const resizeObserver = new ResizeObserver((entries) => {
37
+ entries.forEach(() => {
38
+ if (element) {
39
+ onSetMaxHeight(element.offsetHeight)
40
+ onSetMaxWidth(element.offsetWidth)
41
+ }
42
+ })
40
43
  })
41
- })
42
-
43
- onMount(() => {
44
44
  resizeObserver.observe(element)
45
- })
46
45
 
47
- onDestroy(() => {
48
- resizeObserver.disconnect()
46
+ return () => {
47
+ resizeObserver.disconnect()
48
+ }
49
49
  })
50
50
 
51
- function register() {
52
- document.addEventListener('mousemove', drag)
53
- document.addEventListener('mouseup', unregister)
51
+ function startDrag(e) {
52
+ e.currentTarget.setPointerCapture(e.pointerId)
53
+ document.body.style.userSelect = 'none'
54
54
  dragging = true
55
55
  }
56
56
 
57
57
  const drag = (e) => {
58
- window.getSelection().removeAllRanges()
59
- const newHeight = Math.min(maxHeight, e.pageY - element.offsetTop - 7)
60
- topHeight = newHeight
58
+ if (e.buttons !== 1) return
59
+ const newHeight = Math.min(maxHeight, topHeight + e.movementY)
60
+ topHeight = Math.max(100, newHeight)
61
61
  onSetTopHeight(topHeight)
62
62
  }
63
63
 
64
- function unregister() {
65
- document.removeEventListener('mousemove', drag)
66
- document.removeEventListener('mouseup', unregister)
67
-
68
- onSetTopHeight(topHeight)
64
+ function stopDrag(e) {
65
+ e.currentTarget.releasePointerCapture(e.pointerId)
66
+ document.body.style.userSelect = ''
69
67
  dragging = false
70
68
  }
71
69
  </script>
@@ -75,7 +73,13 @@
75
73
  {@render top?.()}
76
74
  </div>
77
75
  <!-- eslint-disable-next-line -->
78
- <div class="dragbar" class:dragging onmousedown={register}></div>
76
+ <div
77
+ class="dragbar"
78
+ class:dragging
79
+ onpointerdown={startDrag}
80
+ onpointerup={stopDrag}
81
+ onpointermove={drag}
82
+ ></div>
79
83
  {@render bottom?.()}
80
84
  </div>
81
85
 
@@ -0,0 +1,118 @@
1
+ <script>
2
+ let {
3
+ leftWidth = $bindable(),
4
+ maxWidth,
5
+ left,
6
+ right,
7
+ onSetMaxWidth,
8
+ onSetLeftWidth,
9
+ hideDragBar,
10
+ } = $props()
11
+ let element = $state()
12
+ let dragging = $state(false)
13
+
14
+ let init = $state(false)
15
+
16
+ $effect(() => {
17
+ if (element && !init) {
18
+ init = true
19
+ if (leftWidth && maxWidth) {
20
+ return
21
+ }
22
+ const elementWidth = element.offsetWidth
23
+ onSetMaxWidth(elementWidth - 100)
24
+ onSetLeftWidth(Math.round(elementWidth * 0.2))
25
+ }
26
+ })
27
+
28
+ const leftWidthWithUnit = $derived.by(() => {
29
+ if (Number.isInteger(leftWidth) && Number.isInteger(maxWidth)) {
30
+ return maxWidth < leftWidth ? maxWidth + 'px' : leftWidth + 'px'
31
+ }
32
+ return undefined
33
+ })
34
+
35
+ $effect(() => {
36
+ const resizeObserver = new ResizeObserver((entries) => {
37
+ entries.forEach(() => {
38
+ if (element) {
39
+ onSetMaxWidth(element.offsetWidth - 100)
40
+ }
41
+ })
42
+ })
43
+ resizeObserver.observe(element)
44
+
45
+ return () => {
46
+ resizeObserver.disconnect()
47
+ }
48
+ })
49
+
50
+ function startDrag(e) {
51
+ e.currentTarget.setPointerCapture(e.pointerId)
52
+ document.body.style.userSelect = 'none'
53
+ dragging = true
54
+ }
55
+
56
+ const drag = (e) => {
57
+ if (e.buttons !== 1) return
58
+ const newWidth = Math.min(maxWidth, leftWidth + e.movementX)
59
+ leftWidth = Math.max(100, newWidth)
60
+ onSetLeftWidth(leftWidth)
61
+ }
62
+
63
+ function stopDrag(e) {
64
+ e.currentTarget.releasePointerCapture(e.pointerId)
65
+ document.body.style.userSelect = ''
66
+ dragging = false
67
+ }
68
+ </script>
69
+
70
+ <div class="container" bind:this={element}>
71
+ <div class="left" style="width: {leftWidthWithUnit};">
72
+ {@render left?.()}
73
+ </div>
74
+ <!-- eslint-disable-next-line -->
75
+ <div
76
+ class="dragbar"
77
+ class:dragging
78
+ class:hide-drag-bar={hideDragBar}
79
+ onpointerdown={startDrag}
80
+ onpointerup={stopDrag}
81
+ onpointermove={drag}
82
+ ></div>
83
+ {@render right?.()}
84
+ </div>
85
+
86
+ <style>
87
+ .container {
88
+ display: flex;
89
+ flex-direction: row;
90
+ flex-wrap: nowrap;
91
+ width: 100%;
92
+ height: 100%;
93
+ overflow-x: auto;
94
+ }
95
+ .left {
96
+ flex-grow: 0;
97
+ flex-shrink: 0;
98
+ border-right: 0;
99
+ border-radius: 0.625rem 0.625rem 0 0;
100
+ overflow: auto;
101
+ }
102
+ .dragbar {
103
+ flex-grow: 0;
104
+ flex-shrink: 0;
105
+ width: 0.188rem;
106
+ background-color: var(--c-primary);
107
+ cursor: col-resize;
108
+ z-index: 10;
109
+ }
110
+ .dragging,
111
+ .dragbar:hover {
112
+ background-color: var(--c-primary);
113
+ transform: scaleX(2);
114
+ }
115
+ .hide-drag-bar {
116
+ background-color: unset;
117
+ }
118
+ </style>
@@ -108,13 +108,10 @@
108
108
 
109
109
  <style>
110
110
  .sidebar_container {
111
- --w-sidebar: 260px;
111
+ margin-right: 0.125rem;
112
112
  display: flex;
113
113
  flex-direction: column;
114
114
  position: relative;
115
- margin: 0.375rem 0;
116
- width: 0;
117
- max-width: var(--w-sidebar);
118
115
  height: calc(100vh - 0.75rem);
119
116
  background-color: var(--c-sidebar-bg);
120
117
  border-radius: 0.625rem;
@@ -122,8 +119,7 @@
122
119
  overflow: hidden;
123
120
  }
124
121
  .show-sidebar {
125
- margin: 0.375rem 0.375rem 0.375rem 0;
126
- width: var(--w-sidebar);
122
+ margin: 0.375rem 0.125rem 0.375rem 0;
127
123
  box-sizing: border-box;
128
124
  }
129
125
  .project-identifier {
@@ -135,10 +131,10 @@
135
131
  align-items: center;
136
132
  padding: 0.25rem 0.688rem;
137
133
  margin: 0 0 0.125rem;
138
- width: var(--w-sidebar);
134
+ width: 100%;
139
135
  height: 2.25rem;
140
136
  background-color: var(--c-sidebar);
141
- inline-size: var(--w-sidebar);
137
+ inline-size: 100%;
142
138
  overflow: hidden;
143
139
  white-space: nowrap;
144
140
  font-size: 1.25rem;
@@ -183,11 +179,12 @@
183
179
  color: var(--c-basic-500);
184
180
  }
185
181
  /* same styles as the input in the topbar: */
186
- .filter_input:focus-visible {
182
+ .filter_input:focus {
187
183
  background-color: var(--c-primary-bg);
184
+ box-shadow: 0 0 0 1px var(--c-primary);
188
185
  }
189
186
  .filter_zero-results {
190
- width: var(--w-sidebar);
187
+ width: 100%;
191
188
  padding: 0.5rem 0.688rem 0.375rem 0.688rem;
192
189
  text-transform: initial;
193
190
  font-size: 0.813rem;
@@ -213,7 +210,7 @@
213
210
  .controls {
214
211
  display: block;
215
212
  flex-shrink: 0;
216
- width: var(--w-sidebar);
213
+ width: 100%;
217
214
  height: 103px;
218
215
  bottom: 0.375rem;
219
216
  padding: 0;
@@ -38,6 +38,72 @@
38
38
  let myframeready = $state()
39
39
  let myframe = $state()
40
40
 
41
+ const selectedExampleObj = $derived.by(() => {
42
+ if (!das?.examples?.length) return {}
43
+ return das.examples.find((ex) => ex.title === selectedExample) ?? {}
44
+ })
45
+
46
+ const selectedExampleInput = $derived.by(() => {
47
+ const input = selectedExampleObj?.input
48
+ if (input && typeof input === 'object') return input
49
+ return {}
50
+ })
51
+
52
+ function getType(value) {
53
+ if (Array.isArray(value)) {
54
+ return 'array'
55
+ }
56
+ if (value instanceof Date) {
57
+ return 'date'
58
+ }
59
+ return typeof value
60
+ }
61
+
62
+ function capitalize(str) {
63
+ if (str.length > 1) {
64
+ return str.charAt(0).toUpperCase() + str.substring(1)
65
+ }
66
+ return str
67
+ }
68
+
69
+ const params = $derived.by(() => {
70
+ const configuredParams = das?.params ?? []
71
+ const exampleParams = Object.entries(selectedExampleInput).reduce(
72
+ (acc, [name, value]) => {
73
+ let configuredParam = configuredParams.find((p) => p.name === name)
74
+ if (configuredParam) {
75
+ acc.push(configuredParam)
76
+ } else {
77
+ acc.push({ name, type: getType(value), label: capitalize(name) })
78
+ }
79
+ return acc
80
+ },
81
+ []
82
+ )
83
+
84
+ return [
85
+ ...exampleParams,
86
+ ...configuredParams
87
+ .filter((configuredParam) =>
88
+ exampleParams.every(
89
+ (exampleParam) => exampleParam.name !== configuredParam.name
90
+ )
91
+ )
92
+ .map((p) => ({ ...p, value: undefined })),
93
+ ]
94
+ })
95
+
96
+ let paramValues = $derived(structuredClone(selectedExampleInput))
97
+
98
+ const paramValuesForPostMessage = $derived.by(() => {
99
+ try {
100
+ return JSON.parse(JSON.stringify(paramValues))
101
+ } catch (e) {
102
+ console.err(e)
103
+ return null
104
+ }
105
+ })
106
+
41
107
  const resizeObserver = new ResizeObserver((entries) => {
42
108
  entries.forEach((entry) => {
43
109
  onUpdateStageRect(entry.contentRect)
@@ -84,6 +150,14 @@
84
150
  tabs.push({
85
151
  name: 'Examples',
86
152
  props: {
153
+ params,
154
+ values: paramValues,
155
+ onChange: (prop, value) => {
156
+ paramValues = { ...paramValues, [prop]: value }
157
+ },
158
+ onReset: () => {
159
+ paramValues = { ...selectedExampleInput }
160
+ },
87
161
  selected: selectedExample,
88
162
  examples: das.examples.map((ex) => ex.title),
89
163
  onSelectExample: setSelectedExample,
@@ -127,6 +201,7 @@
127
201
  showInspector,
128
202
  showGrid,
129
203
  gridSettings,
204
+ paramValues: paramValuesForPostMessage,
130
205
  },
131
206
  window.location
132
207
  )
@@ -165,7 +240,7 @@
165
240
  {#snippet bottom()}
166
241
  <div class="panel">
167
242
  {#if panelExpanded}
168
- <PanelComponent {tabs} {onToggleExpandPanel} />
243
+ <PanelComponent {tabs} {onToggleExpandPanel} children={undefined} />
169
244
  {/if}
170
245
  </div>
171
246
  {/snippet}