|
24 | 24 | }) |
25 | 25 | let stimulusControllers = $state([]) |
26 | 26 | let registeredStimulusIdentifiers = $state([]) |
| 27 | + let notUsedStimulusIdentifiers = $derived(registeredStimulusIdentifiers.filter((identifier) => !stimulusControllers.find((n) => n.identifier === identifier))) |
27 | 28 | let uniqueIdentifiers = $derived([...new Set(stimulusControllers.map((n) => n.identifier).filter(Boolean))].sort()) |
28 | 29 | let counts = $derived( |
29 | 30 | stimulusControllers.reduce((acc, n) => { |
|
133 | 134 | } |
134 | 135 | </script> |
135 | 136 |
|
136 | | -<Splitpanes horizontal={$horizontalPanes} dblClickSplitter={false}> |
137 | | - <Pane class="stimulus-identifiers-list-pane full-pane" size={options.stimulusIdentifiersPaneDimensions?.streams || 35} minSize={20}> |
138 | | - <div class="pane-container"> |
139 | | - <div class="pane-header flex-center"> |
140 | | - {#if stimulusControllers.length === 0} |
141 | | - <h3 class="pane-header-title">Controllers</h3> |
142 | | - {/if} |
143 | | - </div> |
144 | | - {#if stimulusControllers.length > 0} |
145 | | - <div class="pane-scrollable-list"> |
146 | | - {#each uniqueIdentifiers as identifier, index (identifier)} |
147 | | - <div |
148 | | - class="entry-row p-1 cursor-pointer" |
149 | | - animate:flip={{ delay: 0, duration: 200 }} |
150 | | - role="button" |
151 | | - tabindex="0" |
152 | | - onclick={() => setSelectedIdentifier(identifier)} |
153 | | - onkeydown={handleIdentifiersKeyboardNavigation} |
154 | | - onmouseenter={() => addHighlightOverlay(`[data-controller~="${identifier}"]`)} |
155 | | - onmouseleave={() => hideHighlightOverlay()} |
156 | | - class:selected={selected.identifier === identifier} |
157 | | - > |
158 | | - <div class="d-flex justify-content-between align-items-center"> |
159 | | - <div id={`identifier-${index}`} class:error-text-underline={!isIdentifierRegistered(identifier)}> |
160 | | - {identifier} |
| 137 | +{#if stimulusControllers.length === 0} |
| 138 | + <div class="no-entry-hint mt-4"> |
| 139 | + <span>No Stimulus Controllers seen yet</span> |
| 140 | + <span>We'll keep looking</span> |
| 141 | + </div> |
| 142 | +{:else} |
| 143 | + <Splitpanes horizontal={$horizontalPanes} dblClickSplitter={false}> |
| 144 | + <Pane class="stimulus-identifiers-list-pane full-pane" size={options.stimulusIdentifiersPaneDimensions?.streams || 35} minSize={20}> |
| 145 | + <div class="pane-container"> |
| 146 | + <div class="pane-header flex-center"> |
| 147 | + {#if stimulusControllers.length === 0} |
| 148 | + <h3 class="pane-header-title">Controllers</h3> |
| 149 | + {/if} |
| 150 | + </div> |
| 151 | + {#if stimulusControllers.length > 0} |
| 152 | + <div class="pane-scrollable-list"> |
| 153 | + {#each uniqueIdentifiers as identifier, index (identifier)} |
| 154 | + <div |
| 155 | + class="entry-row p-1 cursor-pointer" |
| 156 | + animate:flip={{ delay: 0, duration: 200 }} |
| 157 | + role="button" |
| 158 | + tabindex="0" |
| 159 | + onclick={() => setSelectedIdentifier(identifier)} |
| 160 | + onkeydown={handleIdentifiersKeyboardNavigation} |
| 161 | + onmouseenter={() => addHighlightOverlay(`[data-controller~="${identifier}"]`)} |
| 162 | + onmouseleave={() => hideHighlightOverlay()} |
| 163 | + class:selected={selected.identifier === identifier} |
| 164 | + > |
| 165 | + <div class="d-flex justify-content-between align-items-center"> |
| 166 | + <div id={`identifier-${index}`} class:error-text-underline={!isIdentifierRegistered(identifier)}> |
| 167 | + {identifier} |
| 168 | + </div> |
| 169 | + {#if !isIdentifierRegistered(identifier)} |
| 170 | + <wa-tooltip for={`identifier-${index}`} style="--max-width: 200px;"> |
| 171 | + <div>This controller does not appear to be registered in window.Stimulus.</div> |
| 172 | + </wa-tooltip> |
| 173 | + {/if} |
| 174 | + <div>{counts[identifier]}</div> |
161 | 175 | </div> |
162 | | - {#if !isIdentifierRegistered(identifier)} |
163 | | - <wa-tooltip for={`identifier-${index}`} style="--max-width: 200px;"> |
164 | | - <div>This controller does not appear to be registered in window.Stimulus.</div> |
165 | | - </wa-tooltip> |
166 | | - {/if} |
167 | | - <div>{counts[identifier]}</div> |
168 | 176 | </div> |
169 | | - </div> |
170 | | - {/each} |
171 | | - </div> |
172 | | - {:else} |
173 | | - <div class="no-entry-hint"> |
174 | | - <span>No Stimulus Controllers seen yet</span> |
175 | | - <span>We'll keep looking</span> |
176 | | - </div> |
177 | | - {/if} |
178 | | - </div> |
179 | | - </Pane> |
| 177 | + {/each} |
180 | 178 |
|
181 | | - <Pane class="stimulus-controller-list-pane full-pane" size={options.stimulusControllerPaneDimensions?.details || 35} minSize={20}> |
182 | | - <div class="pane-container"> |
183 | | - <div class="pane-header flex-center"></div> |
184 | | - {#if selected.identifier} |
185 | | - <div class="pane-scrollable-list"> |
186 | | - {#each getStimulusInstances(selected.identifier) as instance (instance.uuid)} |
187 | | - <div |
188 | | - class="entry-row entry-row--table-layout p-1 cursor-pointer" |
189 | | - class:selected={selected.uuid === instance.uuid} |
190 | | - animate:flip={{ delay: 0, duration: 200 }} |
191 | | - role="button" |
192 | | - tabindex="0" |
193 | | - onclick={() => setSelectedController(instance)} |
194 | | - onkeydown={handleInstancesKeyboardNavigation} |
195 | | - onmouseenter={() => addHighlightOverlay(selectorByUUID(instance.uuid))} |
196 | | - onmouseleave={() => hideHighlightOverlay()} |
197 | | - > |
198 | | - <div class="d-table-row"> |
199 | | - <div class="stimulus-instance-first-column"> |
200 | | - <StripedHtmlTag element={instance} /> |
| 179 | + {#if notUsedStimulusIdentifiers.length > 0} |
| 180 | + {#each notUsedStimulusIdentifiers as identifier (identifier)} |
| 181 | + <div class="entry-row p-1" animate:flip={{ delay: 0, duration: 200 }}> |
| 182 | + <div class="d-flex justify-content-between align-items-center text-muted"> |
| 183 | + {identifier} |
| 184 | + <div>0</div> |
| 185 | + </div> |
201 | 186 | </div> |
| 187 | + {/each} |
| 188 | + {/if} |
| 189 | + </div> |
| 190 | + {:else} |
| 191 | + <div class="no-entry-hint"> |
| 192 | + <span>No Stimulus Controllers seen yet</span> |
| 193 | + <span>We'll keep looking</span> |
| 194 | + </div> |
| 195 | + {/if} |
| 196 | + </div> |
| 197 | + </Pane> |
| 198 | + |
| 199 | + <Pane class="stimulus-controller-list-pane full-pane" size={options.stimulusControllerPaneDimensions?.details || 35} minSize={20}> |
| 200 | + <div class="pane-container"> |
| 201 | + <div class="pane-header flex-center"></div> |
| 202 | + {#if selected.identifier} |
| 203 | + <div class="pane-scrollable-list"> |
| 204 | + {#each getStimulusInstances(selected.identifier) as instance (instance.uuid)} |
| 205 | + <div |
| 206 | + class="entry-row entry-row--table-layout p-1 cursor-pointer" |
| 207 | + class:selected={selected.uuid === instance.uuid} |
| 208 | + animate:flip={{ delay: 0, duration: 200 }} |
| 209 | + role="button" |
| 210 | + tabindex="0" |
| 211 | + onclick={() => setSelectedController(instance)} |
| 212 | + onkeydown={handleInstancesKeyboardNavigation} |
| 213 | + onmouseenter={() => addHighlightOverlay(selectorByUUID(instance.uuid))} |
| 214 | + onmouseleave={() => hideHighlightOverlay()} |
| 215 | + > |
| 216 | + <div class="d-table-row"> |
| 217 | + <div class="stimulus-instance-first-column"> |
| 218 | + <StripedHtmlTag element={instance} /> |
| 219 | + </div> |
202 | 220 |
|
203 | | - <div class="stimulus-instance-second-column"> |
204 | | - <div class="me-3 overflow-x-auto scrollbar-none"> |
205 | | - <InspectButton class="btn-hoverable me-2" uuid={instance.uuid}></InspectButton> |
| 221 | + <div class="stimulus-instance-second-column"> |
| 222 | + <div class="me-3 overflow-x-auto scrollbar-none"> |
| 223 | + <InspectButton class="btn-hoverable me-2" uuid={instance.uuid}></InspectButton> |
| 224 | + </div> |
206 | 225 | </div> |
207 | 226 | </div> |
208 | 227 | </div> |
209 | | - </div> |
210 | | - {/each} |
211 | | - </div> |
212 | | - {:else} |
213 | | - <div class="no-entry-hint"> |
214 | | - <span>Nothing selected</span> |
215 | | - <span>Select a Stimulus Controller to see its details</span> |
216 | | - </div> |
217 | | - {/if} |
218 | | - </div> |
219 | | - </Pane> |
220 | | - |
221 | | - <Pane class="stimulus-detail-pane full-pane" size={options.stimulusDetailsPaneDimensions?.details || 30} minSize={20}> |
222 | | - <div class="pane-container"> |
223 | | - <div class="pane-header flex-center"></div> |
224 | | - {#if selected.controller} |
225 | | - <div class="pane-scrollable-list"> |
226 | | - {#if selected.controller.values.length > 0} |
227 | | - <div class="pane-section-heading">Values</div> |
228 | | - {#each Object.entries(selected.controller.values) as [_key, valueObject] (selected.uuid + selected.identifier + valueObject.key)} |
229 | | - {@const dataAttribute = `data-${selected.identifier}-${valueObject.key}`} |
230 | | - <ValueTreeItem {valueObject} {selected} {dataAttribute} /> |
231 | | - {/each} |
232 | | - {/if} |
233 | | - {#if selected.controller.targets.length > 0} |
234 | | - <div class="pane-section-heading">Targets</div> |
235 | | - {#each selected.controller.targets.sort((a, b) => a.elements?.length < b.elements?.length) as target (selected.uuid + selected.identifier + target.name)} |
236 | | - <TargetTreeItem {target} {selected} /> |
237 | | - {/each} |
238 | | - {/if} |
239 | | - {#if selected.controller.outlets.length > 0} |
240 | | - <div class="pane-section-heading">Outlets</div> |
241 | | - {#each selected.controller.outlets.sort((a, b) => a.elements?.length < b.elements?.length) as outlet (selected.uuid + selected.identifier + outlet.name)} |
242 | | - <OutletTreeItem {outlet} {selected} /> |
243 | | - {/each} |
244 | | - {/if} |
245 | | - {#if selected.controller.classes.length > 0} |
246 | | - <div class="pane-section-heading">Classes</div> |
247 | | - {#each selected.controller.classes.sort((a, b) => a.classes?.length < b.classes?.length) as klass (selected.uuid + selected.identifier + klass.name)} |
248 | | - <ClassTreeItem {klass} {selected} /> |
249 | 228 | {/each} |
250 | | - {/if} |
251 | | - {#if selected.controller.actions.length > 0} |
252 | | - <div class="pane-section-heading">Actions</div> |
253 | | - {#each selected.controller.actions as action (selected.uuid + selected.identifier + action.descriptor)} |
254 | | - <ActionTreeItem {action} {selected} /> |
255 | | - {/each} |
256 | | - {/if} |
257 | | - {#if selected.controller.values.length === 0 && selected.controller.targets.length === 0 && selected.controller.outlets.length === 0 && selected.controller.classes.length === 0 && selected.controller.actions.length === 0} |
258 | | - <div class="no-entry-hint"> |
259 | | - <span>No details available</span> |
260 | | - <span>This controller has no values, targets, outlets, classes or actions</span> |
261 | | - </div> |
262 | | - {/if} |
263 | | - </div> |
264 | | - {:else} |
265 | | - <div class="no-entry-hint"> |
266 | | - <span>Nothing selected</span> |
267 | | - <span>Select a Stimulus Controller to see its details</span> |
268 | | - </div> |
269 | | - {/if} |
270 | | - </div> |
271 | | - </Pane> |
272 | | -</Splitpanes> |
| 229 | + </div> |
| 230 | + {:else} |
| 231 | + <div class="no-entry-hint"> |
| 232 | + <span>Nothing selected</span> |
| 233 | + <span>Select a Stimulus Controller to see its details</span> |
| 234 | + </div> |
| 235 | + {/if} |
| 236 | + </div> |
| 237 | + </Pane> |
| 238 | + |
| 239 | + <Pane class="stimulus-detail-pane full-pane" size={options.stimulusDetailsPaneDimensions?.details || 30} minSize={20}> |
| 240 | + <div class="pane-container"> |
| 241 | + <div class="pane-header flex-center"></div> |
| 242 | + {#if selected.controller} |
| 243 | + <div class="pane-scrollable-list"> |
| 244 | + {#if selected.controller.values.length > 0} |
| 245 | + <div class="pane-section-heading">Values</div> |
| 246 | + {#each Object.entries(selected.controller.values) as [_key, valueObject] (selected.uuid + selected.identifier + valueObject.key)} |
| 247 | + {@const dataAttribute = `data-${selected.identifier}-${valueObject.key}`} |
| 248 | + <ValueTreeItem {valueObject} {selected} {dataAttribute} /> |
| 249 | + {/each} |
| 250 | + {/if} |
| 251 | + {#if selected.controller.targets.length > 0} |
| 252 | + <div class="pane-section-heading">Targets</div> |
| 253 | + {#each selected.controller.targets.sort((a, b) => a.elements?.length < b.elements?.length) as target (selected.uuid + selected.identifier + target.name)} |
| 254 | + <TargetTreeItem {target} {selected} /> |
| 255 | + {/each} |
| 256 | + {/if} |
| 257 | + {#if selected.controller.outlets.length > 0} |
| 258 | + <div class="pane-section-heading">Outlets</div> |
| 259 | + {#each selected.controller.outlets.sort((a, b) => a.elements?.length < b.elements?.length) as outlet (selected.uuid + selected.identifier + outlet.name)} |
| 260 | + <OutletTreeItem {outlet} {selected} /> |
| 261 | + {/each} |
| 262 | + {/if} |
| 263 | + {#if selected.controller.classes.length > 0} |
| 264 | + <div class="pane-section-heading">Classes</div> |
| 265 | + {#each selected.controller.classes.sort((a, b) => a.classes?.length < b.classes?.length) as klass (selected.uuid + selected.identifier + klass.name)} |
| 266 | + <ClassTreeItem {klass} {selected} /> |
| 267 | + {/each} |
| 268 | + {/if} |
| 269 | + {#if selected.controller.actions.length > 0} |
| 270 | + <div class="pane-section-heading">Actions</div> |
| 271 | + {#each selected.controller.actions as action (selected.uuid + selected.identifier + action.descriptor)} |
| 272 | + <ActionTreeItem {action} {selected} /> |
| 273 | + {/each} |
| 274 | + {/if} |
| 275 | + {#if selected.controller.values.length === 0 && selected.controller.targets.length === 0 && selected.controller.outlets.length === 0 && selected.controller.classes.length === 0 && selected.controller.actions.length === 0} |
| 276 | + <div class="no-entry-hint"> |
| 277 | + <span>No details available</span> |
| 278 | + <span>This controller has no values, targets, outlets, classes or actions</span> |
| 279 | + </div> |
| 280 | + {/if} |
| 281 | + </div> |
| 282 | + {:else} |
| 283 | + <div class="no-entry-hint"> |
| 284 | + <span>Nothing selected</span> |
| 285 | + <span>Select a Stimulus Controller to see its details</span> |
| 286 | + </div> |
| 287 | + {/if} |
| 288 | + </div> |
| 289 | + </Pane> |
| 290 | + </Splitpanes> |
| 291 | +{/if} |
273 | 292 |
|
274 | 293 | <style> |
275 | 294 | .stimulus-instance-first-column { |
|
0 commit comments