Index: src/UploadTest.vue
===================================================================
--- src/UploadTest.vue	(revision 4b96189c351c92e8383b4411f7a4a73de521da76)
+++ src/UploadTest.vue	(revision 64249d67d46154f425d75b148c215f53466b90e0)
@@ -12,4 +12,9 @@
 const max_jobs = ref(3)
 
+const can_reset = ref(false)
+const can_start = ref(false)
+const can_pick = ref(false)
+const can_abort = ref(false)
+
 const reset = (): void => {
   (inst as any).refs.uploader.reset()
@@ -20,103 +25,130 @@
 }
 
+const pick = (): void => {
+  (inst as any).refs.uploader.pick()
+}
+
+const abort = (): void => {
+  (inst as any).refs.uploader.abort()
+}
+
 </script>
 
 <template>
-  <component class='uploader' :is='UploadZone' target='https://vite.js29a.usermd.net/upload.php'
-             :max-jobs='max_jobs' :auto-start='auto_start' :auto-reset='auto_reset'
-             :keep-going='keep_going' ref='uploader'>
-    <template #idle='{ pick }'>
-      <div class='idle'>
-        idle
-        <br />
-        <button @click='pick()'>pick</button>
-      </div>
-    </template>
-
-    <template #hover>
-      <div class='hover'>
-        hover
-      </div>
-    </template>
-
-    <template #wait='{ start, queue }'>
-      <div class='wait'>
-        wait
-        <br />
-        <button @click='pick()'>pick</button>
-        <br />
-        <button @click='start()'>start</button>
-        <br/>
-        <div v-for='file in queue'>{{ file.name }}</div>
-      </div>
-    </template>
-
-    <template #uploading='{ progress, current, queue, abort, errors }'>
-      <div class='uploading'>
-        uploading
-        <br />
-        <button @click='abort()'>abort</button>
-        <br />
-        {{ progress.length }} / {{ current.length }} / {{ queue.length }}
-        <br />
-        <button @click='abort()'>abort</button>
-        <b>errors:</b> <span v-for='error in errors'>{{ error.file.name }}</span>
-        <b>progress:</b> <div v-for='item in progress'>{{ item }}</div>
-        <b>current:</b>
-        <div v-for='item in current'>
-          {{ item.file.name }}: {{ item.current }} of {{ item.total }}
-        </div>
-        <b>remaining:</b>
-        <div v-for='file in queue'>{{ file.name }}</div>
-      </div>
-    </template>
-
-    <template #done='{ result, reset }'>
-      <div class='done'>
-        done
-        <br />
-        <button @click='reset()'>reset</button>
-        <br />
-        <div v-for='item in result'>{{ item }}</div>
-      </div>
-    </template>
-
-    <template #error='{ error, reset }'>
-      <div class='error'>
-        error
-        <br />
-        <button @click='reset()'>reset</button>
-        <div>{{ error }}</div>
-      </div>
-    </template>
-
-    <template #aborted='{ result, reset }'>
-      <div class='aborted'>
-        aborted
-        <br />
-        <button @click='reset()'>reset</button>
-        <div v-for='item in result'>{{ item }}</div>
-      </div>
-    </template>
-
-    <template #with-errors='{ result, errors }'>
-      <div class='with-errors'>
-        with errors
-        <br />
-        <b>errors(s):</b>
-        <div v-for='item in errors'>{{ item.file.name }} / {{ item.error }}</div>
-        <b>ok:</b>
-        <div v-for='item in result'>{{ item }}</div>
-      </div>
-    </template>
-  </component>
+  <div class='over'>
+    <button @click='pick' :disabled='!can_pick'>pick</button>
+    <span>&nbsp;</span>
+    <button @click='start' :disabled='!can_start'>start</button>
+    <span>&nbsp;</span>
+    <button @click='abort' :disabled='!can_abort'>abort</button>
+    <span>&nbsp;</span>
+    <button @click='reset' :disabled='!can_reset'>reset</button>
+    <p />
+    <input type='checkbox' v-model='auto_start' id='auto-start' />
+    <label for='auto-start'>&nbsp;auto-start</label><br />
+    <input type='checkbox' v-model='auto_reset' id='auto-reset' />
+    <label for='auto-reset'>&nbsp;auto-reset</label><br />
+    <input type='checkbox' v-model='keep_going' id='keep-going' />
+    <label for='keep-going'>&nbsp;keep-going</label><br />
+    <p />
+
+    <component class='uploader' :is='UploadZone' target='https://vite.js29a.usermd.net/upload.php'
+               :max-jobs='max_jobs' :auto-start='auto_start' :auto-reset='auto_reset'
+               :keep-going='keep_going' ref='uploader'
+               @update:canPick='(flag: boolean) => can_pick = flag'
+               @update:canStart='(flag: boolean) => can_start = flag'
+               @update:canAbort='(flag: boolean) => can_abort = flag'
+               @update:canReset='(flag: boolean) => can_reset = flag'>
+      <template #idle='{ pick }'>
+        <div class='idle'>
+          idle
+          <br />
+          <button @click='pick()'>pick</button>
+        </div>
+      </template>
+
+      <template #hover>
+        <div class='hover'>
+          hover
+        </div>
+      </template>
+
+      <template #wait='{ start, queue }'>
+        <div class='wait'>
+          wait
+          <br />
+          <button @click='pick()'>pick</button>
+          <br />
+          <button @click='start()'>start</button>
+          <br/>
+          <div v-for='file in queue'>{{ file.name }}</div>
+        </div>
+      </template>
+
+      <template #uploading='{ progress, current, queue, abort, errors }'>
+        <div class='uploading'>
+          uploading
+          <br />
+          <button @click='abort()'>abort</button>
+          <br />
+          {{ progress.length }} / {{ current.length }} / {{ queue.length }}
+          <br />
+          <button @click='abort()'>abort</button>
+          <b>errors:</b> <span v-for='error in errors'>{{ error.file.name }}</span>
+          <b>progress:</b> <div v-for='item in progress'>{{ item }}</div>
+          <b>current:</b>
+          <div v-for='item in current'>
+            {{ item.file.name }}: {{ item.current }} of {{ item.total }}
+          </div>
+          <b>remaining:</b>
+          <div v-for='file in queue'>{{ file.name }}</div>
+        </div>
+      </template>
+
+      <template #done='{ result, reset }'>
+        <div class='done'>
+          done
+          <br />
+          <button @click='reset()'>reset</button>
+          <br />
+          <div v-for='item in result'>{{ item }}</div>
+        </div>
+      </template>
+
+      <template #error='{ error, reset }'>
+        <div class='error'>
+          error
+          <br />
+          <button @click='reset()'>reset</button>
+          <div>{{ error }}</div>
+        </div>
+      </template>
+
+      <template #aborted='{ result, reset }'>
+        <div class='aborted'>
+          aborted
+          <br />
+          <button @click='reset()'>reset</button>
+          <div v-for='item in result'>{{ item }}</div>
+        </div>
+      </template>
+
+      <template #with-errors='{ result, errors }'>
+        <div class='with-errors'>
+          with errors
+          <br />
+          <b>errors(s):</b>
+          <div v-for='item in errors'>{{ item.file.name }} / {{ item.error }}</div>
+          <b>ok:</b>
+          <div v-for='item in result'>{{ item }}</div>
+        </div>
+      </template>
+    </component>
+  </div>
 </template>
 
 <style scoped>
 
-.uploader {
-  border: 3px dashed #fff;
-  width: 512px;
-  height: 384px;
+.over {
   position: absolute;
   border-radius: 20px;
@@ -124,4 +156,11 @@
   left: 50%;
   transform: translate(-50%, -50%);
+}
+
+.uploader {
+  border: 3px dashed #fff;
+  width: 512px;
+  height: 384px;
+  display: inline-block;
 }
 
