Slider & upload
Three parts of one job: a slider for the dimensions that decide a pathway, a dropzone for the survey plan, and a file row as the receipt.
Slider
Code
<GdSlider v-model="area" label="Floor area" :min="1" :max="60" unit="m²" />
<GdSlider v-model="height" label="Height" :min="2.4" :max="12" :step="0.1" unit="m" />Upload
Code
<GdDropzone accept=".pdf,.dwg,.jpg" multiple hint="Up to 20 MB · PDF, DWG, JPG" @files="onFiles" />
<GdFileRow v-for="f in files" :key="f.name" v-bind="f" :progress="f.pct" @remove="remove(f)" />File rows
Code
<GdFileRow name="RP80432-site-plan.pdf" state="uploading" :progress="62" />
<GdFileRow name="RP80432-site-plan.pdf" meta="2.4 MB · PDF" />
<GdFileRow name="survey-plan.dwg" state="failed" error="Larger than the 20 MB limit." @retry="again" />The full lodgement flow — what the applicant sees from empty state to lodged — is on Document upload.
API
GdSlider
Props
modelValuerequirednumber—The value, as `v-model`. Required — a slider with no value has nothing to draw.
labelrequiredstring—The name on the left of the row. It is a real `<label>` wrapping the input, so clicking the words reaches the control.
minnumber0The low end.
maxnumber100The high end. `max === min` is guarded, so a degenerate range draws empty rather than dividing by zero.
stepnumber1The increment, and what the arrow keys move by. Use a fraction for a dimension in metres.
unitstring—Rendered after the value — "m²", "m". Quieter and smaller than the number it qualifies.
disabledbooleanfalseInert and unfocusable; the thumb takes the placeholder ink.
Events
update:modelValuenumberEmitted as the range moves, already coerced to a number. The slider has no slots.
GdDropzone
Props
acceptstring—The accept filter, passed to the input verbatim — ".pdf,.dwg,image/*". It is a hint to the picker, never a guarantee: check the files you are handed.
multiplebooleanfalseAllow more than one file per pick.
hintstring—The constraint line under the prompt — "Up to 20 MB · PDF, DWG, JPG". The zone does not enforce it.
disabledbooleanfalseInert. Drops are ignored as well as clicks.
Slots
defaultThe prompt inside the zone. Defaults to "Drop a file or browse".
Events
filesFile[]The picked or dropped files. The input is reset after every pick, so choosing the same file twice fires twice.
GdFileRow
Props
namerequiredstring—The file name. Truncates with an ellipsis rather than wrapping — the row's geometry is fixed.
metastring—Machine facts — "2.4 MB · PDF". Mono, because they are. Shown in the `done` state only.
state"uploading" | "done" | "failed""done"Which of the three rows this is. The geometry is identical in all three.
progressnumber00–100, `uploading` only. Clamped, so an out-of-range number cannot overdraw the bar.
errorstring—Why it failed. Replaces the meta line in the `failed` state; falls back to "Upload failed." if you leave it off, which you should not.
iconstring—A 24×24 path for the file KIND. Defaults to the document glyph.
Events
removeThe × was pressed. Present in every state — a queued mistake, a finished document and a failed attempt are all things a user may take back.
retryThe Retry button was pressed. `failed` only.
Usage Guidelines
- Use a slider for a continuous dimension the user is exploring — floor area, height, setback. For a number they already know, use a numeric input.
- Set
stepto the precision the answer actually has. A height in metres steps by 0.1; a storey count steps by 1. - Always pass
unitwhen the number has one. "9" and "9 m²" are different facts. - Own the upload yourself. The dropzone emits
filesand holds nothing — progress, rows and retries are the caller's. - Treat
acceptandhintas hints, not rules. Neither is enforced; check size and type where you handle the file. - Write a real
erroron a failed row. "Larger than the 20 MB limit." tells the user what to do; the fallback "Upload failed." does not. - Keep the row mounted while it uploads. The three states share one geometry so the list does not jump as files land.
Behavior & Anatomy
A native range under custom paint
A native range under custom paint — the platform keeps arrows, Home/End and touch. The value rides the label row, right-aligned and tabular, so dragging reads as a number changing rather than a knob moving. The verdict this drives never animates its wording: an icon joins or leaves the stack the instant a threshold is crossed.
The zone is a button first
The zone is a real button (clickable, focusable, announced) and drag-and-drop is layered on top, never instead. A keyboard user gets the picker; a mouse user gets both.
The dropzone emits the files and holds nothing: progress, rows and retries are the caller's, because the component cannot know whether a plan goes to R2 or stays in memory.
One geometry, three states
A list must not jump as files land, so the row is the same height whether it is uploading, done or failed. The failure text is the row's meta line rather than a toast that evaporates — a person who looked away should still be able to find out what went wrong — and the remove control is present in every state, because a queued mistake, a finished document and a failed attempt are all things a user may take back.