94 lines
4.4 KiB
Plaintext
94 lines
4.4 KiB
Plaintext
import FieldStyles from "../styles/FieldStyles.wrn"
|
|
|
|
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
|
|
|
component FileUploadProgress {
|
|
outputs {
|
|
cancel(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
|
retry(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
|
complete(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
|
}
|
|
|
|
props {
|
|
size: string = "default"
|
|
color: string = "primary"
|
|
label: string = "Progress"
|
|
value: number = 50
|
|
max: number = 100
|
|
showValue: boolean = true
|
|
fileName: string = ""
|
|
fileSize: string = ""
|
|
uploadedSize: string = ""
|
|
status: string = "uploading"
|
|
cancelLabel: string = "Cancel upload"
|
|
retryLabel: string = "Retry upload"
|
|
class: string = ""
|
|
}
|
|
state currentValue = value
|
|
state currentStatus = status
|
|
functions {
|
|
shared function percent() { if (!Number(max)) { return 0 } return Math.max(0, Math.min(100, Math.round(Number(currentValue) / Number(max) * 100))) }
|
|
client function detail(sourceEvent) { return { value: currentValue, max: max, percent: percent(), status: currentStatus, fileName: fileName, sourceEvent: sourceEvent } }
|
|
client function cancelUpload(sourceEvent) { currentStatus = "cancelled"; output.cancel(detail(sourceEvent)) }
|
|
client function retryUpload(sourceEvent) { currentValue = 0; currentStatus = "uploading"; output.retry(detail(sourceEvent)) }
|
|
client function completeUpload(sourceEvent) { currentValue = max; currentStatus = "complete"; output.complete(detail(sourceEvent)) }
|
|
}
|
|
view {
|
|
<div {...attrs} class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--file-upload-progress {class}" data-status="{currentStatus}" aria-live="polite">
|
|
<div class="wire-next__row"><span>{#if fileName}<strong>{fileName}</strong><small>{#if uploadedSize || fileSize}{uploadedSize}{#if uploadedSize && fileSize} of {/if}{fileSize}{:else}{label}{/if}</small>{:else}<strong>{label}</strong>{/if}</span>{#if showValue}<strong>{percent()}%</strong>{/if}</div>
|
|
<progress value="{currentValue}" max="{max}" aria-label="{label}"></progress>
|
|
<div class="wire-next__upload-status"><span class="wire-next__upload-status-icon" aria-hidden="true"></span><span>{#if currentStatus === "uploading"}Uploading securely…{:else if currentStatus === "complete"}Upload complete{:else if currentStatus === "error"}Upload failed{:else}Upload cancelled{/if}</span></div>
|
|
<div class="wire-next__upload-actions">{#if currentStatus === "uploading"}<button type="button" @click="cancelUpload(event)">{cancelLabel}</button><button type="button" @click="completeUpload(event)">Complete</button>{/if}{#if currentStatus === "error" || currentStatus === "cancelled"}<button type="button" @click="retryUpload(event)">{retryLabel}</button>{/if}</div>
|
|
</div>
|
|
<FieldStyles hidden />
|
|
<ComponentBaseStyles hidden />
|
|
}
|
|
|
|
style {
|
|
.wire-next__row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.wire-next--file-upload-progress progress {
|
|
width: 100%;
|
|
accent-color: var(--wire-color-primary);
|
|
}
|
|
|
|
.wire-next--file-upload-progress {
|
|
display: grid;
|
|
width: min(100%, 36rem);
|
|
gap: 0.75rem;
|
|
padding: 1rem;
|
|
border: 1px solid var(--wire-color-border);
|
|
border-radius: var(--wire-radius-md);
|
|
background: var(--wire-color-surface);
|
|
box-shadow: var(--wire-shadow-1);
|
|
}
|
|
|
|
.wire-next--file-upload-progress progress {
|
|
width: 100%;
|
|
height: 0.55rem;
|
|
overflow: hidden;
|
|
border: 0;
|
|
border-radius: 999px;
|
|
accent-color: var(--wire-component-color);
|
|
}
|
|
|
|
.wire-next__upload-actions {
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.wire-next__upload-actions button {
|
|
min-height: 2.25rem;
|
|
padding-inline: 0.8rem;
|
|
border: 1px solid var(--wire-color-border);
|
|
border-radius: var(--wire-radius-sm);
|
|
background: var(--wire-color-surface-2);
|
|
color: inherit;
|
|
}
|
|
}
|
|
}
|