fix(forms): preserve regex quantifiers and use inline constraint errors
This commit is contained in:
1 parent
1dd60ded0d
commit
fe40cc56df
13 files changed
+132
-26
No files matched your search
@@ -41,7 +41,16 @@ component StrongPassword {
|
||||
state detailsOpen: boolean = false
|
||||
state revealed: boolean = false
|
||||
|
||||
state nativeError: string = ""
|
||||
|
||||
functions {
|
||||
client function handleInvalid(sourceEvent) {
|
||||
sourceEvent.preventDefault()
|
||||
sourceEvent.stopPropagation()
|
||||
nativeError = validationMessage || (sourceEvent.currentTarget.validity.valueMissing ? "Enter your password." : "Enter a password that meets the requirements.")
|
||||
sourceEvent.currentTarget.setAttribute("aria-invalid", "true")
|
||||
}
|
||||
|
||||
shared function hasMinimumLength() {
|
||||
return password.length >= Number(minLength)
|
||||
}
|
||||
@@ -146,11 +155,11 @@ component StrongPassword {
|
||||
disabled="{disabled}"
|
||||
readonly="{readonly}"
|
||||
required="{required}"
|
||||
aria-invalid="{invalid ? 'true' : 'false'}"
|
||||
aria-describedby="{validationMessage ? name + '-validation' : hintText ? name + '-hint' : ''}"
|
||||
aria-invalid="{invalid || nativeError ? 'true' : 'false'}"
|
||||
aria-describedby="{(validationMessage || nativeError) ? name + '-validation' : hintText ? name + '-hint' : ''}"
|
||||
@focus="detailsOpen = true"
|
||||
@blur="detailsOpen = false"
|
||||
@input="password = event.target.value; output.input({ value: password, score: score(), maximumScore: maximumScore(), percent: strengthPercent(), level: strengthLevel() }); output.strength({ value: password, score: score(), maximumScore: maximumScore(), percent: strengthPercent(), level: strengthLevel() })"
|
||||
@invalid="handleInvalid(event)" @input="nativeError = ''; password = event.target.value; output.input({ value: password, score: score(), maximumScore: maximumScore(), percent: strengthPercent(), level: strengthLevel() }); output.strength({ value: password, score: score(), maximumScore: maximumScore(), percent: strengthPercent(), level: strengthLevel() })"
|
||||
@change="output.change({ value: password, score: score(), maximumScore: maximumScore(), percent: strengthPercent(), level: strengthLevel() })"
|
||||
/>
|
||||
<button
|
||||
@@ -231,7 +240,7 @@ component StrongPassword {
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<small id="{name}-validation" class="wrn-next__validation" data-error="{name}">{validationMessage}</small>
|
||||
<small id="{name}-validation" class="wrn-next__validation" data-error="{name}">{(validationMessage || nativeError)}</small>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,16 @@ component TogglePassword {
|
||||
|
||||
state revealed = visible
|
||||
|
||||
state nativeError: string = ""
|
||||
|
||||
functions {
|
||||
client function handleInvalid(sourceEvent) {
|
||||
sourceEvent.preventDefault()
|
||||
sourceEvent.stopPropagation()
|
||||
nativeError = validationMessage || (sourceEvent.currentTarget.validity.valueMissing ? "Enter your password." : "Enter a password that meets the requirements.")
|
||||
sourceEvent.currentTarget.setAttribute("aria-invalid", "true")
|
||||
}
|
||||
|
||||
shared function toggleVisibility() {
|
||||
if (disabled || readonly || !toggleable) {
|
||||
return
|
||||
@@ -78,8 +87,8 @@ component TogglePassword {
|
||||
disabled="{disabled || field.disabled}"
|
||||
readonly="{readonly || field.readonly}"
|
||||
required="{required || field.required}"
|
||||
aria-invalid="{invalid ? 'true' : 'false'}"
|
||||
@input="output.input({ name: event.target.name, value: event.target.value, visible: revealed })"
|
||||
aria-invalid="{invalid || nativeError ? 'true' : 'false'}"
|
||||
@invalid="handleInvalid(event)" @input="nativeError = ''; output.input({ name: event.target.name, value: event.target.value, visible: revealed })"
|
||||
@change="output.change({ name: event.target.name, value: event.target.value, visible: revealed })"
|
||||
/>
|
||||
{#if toggleable && toggleMode === "button"}
|
||||
@@ -122,9 +131,9 @@ component TogglePassword {
|
||||
disabled="{disabled}"
|
||||
readonly="{readonly}"
|
||||
required="{required}"
|
||||
aria-invalid="{invalid ? 'true' : 'false'}"
|
||||
aria-describedby="{validationMessage ? name + '-validation' : helpText ? name + '-help' : ''}"
|
||||
@input="output.input({ value: event.target.value, visible: revealed })"
|
||||
aria-invalid="{invalid || nativeError ? 'true' : 'false'}"
|
||||
aria-describedby="{(validationMessage || nativeError) ? name + '-validation' : helpText ? name + '-help' : ''}"
|
||||
@invalid="handleInvalid(event)" @input="nativeError = ''; output.input({ value: event.target.value, visible: revealed })"
|
||||
@change="output.change({ value: event.target.value, visible: revealed })"
|
||||
/>
|
||||
{#if toggleable && toggleMode === "button"}
|
||||
@@ -153,12 +162,12 @@ component TogglePassword {
|
||||
<span>{checkboxLabel}</span>
|
||||
</label>
|
||||
{/if}
|
||||
{#if helpText && !validationMessage}<small id="{name}-help">{helpText}</small>{/if}
|
||||
{#if helpText && !(validationMessage || nativeError)}<small id="{name}-help">{helpText}</small>{/if}
|
||||
<small
|
||||
id="{name}-validation"
|
||||
class="wrn-next__validation"
|
||||
data-error="{name}"
|
||||
>{validationMessage}</small>
|
||||
>{(validationMessage || nativeError)}</small>
|
||||
</fieldset>
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ component Input {
|
||||
helperText: string = ""
|
||||
cornerHint: string = ""
|
||||
error: string = ""
|
||||
invalidMessage: string = ""
|
||||
inline: boolean = false
|
||||
readonly: boolean = false
|
||||
disabled: boolean = false
|
||||
@@ -56,7 +57,16 @@ component Input {
|
||||
client function handleChange(sourceEvent) { sourceEvent.stopPropagation(); output.change(detail(sourceEvent)) }
|
||||
client function handleFocus(sourceEvent) { sourceEvent.stopPropagation(); output.focus(detail(sourceEvent)) }
|
||||
client function handleBlur(sourceEvent) { sourceEvent.stopPropagation(); output.blur(detail(sourceEvent)) }
|
||||
client function handleInvalid(sourceEvent) { sourceEvent.stopPropagation(); validationError = sourceEvent.currentTarget.validationMessage; sourceEvent.currentTarget.setAttribute("aria-invalid", "true"); sourceEvent.currentTarget.closest(".wrn-next--field").setAttribute("data-invalid", "true"); output.invalid({ value: sourceEvent.currentTarget.value, name: name, message: validationError, sourceEvent: sourceEvent }) }
|
||||
client function handleInvalid(sourceEvent) {
|
||||
sourceEvent.preventDefault()
|
||||
sourceEvent.stopPropagation()
|
||||
const field = sourceEvent.currentTarget
|
||||
const validity = field.validity
|
||||
validationError = error || invalidMessage || (validity.valueMissing ? "This field is required." : validity.typeMismatch ? "Enter a valid " + (type === "email" ? "email address." : "value.") : validity.tooShort ? "Enter at least " + minlength + " characters." : validity.tooLong ? "Enter no more than " + maxlength + " characters." : validity.patternMismatch ? "Enter a value in the required format." : validity.rangeUnderflow ? "Enter a value of at least " + min + "." : validity.rangeOverflow ? "Enter a value no greater than " + max + "." : "Enter a valid value.")
|
||||
field.setAttribute("aria-invalid", "true")
|
||||
field.closest(".wrn-next--field").setAttribute("data-invalid", "true")
|
||||
output.invalid({ value: field.value, name: name, message: validationError, sourceEvent: sourceEvent })
|
||||
}
|
||||
client function handleKeydown(sourceEvent) { sourceEvent.stopPropagation(); output.keydown({ key: sourceEvent.key, value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
|
||||
client function handleKeyup(sourceEvent) { sourceEvent.stopPropagation(); output.keyup({ key: sourceEvent.key, value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ size: string = "default"
|
||||
}
|
||||
client function handleFocus(sourceEvent) { emitField("focus", sourceEvent); output.open({ name: name, sourceEvent: sourceEvent }) }
|
||||
client function handleBlur(sourceEvent) { emitField("blur", sourceEvent); output.close({ name: name, sourceEvent: sourceEvent }) }
|
||||
client function handleInvalid(sourceEvent) { validationError = sourceEvent.currentTarget.validationMessage; sourceEvent.currentTarget.setAttribute("aria-invalid", "true"); sourceEvent.currentTarget.closest(".wrn-next--field").setAttribute("data-invalid", "true"); output.invalid({ name: name, message: validationError, sourceEvent: sourceEvent }) }
|
||||
client function handleInvalid(sourceEvent) { sourceEvent.preventDefault(); sourceEvent.stopPropagation(); validationError = error || "Choose an option."; sourceEvent.currentTarget.setAttribute("aria-invalid", "true"); sourceEvent.currentTarget.closest(".wrn-next--field").setAttribute("data-invalid", "true"); output.invalid({ name: name, message: validationError, sourceEvent: sourceEvent }) }
|
||||
}
|
||||
view {
|
||||
<div {...attrs} class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--field wrn-next--select {class}" data-variant="{variant}" data-inline="{inline}" data-floating="{variant === 'floating'}" data-invalid="{error || validationError ? 'true' : 'false'}" data-readonly="{readonly}">
|
||||
|
||||
@@ -40,7 +40,9 @@ size: string = "default"
|
||||
output[nameEvent]({ value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent })
|
||||
}
|
||||
client function handleInvalid(sourceEvent) {
|
||||
validationError = sourceEvent.currentTarget.validationMessage
|
||||
sourceEvent.preventDefault()
|
||||
sourceEvent.stopPropagation()
|
||||
validationError = error || (sourceEvent.currentTarget.validity.valueMissing ? "This field is required." : "Enter text within the allowed length.")
|
||||
sourceEvent.currentTarget.setAttribute("aria-invalid", "true")
|
||||
sourceEvent.currentTarget.closest(".wrn-next--field").setAttribute("data-invalid", "true")
|
||||
output.invalid({ value: sourceEvent.currentTarget.value, name: name, message: validationError, sourceEvent: sourceEvent })
|
||||
|
||||
Reference in new issue
Block a user