@@ -20,12 +20,13 @@ must be of `string` type, and values can be any JSON serializable value.
2020Attach this behavior script to a ` UILayer ` in the world root to debug the KV data stored in your project.
2121
2222``` tsx title="kv-debugger.tsx"
23- import { JsonValue , rpc , UIBehavior } from " @dreamlab/engine" ;
23+ import { JsonValue , rpc , UIBehavior , UILayer } from " @dreamlab/engine" ;
2424
2525export default class KvDebugger extends UIBehavior {
2626 #player: string = " " ;
2727 #players = new Set <string >();
2828 #list: Record <string , JsonValue > = {};
29+ #isVisible = true ;
2930
3031 @rpc .server ()
3132 async getKv(playerId : string ) {
@@ -100,57 +101,94 @@ div.container {
100101 }
101102 }
102103}
104+
105+ button.kv-toggle {
106+ position: absolute;
107+ right: 12px;
108+ bottom: 12px;
109+ height: 30px;
110+ border-radius: 9999px;
111+ border: 1px solid rgba(255,255,255,0.25);
112+ background: #1f2330;
113+ color: #fff;
114+ opacity: 0.7;
115+ cursor: pointer;
116+ display: grid;
117+ place-items: center;
118+ font-size: 0.9rem;
119+ line-height: 1;
120+ z-index: 1000;
121+ transition: opacity 0.15s ease, transform 0.1s ease;
122+ }
123+
124+ button.kv-toggle:hover { opacity: 1; }
125+ button.kv-toggle:active { transform: scale(0.96); }
103126` ;
104127
105128 this .setCss (css );
129+ this .entity .cast (UILayer ).element .style .zIndex = " 999" ;
106130 this .#update ();
107131 }
108132
109133 render() {
110134 const entries = Object .entries (this .#list );
111135
112136 return (
113- <div className = " container" >
114- <h1 >KV Debugger</h1 >
115-
116- <div className = " selector" >
117- <label htmlFor = " player" >Player Selector</label >
118- <select
119- id = " player"
120- onChange = { (ev ) => {
121- if (! ev .target ) return ;
122- if (! (ev .target instanceof HTMLSelectElement )) return ;
123-
124- this .#player = ev .target .value ;
125- this .#update ();
126- }}
127- >
128- <option value = " " >[server]</option >
129- { [... this .#players ].map ((player ) => (
130- <option value = { player } >{ player } </option >
131- ))}
132- </select >
137+ <div className = " kv-root" >
138+ <div
139+ className = " container"
140+ style = { { display: this .#isVisible ? undefined : " none" }}
141+ >
142+ <h1 >KV Debugger</h1 >
143+
144+ <div className = " selector" >
145+ <label htmlFor = " player" >Player Selector</label >
146+ <select
147+ id = " player"
148+ onChange = { (ev ) => {
149+ if (! ev .target ) return ;
150+ if (! (ev .target instanceof HTMLSelectElement )) return ;
151+
152+ this .#player = ev .target .value ;
153+ this .#update ();
154+ }}
155+ >
156+ <option value = " " >[server]</option >
157+ { [... this .#players ].map ((player ) => <option value = { player } >{ player } </option >)}
158+ </select >
159+ </div >
160+
161+ <div className = " data" >
162+ { entries .length === 0 ? <span >No data stored.</span > : (
163+ <div >
164+ <span >Key</span >
165+ <span >Value</span >
166+
167+ { entries .map (([key , value ]) => (
168+ <div style = { { display: " contents" }} >
169+ <code >{ key } </code >
170+ <pre >{ JSON .stringify (value )} </pre >
171+ </div >
172+ ))}
173+ </div >
174+ )}
175+ </div >
133176 </div >
134177
135- <div className = " data" >
136- { entries .length === 0 ? (
137- <span >No data stored.</span >
138- ) : (
139- <div >
140- <span >Key</span >
141- <span >Value</span >
142-
143- { entries .map (([key , value ]) => (
144- <div style = { { display: " contents" }} >
145- <code >{ key } </code >
146- <pre >{ JSON .stringify (value )} </pre >
147- </div >
148- ))}
149- </div >
150- )}
151- </div >
178+ <button
179+ className = " kv-toggle"
180+ aria-label = { this .#isVisible ? " Hide KV Debugger" : " Show KV Debugger" }
181+ title = { this .#isVisible ? " Hide KV Debugger" : " Show KV Debugger" }
182+ onClick = { () => {
183+ this .#isVisible = ! this .#isVisible ;
184+ this .rerender ();
185+ }}
186+ >
187+ { this .#isVisible ? " Close KV" : " Open KV" }
188+ </button >
152189 </div >
153190 );
154191 }
155192}
193+
156194```
0 commit comments