component TogglePassword { outputs { input(payload: { name?: string; value: string | number | boolean | null | object; visible: boolean }) change(payload: { name?: string; value: string | number | boolean | null | object; visible: boolean }) toggle(payload: { visible: boolean }) } props { size: string = "default" color: string = "primary" label: string = "Password" name: string = "password" value: string = "" placeholder: string = "Enter your password" autocomplete: string = "current-password" minlength: string = "" maxlength: string = "" pattern: string = "(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}" fields: unknown[] = [] visible: boolean = false toggleable: boolean = true toggleMode: string = "button" checkboxLabel: string = "Show password" showLabel: string = "Show password" hideLabel: string = "Hide password" disabled: boolean = false readonly: boolean = false required: boolean = false invalid: boolean = false helpText: string = "" validationMessage: string = "" class: string = "" } state revealed = visible functions { shared function toggleVisibility() { if (disabled || readonly || !toggleable) { return } revealed = !revealed } shared function fieldId(field, index) { return field.id || field.name || name + "-" + index } shared function fieldName(field, index) { return field.name || name + "-" + index } } view {
{#if fields.length}
{#each fields as field, index}
{#if toggleable && toggleMode === "button"} {/if}
{/each}
{:else}
{#if toggleable && toggleMode === "button"} {/if}
{/if} {#if toggleable && toggleMode === "checkbox"} {/if} {#if helpText && !validationMessage}{helpText}{/if} {validationMessage}
} style { .wire-next--toggle-password { display: grid; width: 100%; min-width: 0; max-width: none; box-sizing: border-box; gap: 0.45rem; padding: 0; border: 0; } .wire-next--toggle-password > label { color: var(--wire-color-text); font-size: 0.75rem; font-weight: 600; } .wire-next__password-fields { display: grid; gap: 1rem; } .wire-next__password-field { display: grid; gap: 0.45rem; } .wire-next__password-field > label { color: var(--wire-color-text); font-size: 0.82em; font-weight: 750; } .wire-next__password-control { position: relative; display: flex; min-width: 0; align-items: center; width: 100%; } .wire-next__password-control > input { width: 100%; min-width: 0; min-height: 2.75em; padding: 0.65em 3em 0.65em 0.8em; border: 1px solid var(--wire-color-border); border-radius: var(--wire-radius-sm); outline: 0; color: var(--wire-color-text); background: var(--wire-color-bg); font: inherit; font-size: 0.8125rem; transition: border-color var(--wire-motion-base) var(--wire-ease-standard), box-shadow var(--wire-motion-base) var(--wire-ease-standard); } .wire-next__password-control > input:focus-visible { border-color: var(--wire-component-color); box-shadow: 0 0 0 3px color-mix(in srgb, var(--wire-component-color) 18%, transparent); } .wire-next__password-toggle { position: absolute; top: 50%; right: 0.45em; display: grid; width: 2em; height: 2em; padding: 0; place-items: center; border: 0; border-radius: calc(var(--wire-radius-sm) * 0.72); color: var(--wire-color-muted); background: transparent; cursor: pointer; transform: translateY(-50%); } .wire-next__password-toggle:hover, .wire-next__password-toggle:focus-visible { color: var(--wire-component-color); background: color-mix(in srgb, var(--wire-component-color) 10%, transparent); outline: 0; } .wire-next__password-icon { display: block; width: 1.05em; height: 1.05em; background: currentColor; mask-position: center; mask-repeat: no-repeat; mask-size: contain; } .wire-next__password-icon--show { mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.06 12.35a1 1 0 0 1 0-.7C3.7 7.6 7.64 5 12 5c4.36 0 8.3 2.6 9.94 6.65a1 1 0 0 1 0 .7C20.3 16.4 16.36 19 12 19c-4.36 0-8.3-2.6-9.94-6.65Z'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/svg%3E"); } .wire-next__password-toggle[aria-pressed="true"]::after { position: absolute; width: 1.25em; height: 0.12em; border-radius: 999px; background: currentColor; content: ""; transform: rotate(45deg); box-shadow: 0 0 0 1px var(--wire-color-bg); } .wire-next__password-checkbox { display: inline-flex; width: fit-content; align-items: center; gap: 0.55rem; color: var(--wire-color-muted); font-size: 0.78em; cursor: pointer; } .wire-next__password-checkbox > input { width: 1rem; height: 1rem; margin: 0; accent-color: var(--wire-component-color); } .wire-next--toggle-password > small { color: var(--wire-color-muted); font-size: 0.72em; } } }